From 265b3938b661b6c64148543262c57778182c3f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Mon, 29 Nov 2021 08:49:45 +0100 Subject: [PATCH 01/34] Rename package from sanity-html to portabletext-html --- README.md | 69 ++++++++++--------- portabletext_html/__init__.py | 3 + .../constants.py | 4 +- {sanity_html => portabletext_html}/logger.py | 2 +- .../marker_definitions.py | 4 +- {sanity_html => portabletext_html}/py.typed | 0 .../renderer.py | 18 ++--- {sanity_html => portabletext_html}/types.py | 4 +- {sanity_html => portabletext_html}/utils.py | 4 +- pyproject.toml | 8 +-- sanity_html/__init__.py | 5 -- tests/test_marker_definitions.py | 10 +-- tests/test_module_loading.py | 4 +- tests/test_rendering.py | 2 +- tests/test_upstream_suite.py | 22 +++--- 15 files changed, 80 insertions(+), 79 deletions(-) create mode 100644 portabletext_html/__init__.py rename {sanity_html => portabletext_html}/constants.py (88%) rename {sanity_html => portabletext_html}/logger.py (85%) rename {sanity_html => portabletext_html}/marker_definitions.py (97%) rename {sanity_html => portabletext_html}/py.typed (100%) rename {sanity_html => portabletext_html}/renderer.py (94%) rename {sanity_html => portabletext_html}/types.py (96%) rename {sanity_html => portabletext_html}/utils.py (90%) delete mode 100644 sanity_html/__init__.py diff --git a/README.md b/README.md index b026c61..dc43d25 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Checked with mypy -# Sanity HTML Renderer for Python +# Portable Text HTML Renderer for Python This package generates HTML from [Portable Text](https://github.com/portabletext/portabletext). @@ -20,19 +20,19 @@ For the most part, it mirrors [Sanity's](https://www.sanity.io/) own [block-cont ## Installation ``` -pip install sanity-html +pip install portabletext-html ``` ## Usage -Instantiate the `SanityBlockRenderer` class with your content and call the `render` method. +Instantiate the `PortableTextRenderer` class with your content and call the `render` method. The following content ```python -from sanity_html import SanityBlockRenderer +from portabletext_html import PortableTextRenderer -renderer = SanityBlockRenderer({ +renderer = PortableTextRenderer({ "_key": "R5FvMrjo", "_type": "block", "children": [ @@ -64,26 +64,26 @@ would like to. To illustrate, if you passed this data to the renderer class: ```python -from sanity_html import SanityBlockRenderer - -renderer = SanityBlockRenderer({ - "_type": "block", - "_key": "foo", - "style": "normal", - "children": [ - { - "_type": "span", - "text": "Press, " - }, - { - "_type": "button", - "text": "here" - }, - { - "_type": "span", - "text": ", now!" - } - ] +from portabletext_html import PortableTextRenderer + +renderer = PortableTextRenderer({ + "_type": "block", + "_key": "foo", + "style": "normal", + "children": [ + { + "_type": "span", + "text": "Press, " + }, + { + "_type": "button", + "text": "here" + }, + { + "_type": "span", + "text": ", now!" + } + ] }) renderer.render() ``` @@ -94,12 +94,14 @@ does not have a corresponding built-in type serializer by default. To render this text you must provide your own serializer, like this: ```python -from sanity_html import SanityBlockRenderer +from portabletext_html import PortableTextRenderer + def button_serializer(node: dict, context: Optional[Block], list_item: bool): return f'' -renderer = SanityBlockRenderer( + +renderer = PortableTextRenderer( ..., custom_serializers={'button': button_serializer} ) @@ -136,9 +138,9 @@ Like with custom type serializers, additional serializers for marker definitions and styles can be passed in like this: ```python -from sanity_html import SanityBlockRenderer +from portabletext_html import PortableTextRenderer -renderer = SanityBlockRenderer( +renderer = PortableTextRenderer( ..., custom_marker_definitions={'em': ComicSansEmphasis} ) @@ -152,7 +154,7 @@ Here's an example of a custom style, adding an extra font to the built-in equivalent serializer: ```python -from sanity_html.marker_definitions import MarkerDefinition +from portabletext_html.marker_definitions import MarkerDefinition class ComicSansEmphasis(MarkerDefinition): @@ -178,8 +180,9 @@ Since the `render_suffix` and `render` methods here are actually identical to th they do not need to be specified, and the whole example can be reduced to: ```python -from sanity_html.marker_definitions import MarkerDefinition # base -from sanity_html import SanityBlockRenderer +from portabletext_html.marker_definitions import MarkerDefinition # base +from portabletext_html import PortableTextRenderer + class ComicSansEmphasis(MarkerDefinition): tag = 'em' @@ -189,7 +192,7 @@ class ComicSansEmphasis(MarkerDefinition): return f'<{cls.tag} style="font-family: "Comic Sans MS", "Comic Sans", cursive;">' -renderer = SanityBlockRenderer( +renderer = PortableTextRenderer( ..., custom_marker_definitions={'em': ComicSansEmphasis} ) diff --git a/portabletext_html/__init__.py b/portabletext_html/__init__.py new file mode 100644 index 0000000..bd2f0d5 --- /dev/null +++ b/portabletext_html/__init__.py @@ -0,0 +1,3 @@ +from portabletext_html.renderer import PortableTextRenderer, render + +__all__ = ['PortableTextRenderer', 'render'] diff --git a/sanity_html/constants.py b/portabletext_html/constants.py similarity index 88% rename from sanity_html/constants.py rename to portabletext_html/constants.py index bc73e2d..f5ead44 100644 --- a/sanity_html/constants.py +++ b/portabletext_html/constants.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING -from sanity_html.marker_definitions import ( +from portabletext_html.marker_definitions import ( CodeMarkerDefinition, CommentMarkerDefinition, EmphasisMarkerDefinition, @@ -15,7 +15,7 @@ if TYPE_CHECKING: from typing import Dict, Type - from sanity_html.marker_definitions import MarkerDefinition + from portabletext_html.marker_definitions import MarkerDefinition STYLE_MAP = { 'h1': 'h1', diff --git a/sanity_html/logger.py b/portabletext_html/logger.py similarity index 85% rename from sanity_html/logger.py rename to portabletext_html/logger.py index 7d9ea67..18122b3 100644 --- a/sanity_html/logger.py +++ b/portabletext_html/logger.py @@ -6,7 +6,7 @@ """ import logging -logger = logging.getLogger('sanity_html') +logger = logging.getLogger('portabletext_html') if not logger.handlers: # pragma: no cover logger.setLevel(logging.WARNING) diff --git a/sanity_html/marker_definitions.py b/portabletext_html/marker_definitions.py similarity index 97% rename from sanity_html/marker_definitions.py rename to portabletext_html/marker_definitions.py index 7a7bb05..72cc2d2 100644 --- a/sanity_html/marker_definitions.py +++ b/portabletext_html/marker_definitions.py @@ -2,12 +2,12 @@ from typing import TYPE_CHECKING -from sanity_html.logger import logger +from portabletext_html.logger import logger if TYPE_CHECKING: from typing import Type - from sanity_html.types import Block, Span + from portabletext_html.types import Block, Span class MarkerDefinition: diff --git a/sanity_html/py.typed b/portabletext_html/py.typed similarity index 100% rename from sanity_html/py.typed rename to portabletext_html/py.typed diff --git a/sanity_html/renderer.py b/portabletext_html/renderer.py similarity index 94% rename from sanity_html/renderer.py rename to portabletext_html/renderer.py index 67c2577..614b177 100644 --- a/sanity_html/renderer.py +++ b/portabletext_html/renderer.py @@ -3,16 +3,16 @@ import html from typing import TYPE_CHECKING, cast -from sanity_html.constants import STYLE_MAP -from sanity_html.logger import logger -from sanity_html.marker_definitions import DefaultMarkerDefinition -from sanity_html.types import Block, Span -from sanity_html.utils import get_list_tags, is_block, is_list, is_span +from portabletext_html.constants import STYLE_MAP +from portabletext_html.logger import logger +from portabletext_html.marker_definitions import DefaultMarkerDefinition +from portabletext_html.types import Block, Span +from portabletext_html.utils import get_list_tags, is_block, is_list, is_span if TYPE_CHECKING: from typing import Callable, Dict, List, Optional, Type, Union - from sanity_html.marker_definitions import MarkerDefinition + from portabletext_html.marker_definitions import MarkerDefinition class UnhandledNodeError(Exception): @@ -32,8 +32,8 @@ class MissingSerializerError(UnhandledNodeError): pass -class SanityBlockRenderer: - """HTML renderer for Sanity block content.""" +class PortableTextRenderer: + """HTML renderer for Sanity's portable text format.""" def __init__( self, @@ -246,5 +246,5 @@ def _list_from_block(self, block: dict) -> dict: def render(blocks: List[Dict], *args, **kwargs) -> str: """Shortcut function inspired by Sanity's own blocksToHtml.h callable.""" - renderer = SanityBlockRenderer(blocks, *args, **kwargs) + renderer = PortableTextRenderer(blocks, *args, **kwargs) return renderer.render() diff --git a/sanity_html/types.py b/portabletext_html/types.py similarity index 96% rename from sanity_html/types.py rename to portabletext_html/types.py index c24f165..68638cd 100644 --- a/sanity_html/types.py +++ b/portabletext_html/types.py @@ -3,12 +3,12 @@ from dataclasses import dataclass, field from typing import TYPE_CHECKING, cast -from sanity_html.utils import get_default_marker_definitions +from portabletext_html.utils import get_default_marker_definitions if TYPE_CHECKING: from typing import Literal, Optional, Tuple, Type, Union - from sanity_html.marker_definitions import MarkerDefinition + from portabletext_html.marker_definitions import MarkerDefinition @dataclass(frozen=True) diff --git a/sanity_html/utils.py b/portabletext_html/utils.py similarity index 90% rename from sanity_html/utils.py rename to portabletext_html/utils.py index d0afec7..3977d81 100644 --- a/sanity_html/utils.py +++ b/portabletext_html/utils.py @@ -2,12 +2,12 @@ from typing import TYPE_CHECKING -from sanity_html.constants import ANNOTATION_MARKER_DEFINITIONS, DECORATOR_MARKER_DEFINITIONS +from portabletext_html.constants import ANNOTATION_MARKER_DEFINITIONS, DECORATOR_MARKER_DEFINITIONS if TYPE_CHECKING: from typing import Type - from sanity_html.marker_definitions import MarkerDefinition + from portabletext_html.marker_definitions import MarkerDefinition def get_default_marker_definitions(mark_defs: list[dict]) -> dict[str, Type[MarkerDefinition]]: diff --git a/pyproject.toml b/pyproject.toml index 15152a2..70fba75 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.poetry] -name = 'sanity-html' +name = 'portabletext-html' version = '1.0.0' description = "HTML renderer for Sanity's Portable Text format" homepage = 'https://github.com/otovo/python-sanity-html' @@ -10,7 +10,7 @@ license = 'Apache2' readme = 'README.md' keywords = ['sanity', 'portable', 'text', 'html', 'parsing'] include = ['CHANGELOG.md'] -packages = [{ include = 'sanity_html' }] +packages = [{ include = 'portabletext_html' }] classifiers = [ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', @@ -51,11 +51,11 @@ include_trailing_comma = true line_length = 120 [tool.pytest.ini_options] -addopts = ['--cov=sanity_html','--cov-report', 'term-missing'] +addopts = ['--cov=portabletext_html','--cov-report', 'term-missing'] markers = ['unsupported'] [tool.coverage.run] -source = ['sanity_html/*'] +source = ['portabletext_html/*'] omit = [] branch = true diff --git a/sanity_html/__init__.py b/sanity_html/__init__.py deleted file mode 100644 index 879ae73..0000000 --- a/sanity_html/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Python Sanity HTML Renderer.""" - -from sanity_html.renderer import SanityBlockRenderer, render - -__all__ = ['SanityBlockRenderer', 'render'] diff --git a/tests/test_marker_definitions.py b/tests/test_marker_definitions.py index 0a2577c..6011426 100644 --- a/tests/test_marker_definitions.py +++ b/tests/test_marker_definitions.py @@ -1,5 +1,5 @@ -from sanity_html import SanityBlockRenderer -from sanity_html.marker_definitions import ( +from portabletext_html import PortableTextRenderer +from portabletext_html.marker_definitions import ( CommentMarkerDefinition, EmphasisMarkerDefinition, LinkMarkerDefinition, @@ -7,7 +7,7 @@ StrongMarkerDefinition, UnderlineMarkerDefinition, ) -from sanity_html.types import Block, Span +from portabletext_html.types import Block, Span sample_texts = ['test', None, 1, 2.2, '!"#$%&/()'] @@ -60,7 +60,7 @@ def test_render_comment_marker_success(): def test_custom_marker_definition(): - from sanity_html.marker_definitions import MarkerDefinition + from portabletext_html.marker_definitions import MarkerDefinition class ComicSansEmphasis(MarkerDefinition): tag = 'em' @@ -69,7 +69,7 @@ class ComicSansEmphasis(MarkerDefinition): def render_prefix(cls, span, marker, context): return f'<{cls.tag} style="font-family: "Comic Sans MS", "Comic Sans", cursive;">' - renderer = SanityBlockRenderer( + renderer = PortableTextRenderer( { '_type': 'block', 'children': [{'_key': 'a1ph4', '_type': 'span', 'marks': ['em'], 'text': 'Sanity'}], diff --git a/tests/test_module_loading.py b/tests/test_module_loading.py index d1a6523..03fe074 100644 --- a/tests/test_module_loading.py +++ b/tests/test_module_loading.py @@ -6,6 +6,6 @@ def test_module_should_be_importable(): This catches any compilation issue we might have. """ - from sanity_html import SanityBlockRenderer + from portabletext_html import PortableTextRenderer - assert SanityBlockRenderer + assert PortableTextRenderer diff --git a/tests/test_rendering.py b/tests/test_rendering.py index a9eaf8d..3894862 100644 --- a/tests/test_rendering.py +++ b/tests/test_rendering.py @@ -2,7 +2,7 @@ import json from pathlib import Path -from sanity_html.renderer import render +from portabletext_html.renderer import render def load_fixture(fixture_name) -> dict: diff --git a/tests/test_upstream_suite.py b/tests/test_upstream_suite.py index 01241bf..08efedf 100644 --- a/tests/test_upstream_suite.py +++ b/tests/test_upstream_suite.py @@ -5,10 +5,10 @@ import pytest -from sanity_html import render -from sanity_html.marker_definitions import LinkMarkerDefinition, MarkerDefinition -from sanity_html.renderer import SanityBlockRenderer -from sanity_html.types import Block, Span +from portabletext_html import render +from portabletext_html.marker_definitions import LinkMarkerDefinition, MarkerDefinition +from portabletext_html.renderer import PortableTextRenderer +from portabletext_html.types import Block, Span def fake_image_serializer(node: dict, context: Optional[Block], list_item: bool): @@ -147,7 +147,7 @@ def test_012_image_support(): fixture_data = get_fixture('fixtures/upstream/012-image-support.json') input_blocks = fixture_data['input'] expected_output = fixture_data['output'] - sbr = SanityBlockRenderer(input_blocks, custom_serializers={'image': fake_image_serializer}) + sbr = PortableTextRenderer(input_blocks, custom_serializers={'image': fake_image_serializer}) output = sbr.render() assert output == expected_output @@ -156,7 +156,7 @@ def test_013_materialized_image_support(): fixture_data = get_fixture('fixtures/upstream/013-materialized-image-support.json') input_blocks = fixture_data['input'] expected_output = fixture_data['output'] - sbr = SanityBlockRenderer(input_blocks, custom_serializers={'image': fake_image_serializer}) + sbr = PortableTextRenderer(input_blocks, custom_serializers={'image': fake_image_serializer}) output = sbr.render() assert output == expected_output @@ -230,7 +230,7 @@ def test_022_inline_node(): fixture_data = get_fixture('fixtures/upstream/022-inline-nodes.json') input_blocks = fixture_data['input'] expected_output = fixture_data['output'] - sbr = SanityBlockRenderer(input_blocks, custom_serializers={'image': fake_image_serializer}) + sbr = PortableTextRenderer(input_blocks, custom_serializers={'image': fake_image_serializer}) output = sbr.render() assert output == expected_output @@ -247,7 +247,7 @@ def test_024_inline_image(): fixture_data = get_fixture('fixtures/upstream/024-inline-images.json') input_blocks = fixture_data['input'] expected_output = fixture_data['output'] - sbr = SanityBlockRenderer(input_blocks, custom_serializers={'image': fake_image_serializer}) + sbr = PortableTextRenderer(input_blocks, custom_serializers={'image': fake_image_serializer}) output = sbr.render() assert output == expected_output @@ -256,7 +256,7 @@ def test_025_image_with_hotspot(): fixture_data = get_fixture('fixtures/upstream/025-image-with-hotspot.json') input_blocks = fixture_data['input'] expected_output = fixture_data['output'] - sbr = SanityBlockRenderer(input_blocks, custom_serializers={'image': fake_image_serializer}) + sbr = PortableTextRenderer(input_blocks, custom_serializers={'image': fake_image_serializer}) output = sbr.render() assert output == expected_output @@ -269,7 +269,7 @@ def test_026_inline_block_with_text(): fixture_data = get_fixture('fixtures/upstream/026-inline-block-with-text.json') input_blocks = fixture_data['input'] expected_output = fixture_data['output'] - sbr = SanityBlockRenderer(input_blocks, custom_serializers={'button': button_serializer}) + sbr = PortableTextRenderer(input_blocks, custom_serializers={'button': button_serializer}) output = sbr.render() assert output == expected_output @@ -328,7 +328,7 @@ def render_prefix(cls, span, marker, context) -> str: result = super().render_prefix(span, marker, context) return result.replace(' Date: Mon, 29 Nov 2021 08:50:13 +0100 Subject: [PATCH 02/34] Update version from v1 to v1.0.0b --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 70fba75..957cd8d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = 'portabletext-html' -version = '1.0.0' +version = '1.0.0b1' description = "HTML renderer for Sanity's Portable Text format" homepage = 'https://github.com/otovo/python-sanity-html' repository = 'https://github.com/otovo/python-sanity-html' From 4e8cda9a3819d5fa47f4978a504a66cfcd705e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Mon, 29 Nov 2021 08:50:35 +0100 Subject: [PATCH 03/34] Update lockfile --- poetry.lock | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/poetry.lock b/poetry.lock index 15e5029..268a8e6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -55,7 +55,7 @@ pyflakes = ">=2.3.0,<2.4.0" [[package]] name = "importlib-metadata" -version = "4.8.1" +version = "4.8.2" description = "Read metadata from Python packages" category = "dev" optional = false @@ -68,7 +68,7 @@ zipp = ">=0.5" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] perf = ["ipython"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -88,14 +88,14 @@ python-versions = "*" [[package]] name = "packaging" -version = "21.2" +version = "21.3" description = "Core utilities for Python packages" category = "dev" optional = false python-versions = ">=3.6" [package.dependencies] -pyparsing = ">=2.0.2,<3" +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" [[package]] name = "pluggy" @@ -114,11 +114,11 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "py" -version = "1.10.0" +version = "1.11.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pycodestyle" @@ -138,11 +138,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pyparsing" -version = "2.4.7" +version = "3.0.6" description = "Python parsing module" category = "dev" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = ">=3.6" + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" @@ -192,11 +195,11 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "typing-extensions" -version = "3.10.0.2" -description = "Backported and Experimental Type Hints for Python 3.5+" +version = "4.0.0" +description = "Backported and Experimental Type Hints for Python 3.6+" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "zipp" @@ -287,8 +290,8 @@ flake8 = [ {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.8.1-py3-none-any.whl", hash = "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15"}, - {file = "importlib_metadata-4.8.1.tar.gz", hash = "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1"}, + {file = "importlib_metadata-4.8.2-py3-none-any.whl", hash = "sha256:53ccfd5c134223e497627b9815d5030edf77d2ed573922f7a0b8f8bb81a1c100"}, + {file = "importlib_metadata-4.8.2.tar.gz", hash = "sha256:75bdec14c397f528724c1bfd9709d660b33a4d2e77387a3358f20b848bb5e5fb"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -299,16 +302,16 @@ mccabe = [ {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] packaging = [ - {file = "packaging-21.2-py3-none-any.whl", hash = "sha256:14317396d1e8cdb122989b916fa2c7e9ca8e2be9e8060a6eff75b6b7b4d8a7e0"}, - {file = "packaging-21.2.tar.gz", hash = "sha256:096d689d78ca690e4cd8a89568ba06d07ca097e3306a4381635073ca91479966"}, + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] py = [ - {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, - {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pycodestyle = [ {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, @@ -319,8 +322,8 @@ pyflakes = [ {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] pyparsing = [ - {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, - {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, + {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, + {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, ] pytest = [ {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, @@ -335,9 +338,8 @@ toml = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] typing-extensions = [ - {file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"}, - {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"}, - {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"}, + {file = "typing_extensions-4.0.0-py3-none-any.whl", hash = "sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9"}, + {file = "typing_extensions-4.0.0.tar.gz", hash = "sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed"}, ] zipp = [ {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, From 18e0aa1602efbc61a38ad770a20a0a66460c02cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Mon, 29 Nov 2021 08:51:04 +0100 Subject: [PATCH 04/34] Update pre-commit hooks --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 10b4d9f..3062b26 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/ambv/black - rev: 21.10b0 + rev: 21.11b1 hooks: - id: black args: [ "--quiet" ] @@ -35,12 +35,12 @@ repos: 'flake8-type-checking', ] - repo: https://github.com/asottile/pyupgrade - rev: v2.29.0 + rev: v2.29.1 hooks: - id: pyupgrade args: [ "--py36-plus", "--py37-plus",'--keep-runtime-typing' ] - repo: https://github.com/pycqa/isort - rev: 5.10.0 + rev: 5.10.1 hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-mypy From 4f4fad50dae7a5ee2ddfca5398f60e83658ee1c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Mon, 29 Nov 2021 09:00:43 +0100 Subject: [PATCH 05/34] Update package metadata to support python 3.7+ --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 957cd8d..cc7ffeb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,8 @@ classifiers = [ 'Topic :: Text Processing :: Markup', 'Topic :: Text Processing :: Markup :: HTML', 'Programming Language :: Python', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Typing :: Typed', From ccb34329d3377e562f82ba41b9823403b0b1c6a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Mon, 29 Nov 2021 09:03:33 +0100 Subject: [PATCH 06/34] Bump version from 1.0.0b1 to v1.0.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cc7ffeb..8d8340c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = 'portabletext-html' -version = '1.0.0b1' +version = '1.0.0' description = "HTML renderer for Sanity's Portable Text format" homepage = 'https://github.com/otovo/python-sanity-html' repository = 'https://github.com/otovo/python-sanity-html' From 5bb6edf97242e4415d579e3aa12a61625be45808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Mon, 29 Nov 2021 09:10:16 +0100 Subject: [PATCH 07/34] Remove no longer used ci-script and update poetry version --- .github/scripts/get_python_versions.py | 22 ---------------------- .github/workflows/test.yml | 5 ++--- 2 files changed, 2 insertions(+), 25 deletions(-) delete mode 100644 .github/scripts/get_python_versions.py diff --git a/.github/scripts/get_python_versions.py b/.github/scripts/get_python_versions.py deleted file mode 100644 index 8a39145..0000000 --- a/.github/scripts/get_python_versions.py +++ /dev/null @@ -1,22 +0,0 @@ -if __name__ == '__main__': - import json - - import requests - from packaging import version as semver - - stable_versions = requests.get( - 'https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json' - ).json() - - min_version = semver.parse('3.7') - versions = {} - - for version_object in stable_versions: - - version = version_object['version'] - major_and_minor_version = semver.parse('.'.join(version.split('.')[:2])) - - if major_and_minor_version not in versions and major_and_minor_version >= min_version: - versions[major_and_minor_version] = version - - print(json.dumps(list(versions.values()))) # noqa diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 082066e..a9fc2e7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -48,11 +48,10 @@ jobs: id: poetry-cache with: path: ~/.local - key: key-0 + key: key-1 - uses: snok/install-poetry@v1 with: virtualenvs-create: false - version: 1.2.0a2 - uses: actions/cache@v2 id: cache-venv with: @@ -61,7 +60,7 @@ jobs: - run: | python -m venv .venv source .venv/bin/activate - pip install -U pip + pip install -U pip wheel poetry install --no-interaction --no-root if: steps.cache-venv.outputs.cache-hit != 'true' - name: Run tests From da2282657658c1675e48f3a4bd19e02d84ffc4ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Mon, 29 Nov 2021 10:27:46 +0100 Subject: [PATCH 08/34] Update readme badges --- README.md | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index dc43d25..f3a2d9a 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,7 @@ - - Package version - - - Code coverage - - - Supported Python versions - - - Checked with mypy - +[![pypi](https://img.shields.io/pypi/v/portabletext-html.svg)](https://pypi.org/project/portabletext-html/) +[![test](https://github.com/otovo/python-portabletext-html/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/otovo/python-portabletext-html/actions/workflows/test.yml) +[![code coverage](https://codecov.io/gh/otovo/python-portabletext-html/branch/main/graph/badge.svg)](https://codecov.io/gh/otovo/python-portabletext-html) +[![supported python versions](https://img.shields.io/badge/python-3.7%2B-blue)](https://pypi.org/project/python-portabletext-html/) # Portable Text HTML Renderer for Python @@ -223,4 +215,4 @@ In the meantime, users should be able to serialize image types by passing a cust Contributions are always appreciated 👏 -For details, see the [CONTRIBUTING.md](https://github.com/otovo/python-sanity-html/blob/main/CONTRIBUTING.md). +For details, see the [CONTRIBUTING.md](https://github.com/otovo/python-portabletext-html/blob/main/CONTRIBUTING.md). From 310a0ec14c5b594aece554c33b09854ecd6cfd11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Mon, 29 Nov 2021 10:30:51 +0100 Subject: [PATCH 09/34] Reset test workflow caches --- .github/workflows/test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a9fc2e7..45b4dc7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,7 +18,7 @@ jobs: id: cache-venv with: path: .venv - key: venv-0 + key: venv-1 - run: | python -m venv .venv --upgrade-deps source .venv/bin/activate @@ -28,7 +28,7 @@ jobs: id: pre-commit-cache with: path: ~/.cache/pre-commit - key: key-0 + key: key-1 - run: | source .venv/bin/activate pre-commit run --all-files @@ -48,7 +48,7 @@ jobs: id: poetry-cache with: path: ~/.local - key: key-1 + key: key-2 - uses: snok/install-poetry@v1 with: virtualenvs-create: false @@ -56,7 +56,7 @@ jobs: id: cache-venv with: path: .venv - key: ${{ hashFiles('**/poetry.lock') }}-0 + key: ${{ hashFiles('**/poetry.lock') }}-1 - run: | python -m venv .venv source .venv/bin/activate From e445dd9d0f05f8cfe424112e568f37c36e663096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Mon, 29 Nov 2021 10:35:04 +0100 Subject: [PATCH 10/34] Update test badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f3a2d9a..58abe31 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![pypi](https://img.shields.io/pypi/v/portabletext-html.svg)](https://pypi.org/project/portabletext-html/) -[![test](https://github.com/otovo/python-portabletext-html/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/otovo/python-portabletext-html/actions/workflows/test.yml) +[![test](https://github.com/otovo/python-portabletext-html/actions/workflows/test.yml/badge.svg)](https://github.com/otovo/python-portabletext-html/actions/workflows/test.yml) [![code coverage](https://codecov.io/gh/otovo/python-portabletext-html/branch/main/graph/badge.svg)](https://codecov.io/gh/otovo/python-portabletext-html) [![supported python versions](https://img.shields.io/badge/python-3.7%2B-blue)](https://pypi.org/project/python-portabletext-html/) From b70e66de7f1935cb38133f8522b4c72ff63f1e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Tue, 18 Jan 2022 12:38:55 +0100 Subject: [PATCH 11/34] chore: Add stricter mypy config --- setup.cfg | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/setup.cfg b/setup.cfg index 72028f4..44e5250 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,3 +47,21 @@ exclude = max-complexity = 15 max-line-length = 120 + +[mypy] +show_error_codes = True +warn_unused_ignores = True +strict_optional = True +incremental = True +ignore_missing_imports = True +warn_redundant_casts = True +warn_unused_configs = True +disallow_untyped_defs = True +disallow_untyped_calls = True +local_partial_types = True +show_traceback = True +exclude = + .venv/ + +[mypy-tests.*] +ignore_errors = True From 050a4d9f22e476f44bb08e8f1f67786209967dc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Tue, 18 Jan 2022 12:39:14 +0100 Subject: [PATCH 12/34] chore: Remove redundant casts --- portabletext_html/renderer.py | 4 ++-- portabletext_html/types.py | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/portabletext_html/renderer.py b/portabletext_html/renderer.py index 614b177..3804c85 100644 --- a/portabletext_html/renderer.py +++ b/portabletext_html/renderer.py @@ -10,7 +10,7 @@ from portabletext_html.utils import get_list_tags, is_block, is_list, is_span if TYPE_CHECKING: - from typing import Callable, Dict, List, Optional, Type, Union + from typing import Any, Callable, Dict, List, Optional, Type, Union from portabletext_html.marker_definitions import MarkerDefinition @@ -244,7 +244,7 @@ def _list_from_block(self, block: dict) -> dict: } -def render(blocks: List[Dict], *args, **kwargs) -> str: +def render(blocks: List[Dict], *args: Any, **kwargs: Any) -> str: """Shortcut function inspired by Sanity's own blocksToHtml.h callable.""" renderer = PortableTextRenderer(blocks, *args, **kwargs) return renderer.render() diff --git a/portabletext_html/types.py b/portabletext_html/types.py index 68638cd..1cd38d3 100644 --- a/portabletext_html/types.py +++ b/portabletext_html/types.py @@ -1,7 +1,7 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import TYPE_CHECKING, cast +from typing import TYPE_CHECKING from portabletext_html.utils import get_default_marker_definitions @@ -74,10 +74,8 @@ def get_node_siblings(self, node: Union[dict, Span]) -> Tuple[Optional[dict], Op return None, None try: if type(node) == dict: - node = cast(dict, node) node_idx = self.children.index(node) elif type(node) == Span: - node = cast(Span, node) for index, item in enumerate(self.children): if 'text' in item and node.text == item['text']: # Is it possible to handle several identical texts? From 352ce6a3eb794c78fe77627fef172661eeaeaa56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Tue, 18 Jan 2022 12:40:32 +0100 Subject: [PATCH 13/34] chore: Update pre-commit config --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3062b26..0968ba6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/ambv/black - rev: 21.11b1 + rev: 21.12b0 hooks: - id: black args: [ "--quiet" ] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 + rev: v4.1.0 hooks: - id: check-ast - id: check-merge-conflict @@ -35,7 +35,7 @@ repos: 'flake8-type-checking', ] - repo: https://github.com/asottile/pyupgrade - rev: v2.29.1 + rev: v2.31.0 hooks: - id: pyupgrade args: [ "--py36-plus", "--py37-plus",'--keep-runtime-typing' ] @@ -44,7 +44,7 @@ repos: hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.910-1 + rev: v0.931 hooks: - id: mypy additional_dependencies: From 655a6fcaee339f6f2bf6adc7e691c7cfdcaf25fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Tue, 18 Jan 2022 12:40:52 +0100 Subject: [PATCH 14/34] chore: Update lockfile --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 268a8e6..30cd47f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -8,17 +8,17 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "21.2.0" +version = "21.4.0" description = "Classes Without Boilerplate" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] [[package]] name = "colorama" @@ -55,11 +55,11 @@ pyflakes = ">=2.3.0,<2.4.0" [[package]] name = "importlib-metadata" -version = "4.8.2" +version = "4.10.1" description = "Read metadata from Python packages" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} @@ -68,7 +68,7 @@ zipp = ">=0.5" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -195,7 +195,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "typing-extensions" -version = "4.0.0" +version = "4.0.1" description = "Backported and Experimental Type Hints for Python 3.6+" category = "dev" optional = false @@ -203,15 +203,15 @@ python-versions = ">=3.6" [[package]] name = "zipp" -version = "3.6.0" +version = "3.7.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] [metadata] lock-version = "1.1" @@ -224,8 +224,8 @@ atomicwrites = [ {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ - {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, - {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, + {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, + {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, ] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, @@ -290,8 +290,8 @@ flake8 = [ {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.8.2-py3-none-any.whl", hash = "sha256:53ccfd5c134223e497627b9815d5030edf77d2ed573922f7a0b8f8bb81a1c100"}, - {file = "importlib_metadata-4.8.2.tar.gz", hash = "sha256:75bdec14c397f528724c1bfd9709d660b33a4d2e77387a3358f20b848bb5e5fb"}, + {file = "importlib_metadata-4.10.1-py3-none-any.whl", hash = "sha256:899e2a40a8c4a1aec681feef45733de8a6c58f3f6a0dbed2eb6574b4387a77b6"}, + {file = "importlib_metadata-4.10.1.tar.gz", hash = "sha256:951f0d8a5b7260e9db5e41d429285b5f451e928479f19d80818878527d36e95e"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -338,10 +338,10 @@ toml = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] typing-extensions = [ - {file = "typing_extensions-4.0.0-py3-none-any.whl", hash = "sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9"}, - {file = "typing_extensions-4.0.0.tar.gz", hash = "sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed"}, + {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"}, + {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"}, ] zipp = [ - {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, - {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, + {file = "zipp-3.7.0-py3-none-any.whl", hash = "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"}, + {file = "zipp-3.7.0.tar.gz", hash = "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d"}, ] From 22dc82d6e2abfa195377014086f74fbb6421b940 Mon Sep 17 00:00:00 2001 From: rootisenabled Date: Tue, 1 Feb 2022 11:26:17 +0100 Subject: [PATCH 15/34] custom marks: add test for conditional custom mark --- tests/test_marker_definitions.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/tests/test_marker_definitions.py b/tests/test_marker_definitions.py index 6011426..f67f913 100644 --- a/tests/test_marker_definitions.py +++ b/tests/test_marker_definitions.py @@ -1,3 +1,5 @@ +from typing import Type + from portabletext_html import PortableTextRenderer from portabletext_html.marker_definitions import ( CommentMarkerDefinition, @@ -9,7 +11,7 @@ ) from portabletext_html.types import Block, Span -sample_texts = ['test', None, 1, 2.2, '!"#$%&/()'] +sample_texts = ['test', None, 1, 2.2, '!"#$%/()'] def test_render_emphasis_marker_success(): @@ -62,19 +64,26 @@ def test_render_comment_marker_success(): def test_custom_marker_definition(): from portabletext_html.marker_definitions import MarkerDefinition - class ComicSansEmphasis(MarkerDefinition): + class ConditionalMarkerDefinition(MarkerDefinition): tag = 'em' @classmethod - def render_prefix(cls, span, marker, context): - return f'<{cls.tag} style="font-family: "Comic Sans MS", "Comic Sans", cursive;">' + def render_prefix(cls: Type[MarkerDefinition], span: Span, marker: str, context: Block) -> str: + marker_definition = next((md for md in context.markDefs if md['_key'] == marker), None) + condition = marker_definition.get('cloudCondition', '') + if not condition: + style = "display: none" + return f'<{cls.tag} style=\"{style}\">' + else: + return super().render_prefix(span, marker, context) renderer = PortableTextRenderer( { '_type': 'block', - 'children': [{'_key': 'a1ph4', '_type': 'span', 'marks': ['em'], 'text': 'Sanity'}], - 'markDefs': [], + 'children': [{'_key': 'a1ph4', '_type': 'span', 'marks': ['some_id'], 'text': 'Sanity'}], + 'markDefs': [{"_key": "some_id", "_type": "contractConditional", "cloudCondition": False}], }, - custom_marker_definitions={'em': ComicSansEmphasis}, + custom_marker_definitions={'contractConditional': ConditionalMarkerDefinition}, ) - assert renderer.render() == '

Sanity

' + result = renderer.render() + assert result == '

Sanity

' From 9b7393e5b9ce8fc09fdff0ac2ca22b74c8726ad7 Mon Sep 17 00:00:00 2001 From: rootisenabled Date: Mon, 31 Jan 2022 08:56:11 +0100 Subject: [PATCH 16/34] Bugfix: user-defined custom marks can be passed to Blocks again When I was trying to create my own custom mark definition, I noticed that the information from 'markDefs' property is not passed down to the renderer. `get_default_marker_definitions` method graps the context only from the default_annotations dictionary. `add_custom_marker_definitions` solves the issue by using the same logic as `get_default_marker_definitions`, but looping over user-defined annotations (self.marker_definitions). --- portabletext_html/types.py | 14 +++++++++++--- tests/test_marker_definitions.py | 4 ++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/portabletext_html/types.py b/portabletext_html/types.py index 1cd38d3..0d1c015 100644 --- a/portabletext_html/types.py +++ b/portabletext_html/types.py @@ -53,9 +53,7 @@ def __post_init__(self) -> None: To make handling of span `marks` simpler, we define marker_definitions as a dict, from which we can directly look up both annotation marks or decorator marks. """ - marker_definitions = get_default_marker_definitions(self.markDefs) - marker_definitions.update(self.marker_definitions) - self.marker_definitions = marker_definitions + self.marker_definitions = self._add_custom_marker_definitions() self.marker_frequencies = self._compute_marker_frequencies() def _compute_marker_frequencies(self) -> dict[str, int]: @@ -68,6 +66,16 @@ def _compute_marker_frequencies(self) -> dict[str, int]: counts[mark] = 0 return counts + def _add_custom_marker_definitions(self) -> dict[str, Type[MarkerDefinition]]: + marker_definitions = get_default_marker_definitions(self.markDefs) + marker_definitions.update(self.marker_definitions) + for definition in self.markDefs: + if definition['_type'] in self.marker_definitions: + marker = self.marker_definitions[definition['_type']] + marker_definitions[definition['_key']] = marker + del marker_definitions[definition['_type']] + return marker_definitions + def get_node_siblings(self, node: Union[dict, Span]) -> Tuple[Optional[dict], Optional[dict]]: """Return the sibling nodes (prev, next) to the given node.""" if not self.children: diff --git a/tests/test_marker_definitions.py b/tests/test_marker_definitions.py index f67f913..e357eea 100644 --- a/tests/test_marker_definitions.py +++ b/tests/test_marker_definitions.py @@ -72,7 +72,7 @@ def render_prefix(cls: Type[MarkerDefinition], span: Span, marker: str, context: marker_definition = next((md for md in context.markDefs if md['_key'] == marker), None) condition = marker_definition.get('cloudCondition', '') if not condition: - style = "display: none" + style = 'display: none' return f'<{cls.tag} style=\"{style}\">' else: return super().render_prefix(span, marker, context) @@ -81,7 +81,7 @@ def render_prefix(cls: Type[MarkerDefinition], span: Span, marker: str, context: { '_type': 'block', 'children': [{'_key': 'a1ph4', '_type': 'span', 'marks': ['some_id'], 'text': 'Sanity'}], - 'markDefs': [{"_key": "some_id", "_type": "contractConditional", "cloudCondition": False}], + 'markDefs': [{'_key': 'some_id', '_type': 'contractConditional', 'cloudCondition': False}], }, custom_marker_definitions={'contractConditional': ConditionalMarkerDefinition}, ) From 87938c8a7bd45a4872439dbbda531dfd002f5d8d Mon Sep 17 00:00:00 2001 From: Sourcery AI <> Date: Tue, 1 Feb 2022 12:32:11 +0000 Subject: [PATCH 17/34] 'Refactored by Sourcery' --- portabletext_html/types.py | 4 +--- tests/test_marker_definitions.py | 8 +++----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/portabletext_html/types.py b/portabletext_html/types.py index 0d1c015..ab5236b 100644 --- a/portabletext_html/types.py +++ b/portabletext_html/types.py @@ -94,11 +94,9 @@ def get_node_siblings(self, node: Union[dict, Span]) -> Tuple[Optional[dict], Op except ValueError: return None, None - prev_node = None next_node = None - if node_idx != 0: - prev_node = self.children[node_idx - 1] + prev_node = self.children[node_idx - 1] if node_idx != 0 else None if node_idx != len(self.children) - 1: next_node = self.children[node_idx + 1] diff --git a/tests/test_marker_definitions.py b/tests/test_marker_definitions.py index e357eea..9a3463a 100644 --- a/tests/test_marker_definitions.py +++ b/tests/test_marker_definitions.py @@ -70,12 +70,10 @@ class ConditionalMarkerDefinition(MarkerDefinition): @classmethod def render_prefix(cls: Type[MarkerDefinition], span: Span, marker: str, context: Block) -> str: marker_definition = next((md for md in context.markDefs if md['_key'] == marker), None) - condition = marker_definition.get('cloudCondition', '') - if not condition: - style = 'display: none' - return f'<{cls.tag} style=\"{style}\">' - else: + if condition := marker_definition.get('cloudCondition', ''): return super().render_prefix(span, marker, context) + else: + return f'<{cls.tag} style="display: none">' renderer = PortableTextRenderer( { From 4a7524241b1f016efbce6dcb18f9327a00623460 Mon Sep 17 00:00:00 2001 From: rootisenabled Date: Tue, 1 Feb 2022 13:55:09 +0100 Subject: [PATCH 18/34] remove walrus operator: pytest tests python 3.7, where the operator is not available yet --- tests/test_marker_definitions.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/test_marker_definitions.py b/tests/test_marker_definitions.py index 9cffcc6..4f5c24d 100644 --- a/tests/test_marker_definitions.py +++ b/tests/test_marker_definitions.py @@ -70,10 +70,12 @@ class ConditionalMarkerDefinition(MarkerDefinition): @classmethod def render_prefix(cls: Type[MarkerDefinition], span: Span, marker: str, context: Block) -> str: marker_definition = next((md for md in context.markDefs if md['_key'] == marker), None) - if condition := marker_definition.get('cloudCondition', ''): - return super().render_prefix(span, marker, context) + condition = marker_definition.get('cloudCondition', '') + if not condition: + style = 'display: none' + return f'<{cls.tag} style=\"{style}\">' else: - return f'<{cls.tag} style="display: none">' + return super().render_prefix(span, marker, context) renderer = PortableTextRenderer( { From ebe606c9809a5fd863b4269bf8e6898936e822ec Mon Sep 17 00:00:00 2001 From: rootisenabled Date: Tue, 1 Feb 2022 14:13:24 +0100 Subject: [PATCH 19/34] release 1.0.1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8d8340c..99aeb7e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = 'portabletext-html' -version = '1.0.0' +version = '1.0.1' description = "HTML renderer for Sanity's Portable Text format" homepage = 'https://github.com/otovo/python-sanity-html' repository = 'https://github.com/otovo/python-sanity-html' From 35803be148a18c9d7ccde24bbe881d78e361bfe1 Mon Sep 17 00:00:00 2001 From: rootisenabled Date: Wed, 9 Feb 2022 14:49:31 +0100 Subject: [PATCH 20/34] add render_text method for custom marker definition class. This method gives a library user more flexibility when using custom marks with complex logic (conditionals, dynamic content substitution" --- portabletext_html/marker_definitions.py | 7 ++++++- tests/test_marker_definitions.py | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/portabletext_html/marker_definitions.py b/portabletext_html/marker_definitions.py index 72cc2d2..396f4e1 100644 --- a/portabletext_html/marker_definitions.py +++ b/portabletext_html/marker_definitions.py @@ -37,10 +37,15 @@ def render_suffix(cls: Type[MarkerDefinition], span: Span, marker: str, context: def render(cls: Type[MarkerDefinition], span: Span, marker: str, context: Block) -> str: """Render the marked span directly with prefix and suffix.""" result = cls.render_prefix(span, marker, context) - result += str(span.text) + result += cls.render_text(span, marker, context) result += cls.render_suffix(span, marker, context) return result + @classmethod + def render_text(cls: Type[MarkerDefinition], span: Span, marker: str, context: Block) -> str: + """Render the content part for a marked span.""" + return str(span.text) + # Decorators diff --git a/tests/test_marker_definitions.py b/tests/test_marker_definitions.py index 4f5c24d..0236cbb 100644 --- a/tests/test_marker_definitions.py +++ b/tests/test_marker_definitions.py @@ -1,3 +1,4 @@ +# pylint: skip-file from typing import Type from portabletext_html import PortableTextRenderer @@ -18,6 +19,7 @@ def test_render_emphasis_marker_success(): for text in sample_texts: node = Span(_type='span', text=text) block = Block(_type='block', children=[node.__dict__]) + assert EmphasisMarkerDefinition.render_text(node, 'em', block) == f'{text}' assert EmphasisMarkerDefinition.render(node, 'em', block) == f'{text}' @@ -25,6 +27,7 @@ def test_render_strong_marker_success(): for text in sample_texts: node = Span(_type='span', text=text) block = Block(_type='block', children=[node.__dict__]) + assert StrongMarkerDefinition.render_text(node, 'strong', block) == f'{text}' assert StrongMarkerDefinition.render(node, 'strong', block) == f'{text}' @@ -32,6 +35,7 @@ def test_render_underline_marker_success(): for text in sample_texts: node = Span(_type='span', text=text) block = Block(_type='block', children=[node.__dict__]) + assert UnderlineMarkerDefinition.render_text(node, 'u', block) == f'{text}' assert ( UnderlineMarkerDefinition.render(node, 'u', block) == f'{text}' @@ -42,6 +46,7 @@ def test_render_strikethrough_marker_success(): for text in sample_texts: node = Span(_type='span', text=text) block = Block(_type='block', children=[node.__dict__]) + assert StrikeThroughMarkerDefinition.render_text(node, 'strike', block) == f'{text}' assert StrikeThroughMarkerDefinition.render(node, 'strike', block) == f'{text}' @@ -51,6 +56,7 @@ def test_render_link_marker_success(): block = Block( _type='block', children=[node.__dict__], markDefs=[{'_type': 'link', '_key': 'linkId', 'href': text}] ) + assert LinkMarkerDefinition.render_text(node, 'linkId', block) == f'{text}' assert LinkMarkerDefinition.render(node, 'linkId', block) == f'{text}' From b136e2fa48399290f002be6a6f70cbaf3636dac9 Mon Sep 17 00:00:00 2001 From: rootisenabled Date: Thu, 10 Feb 2022 09:21:36 +0100 Subject: [PATCH 21/34] update README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 58abe31..fd610a8 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,11 @@ class ComicSansEmphasis(MarkerDefinition): def render_suffix(cls, span: Span, marker: str, context: Block) -> str: return f'' + @classmethod + def render_text(cls, span: Span, marker: str, context: Block) -> str: + # custom rendering logic can be placed here + return str(span.text) + @classmethod def render(cls, span: Span, marker: str, context: Block) -> str: result = cls.render_prefix(span, marker, context) From 5bf33f9b7fe45cd1bb94f93ef2e888111130eee5 Mon Sep 17 00:00:00 2001 From: rootisenabled Date: Thu, 10 Feb 2022 09:25:43 +0100 Subject: [PATCH 22/34] release 1.1.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 99aeb7e..dd2b721 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = 'portabletext-html' -version = '1.0.1' +version = '1.1.0' description = "HTML renderer for Sanity's Portable Text format" homepage = 'https://github.com/otovo/python-sanity-html' repository = 'https://github.com/otovo/python-sanity-html' From e3ca1b111e91417dbde0fab5c80a0da2af9cabe3 Mon Sep 17 00:00:00 2001 From: rootisenabled Date: Sat, 12 Mar 2022 14:33:36 +0100 Subject: [PATCH 23/34] bugfix: call custom mark render_text() on render This commit fixes _render_span method: - if any of a span's marks has overriden render_text() method from the base class, we call it. Note that if a span has multiple mark definitions with render_text() method, only the first one will be processed. This is done to avoid text duplication inside an HTML tag. - otherwise, we append span.text to the resulting HTML string --- portabletext_html/renderer.py | 14 +++++++++++++- portabletext_html/types.py | 2 +- tests/test_marker_definitions.py | 8 +++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/portabletext_html/renderer.py b/portabletext_html/renderer.py index 3804c85..56fbfba 100644 --- a/portabletext_html/renderer.py +++ b/portabletext_html/renderer.py @@ -150,7 +150,19 @@ def _render_span(self, span: Span, block: Block) -> str: marker_callable = block.marker_definitions.get(mark, DefaultMarkerDefinition)() result += marker_callable.render_prefix(span, mark, block) - result += html.escape(span.text).replace('\n', '
') + # to avoid rendering the text multiple times, + # only the first custom mark will be used + custom_mark_text_rendered = False + if sorted_marks: + for mark in sorted_marks: + if custom_mark_text_rendered or mark in prev_marks: + continue + marker_callable = block.marker_definitions.get(mark, DefaultMarkerDefinition)() + result += marker_callable.render_text(span, mark, block) + custom_mark_text_rendered = True + + if not custom_mark_text_rendered: + result += html.escape(span.text).replace('\n', '
') for mark in reversed(sorted_marks): if mark in next_marks: diff --git a/portabletext_html/types.py b/portabletext_html/types.py index ab5236b..898d61e 100644 --- a/portabletext_html/types.py +++ b/portabletext_html/types.py @@ -73,7 +73,7 @@ def _add_custom_marker_definitions(self) -> dict[str, Type[MarkerDefinition]]: if definition['_type'] in self.marker_definitions: marker = self.marker_definitions[definition['_type']] marker_definitions[definition['_key']] = marker - del marker_definitions[definition['_type']] + # del marker_definitions[definition['_type']] return marker_definitions def get_node_siblings(self, node: Union[dict, Span]) -> Tuple[Optional[dict], Optional[dict]]: diff --git a/tests/test_marker_definitions.py b/tests/test_marker_definitions.py index 0236cbb..2677218 100644 --- a/tests/test_marker_definitions.py +++ b/tests/test_marker_definitions.py @@ -83,8 +83,14 @@ def render_prefix(cls: Type[MarkerDefinition], span: Span, marker: str, context: else: return super().render_prefix(span, marker, context) + @classmethod + def render_text(cls: Type[MarkerDefinition], span: Span, marker: str, context: Block) -> str: + marker_definition = next((md for md in context.markDefs if md['_key'] == marker), None) + condition = marker_definition.get('cloudCondition', '') + return span.text if not condition else '' + renderer = PortableTextRenderer( - { + blocks={ '_type': 'block', 'children': [{'_key': 'a1ph4', '_type': 'span', 'marks': ['some_id'], 'text': 'Sanity'}], 'markDefs': [{'_key': 'some_id', '_type': 'contractConditional', 'cloudCondition': False}], From f8ff2f2121d478c8179bea94b0f82b465db1b31b Mon Sep 17 00:00:00 2001 From: rootisenabled Date: Mon, 14 Mar 2022 08:54:40 +0100 Subject: [PATCH 24/34] relese 1.1.1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index dd2b721..8a1bdbb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = 'portabletext-html' -version = '1.1.0' +version = '1.1.1' description = "HTML renderer for Sanity's Portable Text format" homepage = 'https://github.com/otovo/python-sanity-html' repository = 'https://github.com/otovo/python-sanity-html' From 51e8f804b1a1ba6ae0b90279c8fd41b7ae9290ab Mon Sep 17 00:00:00 2001 From: Espen Ogino Rathe Date: Wed, 27 Apr 2022 09:36:54 +0200 Subject: [PATCH 25/34] tests: add tests for _render_node's error handling --- tests/fixtures/invalid_node.json | 13 +++++++++++++ tests/fixtures/invalid_type.json | 14 ++++++++++++++ tests/test_rendering.py | 16 +++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/invalid_node.json create mode 100644 tests/fixtures/invalid_type.json diff --git a/tests/fixtures/invalid_node.json b/tests/fixtures/invalid_node.json new file mode 100644 index 0000000..74f09bf --- /dev/null +++ b/tests/fixtures/invalid_node.json @@ -0,0 +1,13 @@ +{ + "_key": "73405dda68e7", + "children": [ + { + "_key": "25a09c61d80a", + "_type": "span", + "marks": [], + "text": "Otovo guarantee is good" + } + ], + "markDefs": [], + "style": "normal" +} diff --git a/tests/fixtures/invalid_type.json b/tests/fixtures/invalid_type.json new file mode 100644 index 0000000..745ac66 --- /dev/null +++ b/tests/fixtures/invalid_type.json @@ -0,0 +1,14 @@ +{ + "_key": "73405dda68e7", + "_type": "invalid_type", + "children": [ + { + "_key": "25a09c61d80a", + "_type": "span", + "marks": [], + "text": "Otovo guarantee is good" + } + ], + "markDefs": [], + "style": "normal" +} diff --git a/tests/test_rendering.py b/tests/test_rendering.py index 3894862..b418e62 100644 --- a/tests/test_rendering.py +++ b/tests/test_rendering.py @@ -2,7 +2,9 @@ import json from pathlib import Path -from portabletext_html.renderer import render +import pytest + +from portabletext_html.renderer import MissingSerializerError, UnhandledNodeError, render def load_fixture(fixture_name) -> dict: @@ -45,3 +47,15 @@ def test_nested_marks(): fixture = load_fixture('nested_marks.json') output = render(fixture) assert output == '

A word of warning; Sanity is addictive.

' + + +def test_missing_serializer(): + fixture = load_fixture('invalid_type.json') + with pytest.raises(MissingSerializerError): + render(fixture) + + +def test_invalid_node(): + fixture = load_fixture('invalid_node.json') + with pytest.raises(UnhandledNodeError): + render(fixture) From 058b755309ca515dc90c05b7048ddb825994c34d Mon Sep 17 00:00:00 2001 From: Espen Ogino Rathe Date: Wed, 27 Apr 2022 09:40:43 +0200 Subject: [PATCH 26/34] bugfix: fix _render_node's error handling A bug caused the MissingSerializerError to not be raised when it was supposed to --- .pre-commit-config.yaml | 7 +++++-- portabletext_html/renderer.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0968ba6..5dadb48 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/ambv/black - rev: 21.12b0 + rev: 22.3.0 hooks: - id: black args: [ "--quiet" ] @@ -19,7 +19,7 @@ repos: - id: mixed-line-ending - id: trailing-whitespace - repo: https://gitlab.com/pycqa/flake8 - rev: 3.9.2 + rev: 4.0.1 hooks: - id: flake8 additional_dependencies: [ @@ -34,6 +34,9 @@ repos: 'flake8-printf-formatting', 'flake8-type-checking', ] + args: [ + '--allow-star-arg-any' + ] - repo: https://github.com/asottile/pyupgrade rev: v2.31.0 hooks: diff --git a/portabletext_html/renderer.py b/portabletext_html/renderer.py index 56fbfba..e924c35 100644 --- a/portabletext_html/renderer.py +++ b/portabletext_html/renderer.py @@ -113,7 +113,7 @@ def _render_node(self, node: dict, context: Optional[Block] = None, list_item: b return self._custom_serializers.get(node.get('_type', ''))(node, context, list_item) # type: ignore else: - if hasattr(node, '_type'): + if '_type' in node: raise MissingSerializerError( f'Found unhandled node type: {node["_type"]}. ' 'Most likely this requires a custom serializer.' ) From b79237f6cac1c06a5462b0516ac06f3ae34244be Mon Sep 17 00:00:00 2001 From: Espen Ogino Rathe Date: Wed, 27 Apr 2022 10:04:03 +0200 Subject: [PATCH 27/34] Make the 1.1.2 release --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8a1bdbb..2aaec41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = 'portabletext-html' -version = '1.1.1' +version = '1.1.2' description = "HTML renderer for Sanity's Portable Text format" homepage = 'https://github.com/otovo/python-sanity-html' repository = 'https://github.com/otovo/python-sanity-html' From 69fa4757adb0821e73ac5c6f5817e82f346e30a7 Mon Sep 17 00:00:00 2001 From: Espen Ogino Rathe Date: Mon, 20 Jun 2022 16:17:15 +0200 Subject: [PATCH 28/34] tests: add tests for custom serializer block + list bug --- .../custom_serializer_node_after_list.json | 20 +++++++++++++++++++ tests/test_rendering.py | 15 ++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 tests/fixtures/custom_serializer_node_after_list.json diff --git a/tests/fixtures/custom_serializer_node_after_list.json b/tests/fixtures/custom_serializer_node_after_list.json new file mode 100644 index 0000000..39386cf --- /dev/null +++ b/tests/fixtures/custom_serializer_node_after_list.json @@ -0,0 +1,20 @@ +[ + { + "_key": "e5b6e416e6e9", + "_type": "block", + "children": [ + { "_key": "3bbbff0f158b", "_type": "span", "marks": [], "text": "resers" } + ], + "level": 1, + "listItem": "bullet", + "markDefs": [], + "style": "normal" + }, + { + "_key": "73405dda68e0", + "_type": "extraInfoBlock", + "extraInfo": "This informations is not supported by Block", + "markDefs": [], + "style": "normal" + } +] diff --git a/tests/test_rendering.py b/tests/test_rendering.py index b418e62..1c82309 100644 --- a/tests/test_rendering.py +++ b/tests/test_rendering.py @@ -1,10 +1,18 @@ import html import json from pathlib import Path +from typing import Optional import pytest from portabletext_html.renderer import MissingSerializerError, UnhandledNodeError, render +from portabletext_html.types import Block + + +def extraInfoSerializer(node: dict, context: Optional[Block], list_item: bool) -> str: + extraInfo = node.get('extraInfo') + + return f'

{extraInfo}

' def load_fixture(fixture_name) -> dict: @@ -59,3 +67,10 @@ def test_invalid_node(): fixture = load_fixture('invalid_node.json') with pytest.raises(UnhandledNodeError): render(fixture) + + +def test_custom_serializer_node_after_list(): + fixture = load_fixture('custom_serializer_node_after_list.json') + output = render(fixture, custom_serializers={'extraInfoBlock': extraInfoSerializer}) + + assert output == '
  • resers

This informations is not supported by Block

' From bf018e41477177080ec2bf1556b82574d116116f Mon Sep 17 00:00:00 2001 From: Espen Ogino Rathe Date: Mon, 20 Jun 2022 16:20:52 +0200 Subject: [PATCH 29/34] bugfix: fix a bug where custom serializer blocks can fail if after a list This commit fixes a bug where the rendering of a node can fail if it has fields not supported by Block and follows directly after a list item. The list item logic would pass in the first node after the list as context and cast it to a Block. This fails if the node has fields not supported by Block. Which is the case for custom serializer blocks. The context is actually not used, and removing it solves the bug. --- portabletext_html/renderer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portabletext_html/renderer.py b/portabletext_html/renderer.py index e924c35..211125e 100644 --- a/portabletext_html/renderer.py +++ b/portabletext_html/renderer.py @@ -66,7 +66,7 @@ def render(self) -> str: if list_nodes and not is_list(node): tree = self._normalize_list_tree(list_nodes) - result += ''.join([self._render_node(n, Block(**node), list_item=True) for n in tree]) + result += ''.join([self._render_node(n, list_item=True) for n in tree]) list_nodes = [] # reset list_nodes if is_list(node): From 8e895e36bf54b39a8e365d05d2934384ee04ef61 Mon Sep 17 00:00:00 2001 From: Espen Ogino Rathe Date: Tue, 21 Jun 2022 12:04:58 +0200 Subject: [PATCH 30/34] Increase patch version to 1.1.3 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2aaec41..d6e1665 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = 'portabletext-html' -version = '1.1.2' +version = '1.1.3' description = "HTML renderer for Sanity's Portable Text format" homepage = 'https://github.com/otovo/python-sanity-html' repository = 'https://github.com/otovo/python-sanity-html' From aef47dcd03c491a7b618ad39ebcbd978524fd18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Fri, 18 Nov 2022 22:21:12 +0100 Subject: [PATCH 31/34] chore: Update pre-commit hooks and lockfile --- .pre-commit-config.yaml | 17 ++++----- poetry.lock | 71 +++++++++++++++++------------------ portabletext_html/renderer.py | 6 +-- 3 files changed, 46 insertions(+), 48 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5dadb48..6493166 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/ambv/black - rev: 22.3.0 + rev: 22.10.0 hooks: - id: black args: [ "--quiet" ] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.3.0 hooks: - id: check-ast - id: check-merge-conflict @@ -18,8 +18,8 @@ repos: - id: trailing-whitespace - id: mixed-line-ending - id: trailing-whitespace - - repo: https://gitlab.com/pycqa/flake8 - rev: 4.0.1 + - repo: https://github.com/pycqa/flake8 + rev: 5.0.4 hooks: - id: flake8 additional_dependencies: [ @@ -34,11 +34,10 @@ repos: 'flake8-printf-formatting', 'flake8-type-checking', ] - args: [ - '--allow-star-arg-any' - ] + args: + - '--allow-star-arg-any' - repo: https://github.com/asottile/pyupgrade - rev: v2.31.0 + rev: v3.2.2 hooks: - id: pyupgrade args: [ "--py36-plus", "--py37-plus",'--keep-runtime-typing' ] @@ -47,7 +46,7 @@ repos: hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.931 + rev: v0.991 hooks: - id: mypy additional_dependencies: diff --git a/poetry.lock b/poetry.lock index 30cd47f..b05bfd9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,6 +1,6 @@ [[package]] name = "atomicwrites" -version = "1.4.0" +version = "1.4.1" description = "Atomic file writes." category = "dev" optional = false @@ -8,25 +8,25 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "21.4.0" +version = "22.1.0" description = "Classes Without Boilerplate" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.5" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] +dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] +docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] +tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] +tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] [[package]] name = "colorama" -version = "0.4.4" +version = "0.4.6" description = "Cross-platform colored terminal text." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" [[package]] name = "coverage" @@ -55,7 +55,7 @@ pyflakes = ">=2.3.0,<2.4.0" [[package]] name = "importlib-metadata" -version = "4.10.1" +version = "5.0.0" description = "Read metadata from Python packages" category = "dev" optional = false @@ -66,9 +66,9 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] [[package]] name = "iniconfig" @@ -138,11 +138,11 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pyparsing" -version = "3.0.6" -description = "Python parsing module" +version = "3.0.9" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.6.8" [package.extras] diagrams = ["jinja2", "railroad-diagrams"] @@ -183,7 +183,7 @@ pytest = ">=4.6" toml = "*" [package.extras] -testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] [[package]] name = "toml" @@ -195,23 +195,23 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "typing-extensions" -version = "4.0.1" -description = "Backported and Experimental Type Hints for Python 3.6+" +version = "4.4.0" +description = "Backported and Experimental Type Hints for Python 3.7+" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "zipp" -version = "3.7.0" +version = "3.10.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "dev" optional = false python-versions = ">=3.7" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" @@ -220,16 +220,15 @@ content-hash = "c641d950bccb6ffac52cf3fcd3571b51f5e31d4864c03e763fe2748919bf855b [metadata.files] atomicwrites = [ - {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, - {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, + {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, ] attrs = [ - {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, - {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, + {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, + {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, ] colorama = [ - {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, - {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] coverage = [ {file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"}, @@ -290,8 +289,8 @@ flake8 = [ {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.10.1-py3-none-any.whl", hash = "sha256:899e2a40a8c4a1aec681feef45733de8a6c58f3f6a0dbed2eb6574b4387a77b6"}, - {file = "importlib_metadata-4.10.1.tar.gz", hash = "sha256:951f0d8a5b7260e9db5e41d429285b5f451e928479f19d80818878527d36e95e"}, + {file = "importlib_metadata-5.0.0-py3-none-any.whl", hash = "sha256:ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43"}, + {file = "importlib_metadata-5.0.0.tar.gz", hash = "sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -322,8 +321,8 @@ pyflakes = [ {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] pyparsing = [ - {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, - {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, + {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, ] pytest = [ {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, @@ -338,10 +337,10 @@ toml = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] typing-extensions = [ - {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"}, - {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"}, + {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, + {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, ] zipp = [ - {file = "zipp-3.7.0-py3-none-any.whl", hash = "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"}, - {file = "zipp-3.7.0.tar.gz", hash = "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d"}, + {file = "zipp-3.10.0-py3-none-any.whl", hash = "sha256:4fcb6f278987a6605757302a6e40e896257570d11c51628968ccb2a47e80c6c1"}, + {file = "zipp-3.10.0.tar.gz", hash = "sha256:7a7262fd930bd3e36c50b9a64897aec3fafff3dfdeec9623ae22b40e93f99bb8"}, ] diff --git a/portabletext_html/renderer.py b/portabletext_html/renderer.py index 211125e..1ca2ce3 100644 --- a/portabletext_html/renderer.py +++ b/portabletext_html/renderer.py @@ -38,8 +38,8 @@ class PortableTextRenderer: def __init__( self, blocks: Union[list[dict], dict], - custom_marker_definitions: dict[str, Type[MarkerDefinition]] = None, - custom_serializers: dict[str, Callable[[dict, Optional[Block], bool], str]] = None, + custom_marker_definitions: dict[str, Type[MarkerDefinition]] | None = None, + custom_serializers: dict[str, Callable[[dict, Optional[Block], bool], str]] | None = None, ) -> None: logger.debug('Initializing block renderer') self._wrapper_element: Optional[str] = None @@ -106,7 +106,7 @@ def _render_node(self, node: dict, context: Optional[Block] = None, list_item: b elif is_span(node): logger.debug('Rendering node as span') span = Span(**node) - context = cast(Block, context) # context should always be a Block here + context = cast('Block', context) # context should always be a Block here return self._render_span(span, block=context) elif self._custom_serializers.get(node.get('_type', '')): From fcf1489bf01df025e6afce7f855a0ddba20ae0fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Fri, 18 Nov 2022 22:22:20 +0100 Subject: [PATCH 32/34] chore: Add Python 3.11 to test suite --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 45b4dc7..5692bbf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,7 +38,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [ "3.7", "3.8", "3.9", "3.10" ] + python-version: [ "3.7.14", "3.8.14", "3.9.15", "3.10.8", "3.11.0" ] steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 From 4515b42662c13a10744ff8f24fd148888dda523d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Fri, 18 Nov 2022 22:22:37 +0100 Subject: [PATCH 33/34] chore: Add Python 3.11 package classifiers --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index d6e1665..7dc039a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,7 @@ classifiers = [ 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', 'Typing :: Typed', ] From 7cd5d21abca77e61bebc3fd46b13ee37842de13c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Fri, 18 Nov 2022 22:23:09 +0100 Subject: [PATCH 34/34] chore: Add Python 3.12 alpha to test suite --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5692bbf..22b34ce 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,7 +38,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [ "3.7.14", "3.8.14", "3.9.15", "3.10.8", "3.11.0" ] + python-version: [ "3.7.14", "3.8.14", "3.9.15", "3.10.8", "3.11.0", "3.12.0-alpha.1" ] steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2