From e2096de7f3009dcc9ef64dd3a29d0d04356f956e Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Wed, 9 Mar 2022 14:32:42 +0000 Subject: [PATCH 01/18] chore: add mypy testing Scaffolding in the testing, and will not complete succssfully yet. Will be followed by code changes to pass. Signed-off-by: Mike Fiedler --- .github/workflows/ci.yml | 2 ++ pyproject.toml | 9 +++++++++ tox.ini | 11 ++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd37c5f..4ea6e68 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,8 @@ jobs: run: python -m pip install tox - name: Run linting run: python -m tox -e pep8 + - name: Run mypy + run: python -m tox -e mypy packaging: name: Packaging runs-on: ubuntu-latest diff --git a/pyproject.toml b/pyproject.toml index 058a690..df12ffd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,12 @@ [build-system] requires = ["setuptools>=40.8.0", "wheel", "bleach>=2.1.0", "docutils>=0.13.1", "Pygments>=2.5.1"] build-backend = "setuptools.build_meta:__legacy__" + +[tool.mypy] +warn_unused_configs = true +[[tool.mypy.overrides]] +# These modules do not yet have types available. +module = [ + "cmarkgfm.*" +] +ignore_missing_imports = true diff --git a/tox.ini b/tox.ini index 9adf936..c60eeb4 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py36,py37,py38,py39,py310,pep8,packaging,noextra +envlist = py36,py37,py38,py39,py310,pep8,packaging,noextra,mypy [testenv] deps = @@ -8,6 +8,15 @@ commands = pytest --strict {posargs} extras = md +[testenv:mypy] +basepython = python3 +deps = + mypy + types-bleach + types-docutils + types-Pygments +commands = mypy readme_renderer + [testenv:pep8] basepython = python3 deps = From a0903b16a59c73e3456906d7060b0f79c6a7f802 Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Wed, 9 Mar 2022 23:31:36 +0000 Subject: [PATCH 02/18] lint: ignore empty dict Surfaced via `mypy`, in that an empty dict could not infer what types could be there. Instead of importing `typing` and annotating the empty Dict, I opted to ignore the line, as we do not expect to populate the dict at all, and are using it to **prevent** additions to the value. Signed-off-by: Mike Fiedler --- readme_renderer/rst.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme_renderer/rst.py b/readme_renderer/rst.py index d78394c..7ecf947 100644 --- a/readme_renderer/rst.py +++ b/readme_renderer/rst.py @@ -25,7 +25,7 @@ class ReadMeHTMLTranslator(HTMLTranslator): # Overrides base class not to output `` tag for SVG images. - object_image_types = {} + object_image_types = {} # type: ignore def emptytag(self, node, tagname, suffix="\n", **attributes): """Override this to add back the width/height attributes.""" From bdae3c3a72487981438e863c705df5d94aef35d9 Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Wed, 9 Mar 2022 23:06:03 +0000 Subject: [PATCH 03/18] chore: remove unused styles parameter Surfaced via `mypy`, recommended adding a type to the empty list. The list was originally empty back in 0.1.0. Instead of adding a type, remove the constant, and the code that uses it from `clean()` - as it was partially reverted in #121. The default `ALLOWED_STYLES` in the underlying library is `[]`. Related: https://github.com/pypa/readme_renderer/pull/114#discussion_r218405013 Signed-off-by: Mike Fiedler --- readme_renderer/clean.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/readme_renderer/clean.py b/readme_renderer/clean.py index 190f423..99fe80c 100644 --- a/readme_renderer/clean.py +++ b/readme_renderer/clean.py @@ -59,9 +59,6 @@ "input": ["type", "checked", "disabled"], } -ALLOWED_STYLES = [ -] - class DisabledCheckboxInputsFilter: def __init__(self, source): @@ -89,19 +86,16 @@ def __getattr__(self, name): return getattr(self.source, name) -def clean(html, tags=None, attributes=None, styles=None): +def clean(html, tags=None, attributes=None): if tags is None: tags = ALLOWED_TAGS if attributes is None: attributes = ALLOWED_ATTRIBUTES - if styles is None: - styles = ALLOWED_STYLES # Clean the output using Bleach cleaner = bleach.sanitizer.Cleaner( tags=tags, attributes=attributes, - styles=styles, filters=[ # Bleach Linkify makes it easy to modify links, however, we will # not be using it to create additional links. From 8817a2db4adfad37e3fd4fb754b46984893aeb8d Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Wed, 9 Mar 2022 23:20:42 +0000 Subject: [PATCH 04/18] fix: correct import for unescape Surfaced via `mypy`, in that the `html.parser` module does not have a direct implementation of `unescape`. Refs: https://docs.python.org/3.6/library/html.html#html.unescape In #192 support for Python 2.7 was removed, the import path changed. This works due to imports placing the imported code in the local scope. If the `html.parser` module ever stopped importing `unescape`, this import would break as a result. Signed-off-by: Mike Fiedler --- readme_renderer/markdown.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme_renderer/markdown.py b/readme_renderer/markdown.py index fdf84ed..6cd1e97 100644 --- a/readme_renderer/markdown.py +++ b/readme_renderer/markdown.py @@ -16,7 +16,7 @@ import re import warnings -from html.parser import unescape +from html import unescape import pygments import pygments.lexers From 144692e219b393f6075e835adacb22d99da8dad8 Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Wed, 9 Mar 2022 23:36:10 +0000 Subject: [PATCH 05/18] chore: update pytest markers cli flag Currently emits a warning: PytestRemovedIn8Warning: The --strict option is deprecated, use --strict-markers instead. Signed-off-by: Mike Fiedler --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index c60eeb4..dff1b2d 100644 --- a/tox.ini +++ b/tox.ini @@ -5,7 +5,7 @@ envlist = py36,py37,py38,py39,py310,pep8,packaging,noextra,mypy deps = pytest commands = - pytest --strict {posargs} + pytest --strict-markers {posargs} extras = md [testenv:mypy] From 3224f56426181847a70cb54e1735d851f64f41bb Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Thu, 10 Mar 2022 00:17:58 +0000 Subject: [PATCH 06/18] chore(types): add types to clean module Surfaced by running mypy in strict mode, and added types where relevant. Signed-off-by: Mike Fiedler --- readme_renderer/clean.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/readme_renderer/clean.py b/readme_renderer/clean.py index 99fe80c..d8e66c0 100644 --- a/readme_renderer/clean.py +++ b/readme_renderer/clean.py @@ -14,6 +14,7 @@ from __future__ import absolute_import, division, print_function import functools +import typing import bleach import bleach.callbacks @@ -61,10 +62,10 @@ class DisabledCheckboxInputsFilter: - def __init__(self, source): + def __init__(self, source: typing.Any) -> None: self.source = source - def __iter__(self): + def __iter__(self) -> typing.Iterator[typing.Dict[str, typing.Optional[str]]]: for token in self.source: if token.get("name") == "input": # only allow disabled checkbox inputs @@ -82,11 +83,15 @@ def __iter__(self): else: yield token - def __getattr__(self, name): + def __getattr__(self, name: str) -> typing.Any: return getattr(self.source, name) -def clean(html, tags=None, attributes=None): +def clean( + html: str, + tags: typing.Optional[typing.List[str]] = None, + attributes: typing.Optional[typing.Dict[str, typing.List[str]]] = None +) -> typing.Optional[str]: if tags is None: tags = ALLOWED_TAGS if attributes is None: From 8eb342fb46093b267190991449ae01a16af03c16 Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Thu, 10 Mar 2022 00:23:05 +0000 Subject: [PATCH 07/18] chore(types): add types to txt module Signed-off-by: Mike Fiedler --- readme_renderer/txt.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/readme_renderer/txt.py b/readme_renderer/txt.py index 3218922..365164d 100644 --- a/readme_renderer/txt.py +++ b/readme_renderer/txt.py @@ -14,6 +14,7 @@ from __future__ import absolute_import, division, print_function import sys +import typing from .clean import clean @@ -26,6 +27,6 @@ def html_escape(s): return escape(s, quote=True).replace("'", ''') -def render(raw, **kwargs): +def render(raw: str, **kwargs: typing.Any) -> typing.Optional[str]: rendered = html_escape(raw).replace("\n", "
") return clean(rendered, tags=["br"]) From c959bfd0abb89454aab171b60955cdfce497721a Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Thu, 10 Mar 2022 00:35:34 +0000 Subject: [PATCH 08/18] chore(types): add types to markdown module Signed-off-by: Mike Fiedler --- readme_renderer/markdown.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/readme_renderer/markdown.py b/readme_renderer/markdown.py index 6cd1e97..18ad573 100644 --- a/readme_renderer/markdown.py +++ b/readme_renderer/markdown.py @@ -15,6 +15,7 @@ import re import warnings +from typing import Any, Match, Optional from html import unescape @@ -51,7 +52,7 @@ } -def render(raw, variant="GFM", **kwargs): +def render(raw: str, variant: str = "GFM", **kwargs: Any) -> Optional[str]: if not variants: warnings.warn(_EXTRA_WARNING) return None @@ -61,7 +62,8 @@ def render(raw, variant="GFM", **kwargs): if not renderer: return None - rendered = renderer(raw) + # The renderer is a lambda function, and mypy fails lambdas right now. + rendered = renderer(raw) # type: ignore if not rendered: return None @@ -71,7 +73,7 @@ def render(raw, variant="GFM", **kwargs): return cleaned -def _highlight(html): +def _highlight(html: str) -> str: """Syntax-highlights HTML-rendered Markdown. Plucks sections to highlight that conform the the GitHub fenced code info @@ -94,7 +96,7 @@ def _highlight(html): '(?(in_code)|)(?P.+?)' r'', re.DOTALL) - def replacer(match): + def replacer(match: Match[Any]) -> str: try: lang = match.group('lang') lang = _LANG_ALIASES.get(lang, lang) From d4d80cefce24ebdb20e23aa7f157011b8dcf9cca Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Thu, 10 Mar 2022 00:50:22 +0000 Subject: [PATCH 09/18] chore: add types to rst module The types-docutils hints are still incomplete, good progress is being made. See: https://github.com/python/typeshed/pull/7256 I've had to use an ignore on the class inheritance, and a couple of `typing.Any` annotations until that package implements more type hints. Signed-off-by: Mike Fiedler --- readme_renderer/rst.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/readme_renderer/rst.py b/readme_renderer/rst.py index 7ecf947..70f8d30 100644 --- a/readme_renderer/rst.py +++ b/readme_renderer/rst.py @@ -14,20 +14,28 @@ from __future__ import absolute_import, division, print_function import io +import typing from docutils.core import publish_parts +from docutils.nodes import colspec, image from docutils.writers.html4css1 import HTMLTranslator, Writer from docutils.utils import SystemMessage from .clean import clean -class ReadMeHTMLTranslator(HTMLTranslator): +class ReadMeHTMLTranslator(HTMLTranslator): # type: ignore # Overrides base class not to output `` tag for SVG images. object_image_types = {} # type: ignore - def emptytag(self, node, tagname, suffix="\n", **attributes): + def emptytag( + self, + node: typing.Union[colspec, image], + tagname: str, + suffix: str = "\n", + **attributes: typing.Any + ) -> typing.Any: """Override this to add back the width/height attributes.""" if tagname == "img": if "width" in node: @@ -95,7 +103,11 @@ def emptytag(self, node, tagname, suffix="\n", **attributes): } -def render(raw, stream=None, **kwargs): +def render( + raw: str, + stream: typing.Optional[typing.Any] = None, + **kwargs: typing.Any +) -> typing.Optional[str]: if stream is None: # Use a io.StringIO as the warning stream to prevent warnings from # being printed to sys.stderr. From b06aeb53da20c9a50bf852c7a6e32adce10560f2 Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Thu, 10 Mar 2022 01:18:16 +0000 Subject: [PATCH 10/18] chore: ignore distutils module from types `mypy` strict mode is having a hard time with the `distutils` imports, since they are wrapped in `setuptools` right now as a private package. This pacakge's distutils integration will need to be reworked anyhow. Left a comment with details at the top of the file. Signed-off-by: Mike Fiedler --- readme_renderer/integration/distutils.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/readme_renderer/integration/distutils.py b/readme_renderer/integration/distutils.py index eb04460..2af851a 100644 --- a/readme_renderer/integration/distutils.py +++ b/readme_renderer/integration/distutils.py @@ -11,6 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + +# The `distutils` integration is going to need to get updated to `setuptools`` +# soon enough, as `distutils` is deprecated and will be removed in Python 3.12. +# There's currently some pass-through imports that allow this to work, but is +# challenging for `mypy` in `strict` mode, so let's skip this file for now. +# See https://peps.python.org/pep-0632/ +# mypy: ignore-errors from __future__ import absolute_import, division, print_function import cgi From 51fb70de84a277ffc5d2d40ac582c7244e4fdc9e Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Thu, 10 Mar 2022 01:19:54 +0000 Subject: [PATCH 11/18] test: use strict mode for mypy Prevent new things from creeping in during development. Signed-off-by: Mike Fiedler --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index dff1b2d..d40a6d3 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,7 @@ deps = types-bleach types-docutils types-Pygments -commands = mypy readme_renderer +commands = mypy --strict readme_renderer [testenv:pep8] basepython = python3 From c8c444a5c3f63dad013b2fe07cfade809282dd23 Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Thu, 10 Mar 2022 01:27:09 +0000 Subject: [PATCH 12/18] chore: tell the world we've got types Include a blank `py.typed` file in the package to inform `mypy` that there's types to be found in this package. Signed-off-by: Mike Fiedler --- MANIFEST.in | 1 + readme_renderer/py.typed | 0 2 files changed, 1 insertion(+) create mode 100644 readme_renderer/py.typed diff --git a/MANIFEST.in b/MANIFEST.in index cfa0b3a..1533bc0 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,6 @@ include LICENSE README.rst CHANGES.rst include tox.ini .coveragerc pytest.ini +include readme_renderer/py.typed recursive-include tests *.html recursive-include tests *.py diff --git a/readme_renderer/py.typed b/readme_renderer/py.typed new file mode 100644 index 0000000..e69de29 From 66f3ec36ab9b81d1889648ad4418ec9792915972 Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Thu, 10 Mar 2022 13:35:36 +0000 Subject: [PATCH 13/18] chore: move strict flag to config Allows other tools to ebenfit from a consistent configuration. Signed-off-by: Mike Fiedler --- pyproject.toml | 1 + tox.ini | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index df12ffd..9af657a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,6 +3,7 @@ requires = ["setuptools>=40.8.0", "wheel", "bleach>=2.1.0", "docutils>=0.13.1", build-backend = "setuptools.build_meta:__legacy__" [tool.mypy] +strict = true warn_unused_configs = true [[tool.mypy.overrides]] # These modules do not yet have types available. diff --git a/tox.ini b/tox.ini index d40a6d3..dff1b2d 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,7 @@ deps = types-bleach types-docutils types-Pygments -commands = mypy --strict readme_renderer +commands = mypy readme_renderer [testenv:pep8] basepython = python3 From 77ffeff39127ba821c575e5c8220a80ca9e5e7d3 Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Thu, 10 Mar 2022 13:43:14 +0000 Subject: [PATCH 14/18] refactor: change imports to be consistent with others Signed-off-by: Mike Fiedler --- readme_renderer/markdown.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/readme_renderer/markdown.py b/readme_renderer/markdown.py index 18ad573..d7d48d9 100644 --- a/readme_renderer/markdown.py +++ b/readme_renderer/markdown.py @@ -14,8 +14,8 @@ from __future__ import absolute_import, division, print_function import re +import typing import warnings -from typing import Any, Match, Optional from html import unescape @@ -52,7 +52,11 @@ } -def render(raw: str, variant: str = "GFM", **kwargs: Any) -> Optional[str]: +def render( + raw: str, + variant: str = "GFM", + **kwargs: typing.Any +) -> typing.Optional[str]: if not variants: warnings.warn(_EXTRA_WARNING) return None @@ -96,7 +100,7 @@ def _highlight(html: str) -> str: '(?(in_code)|)(?P.+?)' r'', re.DOTALL) - def replacer(match: Match[Any]) -> str: + def replacer(match: typing.Match[typing.Any]) -> str: try: lang = match.group('lang') lang = _LANG_ALIASES.get(lang, lang) From 887cdc3fa7bb08680b1bdbfa37c27b570af7b4ca Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Thu, 10 Mar 2022 13:47:05 +0000 Subject: [PATCH 15/18] docs: add inline details for specific ignores Signed-off-by: Mike Fiedler --- readme_renderer/rst.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme_renderer/rst.py b/readme_renderer/rst.py index 70f8d30..e8faa75 100644 --- a/readme_renderer/rst.py +++ b/readme_renderer/rst.py @@ -24,10 +24,10 @@ from .clean import clean -class ReadMeHTMLTranslator(HTMLTranslator): # type: ignore +class ReadMeHTMLTranslator(HTMLTranslator): # type: ignore[misc] # docutils is incomplete, returns `Any` python/typeshed#7256 # noqa E501 # Overrides base class not to output `` tag for SVG images. - object_image_types = {} # type: ignore + object_image_types = {} # type: ignore[var-annotated] # intentnionally empty def emptytag( self, From a8203b2014fd4f6e03e6dd24db765d08ecbb1ab7 Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Thu, 10 Mar 2022 13:50:37 +0000 Subject: [PATCH 16/18] lint: apply more specific type Signed-off-by: Mike Fiedler --- readme_renderer/rst.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme_renderer/rst.py b/readme_renderer/rst.py index e8faa75..b2dcf25 100644 --- a/readme_renderer/rst.py +++ b/readme_renderer/rst.py @@ -105,7 +105,7 @@ def emptytag( def render( raw: str, - stream: typing.Optional[typing.Any] = None, + stream: typing.Optional[typing.IO[str]] = None, **kwargs: typing.Any ) -> typing.Optional[str]: if stream is None: From 4be323ac7e077897fb46a614185ccad90a7f1acd Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Thu, 10 Mar 2022 14:05:13 +0000 Subject: [PATCH 17/18] docs: add comment to why source is Any Signed-off-by: Mike Fiedler --- readme_renderer/clean.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme_renderer/clean.py b/readme_renderer/clean.py index d8e66c0..9b1663d 100644 --- a/readme_renderer/clean.py +++ b/readme_renderer/clean.py @@ -62,6 +62,8 @@ class DisabledCheckboxInputsFilter: + # The typeshed for bleach (html5lib) filters is incomplete, use `typing.Any` + # See https://github.com/python/typeshed/blob/505ea726415016e53638c8b584b8fdc9c722cac1/stubs/bleach/bleach/html5lib_shim.pyi#L7-L8 # noqa E501 def __init__(self, source: typing.Any) -> None: self.source = source From 710c2e754db409f099b99556174e8778d5305e68 Mon Sep 17 00:00:00 2001 From: Mike Fiedler Date: Fri, 11 Mar 2022 12:52:22 +0000 Subject: [PATCH 18/18] lint: replace typing imports with relative ones Signed-off-by: Mike Fiedler --- readme_renderer/clean.py | 14 +++++++------- readme_renderer/markdown.py | 8 ++++---- readme_renderer/rst.py | 16 ++++++++-------- readme_renderer/txt.py | 4 ++-- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/readme_renderer/clean.py b/readme_renderer/clean.py index 9b1663d..042883c 100644 --- a/readme_renderer/clean.py +++ b/readme_renderer/clean.py @@ -14,7 +14,7 @@ from __future__ import absolute_import, division, print_function import functools -import typing +from typing import Any, Dict, Iterator, List, Optional import bleach import bleach.callbacks @@ -64,10 +64,10 @@ class DisabledCheckboxInputsFilter: # The typeshed for bleach (html5lib) filters is incomplete, use `typing.Any` # See https://github.com/python/typeshed/blob/505ea726415016e53638c8b584b8fdc9c722cac1/stubs/bleach/bleach/html5lib_shim.pyi#L7-L8 # noqa E501 - def __init__(self, source: typing.Any) -> None: + def __init__(self, source: Any) -> None: self.source = source - def __iter__(self) -> typing.Iterator[typing.Dict[str, typing.Optional[str]]]: + def __iter__(self) -> Iterator[Dict[str, Optional[str]]]: for token in self.source: if token.get("name") == "input": # only allow disabled checkbox inputs @@ -85,15 +85,15 @@ def __iter__(self) -> typing.Iterator[typing.Dict[str, typing.Optional[str]]]: else: yield token - def __getattr__(self, name: str) -> typing.Any: + def __getattr__(self, name: str) -> Any: return getattr(self.source, name) def clean( html: str, - tags: typing.Optional[typing.List[str]] = None, - attributes: typing.Optional[typing.Dict[str, typing.List[str]]] = None -) -> typing.Optional[str]: + tags: Optional[List[str]] = None, + attributes: Optional[Dict[str, List[str]]] = None +) -> Optional[str]: if tags is None: tags = ALLOWED_TAGS if attributes is None: diff --git a/readme_renderer/markdown.py b/readme_renderer/markdown.py index d7d48d9..416c02e 100644 --- a/readme_renderer/markdown.py +++ b/readme_renderer/markdown.py @@ -14,8 +14,8 @@ from __future__ import absolute_import, division, print_function import re -import typing import warnings +from typing import Any, Match, Optional from html import unescape @@ -55,8 +55,8 @@ def render( raw: str, variant: str = "GFM", - **kwargs: typing.Any -) -> typing.Optional[str]: + **kwargs: Any +) -> Optional[str]: if not variants: warnings.warn(_EXTRA_WARNING) return None @@ -100,7 +100,7 @@ def _highlight(html: str) -> str: '(?(in_code)|)(?P.+?)' r'', re.DOTALL) - def replacer(match: typing.Match[typing.Any]) -> str: + def replacer(match: Match[Any]) -> str: try: lang = match.group('lang') lang = _LANG_ALIASES.get(lang, lang) diff --git a/readme_renderer/rst.py b/readme_renderer/rst.py index b2dcf25..f237f32 100644 --- a/readme_renderer/rst.py +++ b/readme_renderer/rst.py @@ -14,7 +14,7 @@ from __future__ import absolute_import, division, print_function import io -import typing +from typing import Any, Dict, IO, Optional, Union from docutils.core import publish_parts from docutils.nodes import colspec, image @@ -27,15 +27,15 @@ class ReadMeHTMLTranslator(HTMLTranslator): # type: ignore[misc] # docutils is incomplete, returns `Any` python/typeshed#7256 # noqa E501 # Overrides base class not to output `` tag for SVG images. - object_image_types = {} # type: ignore[var-annotated] # intentnionally empty + object_image_types: Dict[str, str] = {} def emptytag( self, - node: typing.Union[colspec, image], + node: Union[colspec, image], tagname: str, suffix: str = "\n", - **attributes: typing.Any - ) -> typing.Any: + **attributes: Any + ) -> Any: """Override this to add back the width/height attributes.""" if tagname == "img": if "width" in node: @@ -105,9 +105,9 @@ def emptytag( def render( raw: str, - stream: typing.Optional[typing.IO[str]] = None, - **kwargs: typing.Any -) -> typing.Optional[str]: + stream: Optional[IO[str]] = None, + **kwargs: Any +) -> Optional[str]: if stream is None: # Use a io.StringIO as the warning stream to prevent warnings from # being printed to sys.stderr. diff --git a/readme_renderer/txt.py b/readme_renderer/txt.py index 365164d..13dc38a 100644 --- a/readme_renderer/txt.py +++ b/readme_renderer/txt.py @@ -14,7 +14,7 @@ from __future__ import absolute_import, division, print_function import sys -import typing +from typing import Any, Optional from .clean import clean @@ -27,6 +27,6 @@ def html_escape(s): return escape(s, quote=True).replace("'", ''') -def render(raw: str, **kwargs: typing.Any) -> typing.Optional[str]: +def render(raw: str, **kwargs: Any) -> Optional[str]: rendered = html_escape(raw).replace("\n", "
") return clean(rendered, tags=["br"])