From 255ab1d610bb76add8c60cd813768b9219e00950 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sat, 4 Jan 2025 06:37:44 -0600 Subject: [PATCH] chore(ruff) Automated fixes for typing annotations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed 215 errors: - docs/conf.py: 2 × UP007 (non-pep604-annotation) 2 × UP037 (quoted-annotation) 1 × I002 (missing-required-import) 1 × I001 (unsorted-imports) - src/django_docutils/__about__.py: 1 × I002 (missing-required-import) - src/django_docutils/_internal/types.py: 2 × UP037 (quoted-annotation) 1 × I002 (missing-required-import) - src/django_docutils/exc.py: 1 × I002 (missing-required-import) - src/django_docutils/lib/directives/code.py: 1 × TC003 (typing-only-standard-library-import) 1 × I002 (missing-required-import) 1 × UP037 (quoted-annotation) 1 × I001 (unsorted-imports) - src/django_docutils/lib/directives/registry.py: 1 × I002 (missing-required-import) - src/django_docutils/lib/metadata/extract.py: 2 × UP007 (non-pep604-annotation) 1 × F401 (unused-import) 1 × I002 (missing-required-import) 1 × I001 (unsorted-imports) - src/django_docutils/lib/metadata/process.py: 1 × I002 (missing-required-import) - src/django_docutils/lib/metadata/processors.py: 1 × I002 (missing-required-import) - src/django_docutils/lib/metadata/tests/test_extract.py: 1 × I001 (unsorted-imports) 1 × TC003 (typing-only-standard-library-import) 1 × I002 (missing-required-import) - src/django_docutils/lib/metadata/tests/test_process.py: 1 × I002 (missing-required-import) - src/django_docutils/lib/publisher.py: 11 × UP007 (non-pep604-annotation) 2 × UP037 (quoted-annotation) 1 × I002 (missing-required-import) 1 × TC002 (typing-only-third-party-import) 1 × I001 (unsorted-imports) - src/django_docutils/lib/roles/common.py: 3 × UP037 (quoted-annotation) 2 × UP007 (non-pep604-annotation) 1 × I002 (missing-required-import) - src/django_docutils/lib/roles/email.py: 2 × UP007 (non-pep604-annotation) 2 × I001 (unsorted-imports) 1 × TC001 (typing-only-first-party-import) 1 × I002 (missing-required-import) 1 × TC002 (typing-only-third-party-import) - src/django_docutils/lib/roles/file.py: 6 × UP007 (non-pep604-annotation) 1 × TC002 (typing-only-third-party-import) 1 × I002 (missing-required-import) - src/django_docutils/lib/roles/github.py: 2 × UP007 (non-pep604-annotation) 2 × I001 (unsorted-imports) 1 × I002 (missing-required-import) 1 × TC001 (typing-only-first-party-import) 1 × TC002 (typing-only-third-party-import) - src/django_docutils/lib/roles/hackernews.py: 2 × UP007 (non-pep604-annotation) 2 × I001 (unsorted-imports) 1 × I002 (missing-required-import) 1 × TC001 (typing-only-first-party-import) 1 × TC002 (typing-only-third-party-import) - src/django_docutils/lib/roles/kbd.py: 2 × UP007 (non-pep604-annotation) 1 × TC002 (typing-only-third-party-import) 1 × I002 (missing-required-import) - src/django_docutils/lib/roles/leanpub.py: 2 × UP007 (non-pep604-annotation) 2 × I001 (unsorted-imports) 1 × I002 (missing-required-import) 1 × TC001 (typing-only-first-party-import) 1 × TC002 (typing-only-third-party-import) - src/django_docutils/lib/roles/pypi.py: 2 × UP007 (non-pep604-annotation) 2 × I001 (unsorted-imports) 1 × I002 (missing-required-import) 1 × TC001 (typing-only-first-party-import) 1 × TC002 (typing-only-third-party-import) - src/django_docutils/lib/roles/readthedocs.py: 2 × UP007 (non-pep604-annotation) 2 × I001 (unsorted-imports) 1 × TC001 (typing-only-first-party-import) 1 × I002 (missing-required-import) 1 × TC002 (typing-only-third-party-import) - src/django_docutils/lib/roles/registry.py: 1 × I002 (missing-required-import) - src/django_docutils/lib/roles/twitter.py: 2 × UP007 (non-pep604-annotation) 2 × I001 (unsorted-imports) 1 × I002 (missing-required-import) 1 × TC001 (typing-only-first-party-import) 1 × TC002 (typing-only-third-party-import) - src/django_docutils/lib/roles/types.py: 1 × I002 (missing-required-import) - src/django_docutils/lib/roles/url.py: 2 × UP007 (non-pep604-annotation) 2 × I001 (unsorted-imports) 1 × I002 (missing-required-import) 1 × TC001 (typing-only-first-party-import) 1 × TC002 (typing-only-third-party-import) - src/django_docutils/lib/roles/wikipedia.py: 2 × UP007 (non-pep604-annotation) 2 × I001 (unsorted-imports) 1 × TC001 (typing-only-first-party-import) 1 × I002 (missing-required-import) 1 × TC002 (typing-only-third-party-import) - src/django_docutils/lib/settings.py: 1 × UP007 (non-pep604-annotation) 1 × I002 (missing-required-import) - src/django_docutils/lib/tests/test_utils.py: 1 × I002 (missing-required-import) - src/django_docutils/lib/tests/test_writers.py: 1 × I002 (missing-required-import) - src/django_docutils/lib/text.py: 1 × I002 (missing-required-import) - src/django_docutils/lib/transforms/code.py: 8 × UP037 (quoted-annotation) 1 × UP007 (non-pep604-annotation) 1 × I002 (missing-required-import) - src/django_docutils/lib/transforms/toc.py: 2 × UP007 (non-pep604-annotation) 1 × I002 (missing-required-import) - src/django_docutils/lib/types.py: 1 × I002 (missing-required-import) - src/django_docutils/lib/utils.py: 1 × TC003 (typing-only-standard-library-import) 1 × I002 (missing-required-import) 1 × UP037 (quoted-annotation) 1 × I001 (unsorted-imports) - src/django_docutils/lib/views.py: 7 × UP007 (non-pep604-annotation) 2 × I001 (unsorted-imports) 2 × TC002 (typing-only-third-party-import) 1 × I002 (missing-required-import) 1 × TC001 (typing-only-first-party-import) - src/django_docutils/lib/writers.py: 4 × UP007 (non-pep604-annotation) 1 × TC002 (typing-only-third-party-import) 1 × I002 (missing-required-import) - src/django_docutils/template.py: 4 × UP037 (quoted-annotation) 2 × UP007 (non-pep604-annotation) 1 × I002 (missing-required-import) 1 × TC002 (typing-only-third-party-import) - src/django_docutils/templatetags/django_docutils.py: 7 × UP007 (non-pep604-annotation) 1 × F401 (unused-import) 1 × I002 (missing-required-import) 1 × I001 (unsorted-imports) - src/django_docutils/views.py: 11 × UP007 (non-pep604-annotation) 2 × TC002 (typing-only-third-party-import) 1 × I002 (missing-required-import) 1 × I001 (unsorted-imports) - tests/constants.py: 1 × I002 (missing-required-import) - tests/settings.py: 1 × I002 (missing-required-import) 1 × UP037 (quoted-annotation) - tests/test_docutils_roles.py: 2 × TC002 (typing-only-third-party-import) 1 × UP007 (non-pep604-annotation) 1 × I002 (missing-required-import) 1 × TC003 (typing-only-standard-library-import) 1 × I001 (unsorted-imports) - tests/test_template.py: 1 × TC003 (typing-only-standard-library-import) 1 × I002 (missing-required-import) 1 × UP037 (quoted-annotation) 1 × I001 (unsorted-imports) - tests/test_templatetag.py: 1 × I002 (missing-required-import) Found 567 errors (215 fixed, 352 remaining). 43 files reformatted, 12 files left unchanged uv run ruff check --select ALL . --fix --unsafe-fixes --preview --show-fixes; uv run ruff format . --- docs/conf.py | 10 ++++--- src/django_docutils/__about__.py | 2 ++ src/django_docutils/_internal/types.py | 6 ++-- src/django_docutils/exc.py | 2 ++ src/django_docutils/lib/directives/code.py | 7 +++-- .../lib/directives/registry.py | 2 ++ src/django_docutils/lib/metadata/extract.py | 6 ++-- src/django_docutils/lib/metadata/process.py | 2 ++ .../lib/metadata/processors.py | 2 ++ .../lib/metadata/tests/test_extract.py | 7 ++++- .../lib/metadata/tests/test_process.py | 2 ++ src/django_docutils/lib/publisher.py | 28 +++++++++-------- src/django_docutils/lib/roles/common.py | 12 ++++---- src/django_docutils/lib/roles/email.py | 14 +++++---- src/django_docutils/lib/roles/file.py | 18 ++++++----- src/django_docutils/lib/roles/github.py | 14 +++++---- src/django_docutils/lib/roles/hackernews.py | 14 +++++---- src/django_docutils/lib/roles/kbd.py | 10 +++++-- src/django_docutils/lib/roles/leanpub.py | 14 +++++---- src/django_docutils/lib/roles/pypi.py | 14 +++++---- src/django_docutils/lib/roles/readthedocs.py | 14 +++++---- src/django_docutils/lib/roles/registry.py | 2 ++ src/django_docutils/lib/roles/twitter.py | 14 +++++---- src/django_docutils/lib/roles/types.py | 2 ++ src/django_docutils/lib/roles/url.py | 14 +++++---- src/django_docutils/lib/roles/wikipedia.py | 14 +++++---- src/django_docutils/lib/settings.py | 4 ++- src/django_docutils/lib/tests/test_utils.py | 2 ++ src/django_docutils/lib/tests/test_writers.py | 2 ++ src/django_docutils/lib/text.py | 2 ++ src/django_docutils/lib/transforms/code.py | 12 ++++---- src/django_docutils/lib/transforms/toc.py | 6 ++-- src/django_docutils/lib/types.py | 2 ++ src/django_docutils/lib/utils.py | 9 ++++-- src/django_docutils/lib/views.py | 26 +++++++++------- src/django_docutils/lib/writers.py | 14 +++++---- src/django_docutils/template.py | 14 +++++---- .../templatetags/django_docutils.py | 14 ++++----- src/django_docutils/views.py | 30 +++++++++++-------- tests/constants.py | 2 ++ tests/settings.py | 4 ++- tests/test_docutils_roles.py | 13 +++++--- tests/test_template.py | 7 +++-- tests/test_templatetag.py | 2 ++ 44 files changed, 267 insertions(+), 144 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 110a0435..beecec5f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,8 @@ """Sphinx configuration for Django Docutils.""" # flake8: noqa: E501 +from __future__ import annotations + import inspect import os import pathlib @@ -77,7 +79,7 @@ html_extra_path = ["manifest.json"] html_theme = "furo" html_theme_path: list[str] = [] -html_theme_options: dict[str, t.Union[str, list[dict[str, str]]]] = { +html_theme_options: dict[str, str | list[dict[str, str]]] = { "light_logo": "img/icons/logo.svg", "dark_logo": "img/icons/logo-dark.svg", "footer_icons": [ @@ -147,7 +149,7 @@ } -def linkcode_resolve(domain: str, info: dict[str, str]) -> t.Union[None, str]: +def linkcode_resolve(domain: str, info: dict[str, str]) -> None | str: """ Determine the URL corresponding to Python object. @@ -217,13 +219,13 @@ def linkcode_resolve(domain: str, info: dict[str, str]) -> t.Union[None, str]: ) -def remove_tabs_js(app: "Sphinx", exc: Exception) -> None: +def remove_tabs_js(app: Sphinx, exc: Exception) -> None: """Fix for sphinx-inline-tabs#18.""" if app.builder.format == "html" and not exc: tabs_js = pathlib.Path(app.builder.outdir) / "_static" / "tabs.js" tabs_js.unlink(missing_ok=True) -def setup(app: "Sphinx") -> None: +def setup(app: Sphinx) -> None: """Sphinx setup hook.""" app.connect("build-finished", remove_tabs_js) diff --git a/src/django_docutils/__about__.py b/src/django_docutils/__about__.py index d9ae4ccb..81f91859 100644 --- a/src/django_docutils/__about__.py +++ b/src/django_docutils/__about__.py @@ -1,5 +1,7 @@ """Metadata package for Django Docutils.""" +from __future__ import annotations + __title__ = "django-docutils" __package_name__ = "django_docutils" __description__ = "Docutils (a.k.a. reStructuredText, reST, RST) support for django." diff --git a/src/django_docutils/_internal/types.py b/src/django_docutils/_internal/types.py index bb9de1cf..7270cdc9 100644 --- a/src/django_docutils/_internal/types.py +++ b/src/django_docutils/_internal/types.py @@ -7,6 +7,8 @@ .. _typeshed's: https://github.com/python/typeshed/blob/5df8de7/stdlib/_typeshed/__init__.pyi#L115-L118 """ # E501 +from __future__ import annotations + from typing import TYPE_CHECKING, Union if TYPE_CHECKING: @@ -14,10 +16,10 @@ from typing_extensions import TypeAlias -StrPath: "TypeAlias" = Union[str, "PathLike[str]"] # stable +StrPath: TypeAlias = Union[str, "PathLike[str]"] # stable """:class:`os.PathLike` or :class:`str`""" -StrOrBytesPath: "TypeAlias" = Union[ +StrOrBytesPath: TypeAlias = Union[ str, bytes, "PathLike[str]", diff --git a/src/django_docutils/exc.py b/src/django_docutils/exc.py index 3ea311e6..438aa3ca 100644 --- a/src/django_docutils/exc.py +++ b/src/django_docutils/exc.py @@ -1,5 +1,7 @@ """Exceptions for Django Docutils.""" +from __future__ import annotations + class DjangoDocutilsException(Exception): """Base exception for Django Docutils package.""" diff --git a/src/django_docutils/lib/directives/code.py b/src/django_docutils/lib/directives/code.py index 5c319163..ce0a566c 100644 --- a/src/django_docutils/lib/directives/code.py +++ b/src/django_docutils/lib/directives/code.py @@ -36,9 +36,10 @@ :license: BSD, see LICENSE for details. """ +from __future__ import annotations + import re import typing as t -from collections.abc import Callable from docutils import nodes from docutils.parsers.rst import Directive, directives @@ -48,6 +49,8 @@ from pygments.lexers.special import TextLexer if t.TYPE_CHECKING: + from collections.abc import Callable + from pygments.formatter import Formatter @@ -72,7 +75,7 @@ def patch_bash_session_lexer() -> None: DEFAULT = HtmlFormatter(cssclass="highlight code-block", noclasses=INLINESTYLES) #: Add name -> formatter pairs for every variant you want to use -VARIANTS: dict[str, "Formatter[str]"] = { +VARIANTS: dict[str, Formatter[str]] = { # 'linenos': HtmlFormatter(noclasses=INLINESTYLES, linenos=True), } diff --git a/src/django_docutils/lib/directives/registry.py b/src/django_docutils/lib/directives/registry.py index 88badba7..fae1bad7 100644 --- a/src/django_docutils/lib/directives/registry.py +++ b/src/django_docutils/lib/directives/registry.py @@ -1,5 +1,7 @@ """Register douctils directives for django-docutils.""" +from __future__ import annotations + from django.utils.module_loading import import_string from docutils.parsers.rst import directives diff --git a/src/django_docutils/lib/metadata/extract.py b/src/django_docutils/lib/metadata/extract.py index 08174cc6..5331c733 100644 --- a/src/django_docutils/lib/metadata/extract.py +++ b/src/django_docutils/lib/metadata/extract.py @@ -1,13 +1,13 @@ """Title, Subtitle, and Metadata extraction of reStructuredText.""" -import typing as t +from __future__ import annotations from django.template.defaultfilters import truncatewords from django.utils.html import strip_tags from docutils import nodes -def extract_title(document: nodes.document) -> t.Optional[str]: +def extract_title(document: nodes.document) -> str | None: """Return the title of the document. Parameters @@ -77,7 +77,7 @@ def extract_metadata(document: nodes.document) -> dict[str, str]: return output -def extract_subtitle(document: nodes.document) -> t.Optional[str]: +def extract_subtitle(document: nodes.document) -> str | None: """Return the subtitle of the document.""" for node in document.traverse(nodes.PreBibliographic): # type:ignore if isinstance(node, nodes.subtitle): diff --git a/src/django_docutils/lib/metadata/process.py b/src/django_docutils/lib/metadata/process.py index f4d26b89..e48e3e94 100644 --- a/src/django_docutils/lib/metadata/process.py +++ b/src/django_docutils/lib/metadata/process.py @@ -30,6 +30,8 @@ def process_datetime(metadata): See *processors.py* for more examples. """ +from __future__ import annotations + from django.utils.module_loading import import_string from django_docutils.lib.settings import DJANGO_DOCUTILS_LIB_RST diff --git a/src/django_docutils/lib/metadata/processors.py b/src/django_docutils/lib/metadata/processors.py index 000829a1..5ce157a4 100644 --- a/src/django_docutils/lib/metadata/processors.py +++ b/src/django_docutils/lib/metadata/processors.py @@ -1,5 +1,7 @@ """Metadata processing for Django Docutils.""" +from __future__ import annotations + import datetime import typing as t diff --git a/src/django_docutils/lib/metadata/tests/test_extract.py b/src/django_docutils/lib/metadata/tests/test_extract.py index b144b37f..67ff5e27 100644 --- a/src/django_docutils/lib/metadata/tests/test_extract.py +++ b/src/django_docutils/lib/metadata/tests/test_extract.py @@ -1,6 +1,8 @@ """Test metadata and title extraction from reStructuredText.""" -import pathlib +from __future__ import annotations + +from typing import TYPE_CHECKING from django.utils.encoding import force_bytes from docutils.core import publish_doctree @@ -12,6 +14,9 @@ ) from django_docutils.lib.settings import DJANGO_DOCUTILS_LIB_RST +if TYPE_CHECKING: + import pathlib + def test_extract_title() -> None: """Assert title extraction from reStructuredText.""" diff --git a/src/django_docutils/lib/metadata/tests/test_process.py b/src/django_docutils/lib/metadata/tests/test_process.py index 1b5b30f3..e9d478aa 100644 --- a/src/django_docutils/lib/metadata/tests/test_process.py +++ b/src/django_docutils/lib/metadata/tests/test_process.py @@ -1,5 +1,7 @@ """Test docutils metadata (docinfo) processing in Django Docutils.""" +from __future__ import annotations + import datetime from django.utils.encoding import force_bytes diff --git a/src/django_docutils/lib/publisher.py b/src/django_docutils/lib/publisher.py index bee1dca9..91001f22 100644 --- a/src/django_docutils/lib/publisher.py +++ b/src/django_docutils/lib/publisher.py @@ -1,5 +1,7 @@ """Docutils Publisher fors for Django Docutils.""" +from __future__ import annotations + import typing as t from django.utils.encoding import force_bytes, force_str @@ -7,7 +9,6 @@ from docutils import io, nodes from docutils.core import Publisher, publish_doctree as docutils_publish_doctree from docutils.readers.doctree import Reader -from docutils.writers.html5_polyglot import Writer from .directives.registry import register_django_docutils_directives from .roles.registry import register_django_docutils_roles @@ -17,19 +18,20 @@ if t.TYPE_CHECKING: from docutils import SettingsSpec + from docutils.writers.html5_polyglot import Writer docutils_settings = DJANGO_DOCUTILS_LIB_RST.get("docutils", {}) def publish_parts_from_doctree( document: nodes.document, - destination_path: t.Optional[str] = None, - writer: t.Optional[Writer] = None, + destination_path: str | None = None, + writer: Writer | None = None, writer_name: str = "pseudoxml", - settings: t.Optional[t.Any] = None, - settings_spec: "t.Optional[SettingsSpec]" = None, - settings_overrides: t.Optional[t.Any] = None, - config_section: t.Optional[str] = None, + settings: t.Any | None = None, + settings_spec: SettingsSpec | None = None, + settings_overrides: t.Any | None = None, + config_section: str | None = None, enable_exit_status: bool = False, ) -> dict[str, str]: """Render docutils doctree into docutils parts.""" @@ -56,8 +58,8 @@ def publish_parts_from_doctree( def publish_toc_from_doctree( doctree: nodes.document, - writer: t.Optional[Writer] = None, -) -> t.Optional[str]: + writer: Writer | None = None, +) -> str | None: """Publish table of contents from docutils doctree.""" if not writer: writer = DjangoDocutilsWriter() @@ -98,7 +100,7 @@ def publish_toc_from_doctree( def publish_doctree( - source: t.Union[str, bytes], + source: str | bytes, settings_overrides: t.Any = docutils_settings, ) -> nodes.document: """Split off ability to get doctree (a.k.a. document). @@ -139,8 +141,8 @@ class PublishHtmlDocTreeKwargs(TypedDict): def publish_html_from_source( source: str, - **kwargs: "Unpack[PublishHtmlDocTreeKwargs]", -) -> t.Optional[str]: + **kwargs: Unpack[PublishHtmlDocTreeKwargs], +) -> str | None: """Return HTML from reStructuredText source string.""" doctree = publish_doctree(source) return publish_html_from_doctree(doctree, **kwargs) @@ -150,7 +152,7 @@ def publish_html_from_doctree( doctree: nodes.document, show_title: bool = True, toc_only: bool = False, -) -> t.Optional[str]: +) -> str | None: """Return HTML from reStructuredText document (doctree). Parameters diff --git a/src/django_docutils/lib/roles/common.py b/src/django_docutils/lib/roles/common.py index a9572359..fba84e34 100644 --- a/src/django_docutils/lib/roles/common.py +++ b/src/django_docutils/lib/roles/common.py @@ -1,5 +1,7 @@ """Core parts for Django Docutils roles.""" +from __future__ import annotations + import typing as t from docutils import nodes, utils @@ -13,9 +15,9 @@ def generic_url_role( name: str, text: str, - url_handler_fn: "UrlHandlerFn", - innernodeclass: type[t.Union[nodes.Text, nodes.TextElement]] = nodes.Text, -) -> "RoleFnReturnValue": + url_handler_fn: UrlHandlerFn, + innernodeclass: type[nodes.Text | nodes.TextElement] = nodes.Text, +) -> RoleFnReturnValue: """Docutils Role for Django Docutils. This generic role also handles explicit titles (``:role:`yata yata ```) @@ -78,8 +80,8 @@ def url_handler(target): def generic_remote_url_role( name: str, text: str, - url_handler_fn: "RemoteUrlHandlerFn", - innernodeclass: type[t.Union[nodes.Text, nodes.TextElement]] = nodes.Text, + url_handler_fn: RemoteUrlHandlerFn, + innernodeclass: type[nodes.Text | nodes.TextElement] = nodes.Text, ) -> tuple[list[nodes.reference], list[t.Any]]: """Docutils Role that can call an external data source for title and URL. diff --git a/src/django_docutils/lib/roles/email.py b/src/django_docutils/lib/roles/email.py index f34a5e59..b0b8911a 100644 --- a/src/django_docutils/lib/roles/email.py +++ b/src/django_docutils/lib/roles/email.py @@ -1,11 +1,15 @@ """Email role for docutils.""" -import typing as t +from __future__ import annotations -from docutils.parsers.rst.states import Inliner +import typing as t from .common import generic_url_role -from .types import RoleFnReturnValue + +if t.TYPE_CHECKING: + from docutils.parsers.rst.states import Inliner + + from .types import RoleFnReturnValue def email_role( @@ -14,8 +18,8 @@ def email_role( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, - content: t.Optional[str] = None, + options: dict[str, t.Any] | None = None, + content: str | None = None, ) -> RoleFnReturnValue: """Role for linking to email articles. diff --git a/src/django_docutils/lib/roles/file.py b/src/django_docutils/lib/roles/file.py index 0fc410c7..1865203c 100644 --- a/src/django_docutils/lib/roles/file.py +++ b/src/django_docutils/lib/roles/file.py @@ -1,10 +1,14 @@ """File role for Docutils.""" +from __future__ import annotations + import os import typing as t from docutils import nodes, utils -from docutils.parsers.rst.states import Inliner + +if t.TYPE_CHECKING: + from docutils.parsers.rst.states import Inliner def file_role( @@ -13,8 +17,8 @@ def file_role( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, - content: t.Optional[str] = None, + options: dict[str, t.Any] | None = None, + content: str | None = None, ) -> tuple[list[nodes.emphasis], list[t.Any]]: """Role for files. @@ -66,8 +70,8 @@ def manifest_role( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, - content: t.Optional[str] = None, + options: dict[str, t.Any] | None = None, + content: str | None = None, ) -> tuple[list[nodes.emphasis], list[t.Any]]: """Role for manifests (package.json, file outputs). @@ -103,8 +107,8 @@ def exe_role( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, - content: t.Optional[str] = None, + options: dict[str, t.Any] | None = None, + content: str | None = None, ) -> tuple[list[nodes.emphasis], list[t.Any]]: """Role for executables. diff --git a/src/django_docutils/lib/roles/github.py b/src/django_docutils/lib/roles/github.py index 87ab3333..fb52c6dc 100644 --- a/src/django_docutils/lib/roles/github.py +++ b/src/django_docutils/lib/roles/github.py @@ -1,11 +1,15 @@ """GitHub role for Docutils.""" -import typing as t +from __future__ import annotations -from docutils.parsers.rst.states import Inliner +import typing as t from .common import generic_url_role -from .types import RoleFnReturnValue + +if t.TYPE_CHECKING: + from docutils.parsers.rst.states import Inliner + + from .types import RoleFnReturnValue def github_role( @@ -14,8 +18,8 @@ def github_role( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, - content: t.Optional[str] = None, + options: dict[str, t.Any] | None = None, + content: str | None = None, ) -> RoleFnReturnValue: """Role for linking to GitHub repos and issues. diff --git a/src/django_docutils/lib/roles/hackernews.py b/src/django_docutils/lib/roles/hackernews.py index fe54bb47..7b0affc1 100644 --- a/src/django_docutils/lib/roles/hackernews.py +++ b/src/django_docutils/lib/roles/hackernews.py @@ -1,12 +1,16 @@ """HN (HackerNews) role for Docutils.""" +from __future__ import annotations + import typing as t from urllib.parse import quote -from docutils.parsers.rst.states import Inliner - from .common import generic_url_role -from .types import RoleFnReturnValue + +if t.TYPE_CHECKING: + from docutils.parsers.rst.states import Inliner + + from .types import RoleFnReturnValue def hackernews_role( @@ -15,8 +19,8 @@ def hackernews_role( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, - content: t.Optional[str] = None, + options: dict[str, t.Any] | None = None, + content: str | None = None, ) -> RoleFnReturnValue: """Role for linking to hackernews articles. diff --git a/src/django_docutils/lib/roles/kbd.py b/src/django_docutils/lib/roles/kbd.py index 06fe1356..70e2d29a 100644 --- a/src/django_docutils/lib/roles/kbd.py +++ b/src/django_docutils/lib/roles/kbd.py @@ -1,9 +1,13 @@ """ (Keyboard Input Element) role for Docutils.""" +from __future__ import annotations + import typing as t from docutils import nodes -from docutils.parsers.rst.states import Inliner + +if t.TYPE_CHECKING: + from docutils.parsers.rst.states import Inliner def kbd_role( @@ -12,8 +16,8 @@ def kbd_role( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, - content: t.Optional[str] = None, + options: dict[str, t.Any] | None = None, + content: str | None = None, ) -> tuple[list[nodes.raw], list[t.Any]]: """Role for ````, the keyboard input element. diff --git a/src/django_docutils/lib/roles/leanpub.py b/src/django_docutils/lib/roles/leanpub.py index b1dc40de..feaabd9d 100644 --- a/src/django_docutils/lib/roles/leanpub.py +++ b/src/django_docutils/lib/roles/leanpub.py @@ -1,11 +1,15 @@ """Leanpub role for Docutils.""" -import typing as t +from __future__ import annotations -from docutils.parsers.rst.states import Inliner +import typing as t from .common import generic_url_role -from .types import RoleFnReturnValue + +if t.TYPE_CHECKING: + from docutils.parsers.rst.states import Inliner + + from .types import RoleFnReturnValue def leanpub_role( @@ -14,8 +18,8 @@ def leanpub_role( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, - content: t.Optional[str] = None, + options: dict[str, t.Any] | None = None, + content: str | None = None, ) -> RoleFnReturnValue: """Role for linking to leanpub page. diff --git a/src/django_docutils/lib/roles/pypi.py b/src/django_docutils/lib/roles/pypi.py index 4d46b810..4afc52ef 100644 --- a/src/django_docutils/lib/roles/pypi.py +++ b/src/django_docutils/lib/roles/pypi.py @@ -1,11 +1,15 @@ """PyPI (Python Package Index) role for docutils.""" -import typing as t +from __future__ import annotations -from docutils.parsers.rst.states import Inliner +import typing as t from .common import generic_url_role -from .types import RoleFnReturnValue + +if t.TYPE_CHECKING: + from docutils.parsers.rst.states import Inliner + + from .types import RoleFnReturnValue def pypi_role( @@ -14,8 +18,8 @@ def pypi_role( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, - content: t.Optional[str] = None, + options: dict[str, t.Any] | None = None, + content: str | None = None, ) -> RoleFnReturnValue: """Role for linking to PyPI (Python Package Index) page. diff --git a/src/django_docutils/lib/roles/readthedocs.py b/src/django_docutils/lib/roles/readthedocs.py index f65f13b9..f5f85bda 100644 --- a/src/django_docutils/lib/roles/readthedocs.py +++ b/src/django_docutils/lib/roles/readthedocs.py @@ -1,11 +1,15 @@ """ReadTheDocs role for Docutils.""" -import typing as t +from __future__ import annotations -from docutils.parsers.rst.states import Inliner +import typing as t from .common import generic_url_role -from .types import RoleFnReturnValue + +if t.TYPE_CHECKING: + from docutils.parsers.rst.states import Inliner + + from .types import RoleFnReturnValue def readthedocs_role( @@ -14,8 +18,8 @@ def readthedocs_role( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, - content: t.Optional[str] = None, + options: dict[str, t.Any] | None = None, + content: str | None = None, ) -> RoleFnReturnValue: """Role for linking to readthedocs.org page. diff --git a/src/django_docutils/lib/roles/registry.py b/src/django_docutils/lib/roles/registry.py index e22ea34e..bc971f6e 100644 --- a/src/django_docutils/lib/roles/registry.py +++ b/src/django_docutils/lib/roles/registry.py @@ -1,5 +1,7 @@ """Register docutils roles for django-docutils.""" +from __future__ import annotations + import inspect import typing as t diff --git a/src/django_docutils/lib/roles/twitter.py b/src/django_docutils/lib/roles/twitter.py index 4134093d..e01b1436 100644 --- a/src/django_docutils/lib/roles/twitter.py +++ b/src/django_docutils/lib/roles/twitter.py @@ -1,11 +1,15 @@ """Twitter role for docutils.""" -import typing as t +from __future__ import annotations -from docutils.parsers.rst.states import Inliner +import typing as t from .common import generic_url_role -from .types import RoleFnReturnValue + +if t.TYPE_CHECKING: + from docutils.parsers.rst.states import Inliner + + from .types import RoleFnReturnValue def twitter_role( @@ -14,8 +18,8 @@ def twitter_role( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, - content: t.Optional[str] = None, + options: dict[str, t.Any] | None = None, + content: str | None = None, ) -> RoleFnReturnValue: """Role for linking to twitter articles. diff --git a/src/django_docutils/lib/roles/types.py b/src/django_docutils/lib/roles/types.py index 8a7805ac..1e08aa41 100644 --- a/src/django_docutils/lib/roles/types.py +++ b/src/django_docutils/lib/roles/types.py @@ -1,5 +1,7 @@ """Typings for Django Docutils roles for Docutils.""" +from __future__ import annotations + import typing as t from docutils import nodes diff --git a/src/django_docutils/lib/roles/url.py b/src/django_docutils/lib/roles/url.py index d7f24a77..f7128720 100644 --- a/src/django_docutils/lib/roles/url.py +++ b/src/django_docutils/lib/roles/url.py @@ -1,11 +1,15 @@ """URL Role for docutils.""" -import typing as t +from __future__ import annotations -from docutils.parsers.rst.states import Inliner +import typing as t from .common import generic_url_role -from .types import RoleFnReturnValue + +if t.TYPE_CHECKING: + from docutils.parsers.rst.states import Inliner + + from .types import RoleFnReturnValue def url_role( @@ -14,8 +18,8 @@ def url_role( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, - content: t.Optional[str] = None, + options: dict[str, t.Any] | None = None, + content: str | None = None, ) -> RoleFnReturnValue: """Role for linking to url articles. diff --git a/src/django_docutils/lib/roles/wikipedia.py b/src/django_docutils/lib/roles/wikipedia.py index 8ba570db..db88279f 100644 --- a/src/django_docutils/lib/roles/wikipedia.py +++ b/src/django_docutils/lib/roles/wikipedia.py @@ -1,12 +1,16 @@ """Wikipedia role for Docutils.""" +from __future__ import annotations + import typing as t from urllib.parse import quote -from docutils.parsers.rst.states import Inliner - from .common import generic_url_role -from .types import RoleFnReturnValue + +if t.TYPE_CHECKING: + from docutils.parsers.rst.states import Inliner + + from .types import RoleFnReturnValue def wikipedia_role( @@ -15,8 +19,8 @@ def wikipedia_role( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, - content: t.Optional[str] = None, + options: dict[str, t.Any] | None = None, + content: str | None = None, ) -> RoleFnReturnValue: """Role for linking to Wikipedia articles. diff --git a/src/django_docutils/lib/settings.py b/src/django_docutils/lib/settings.py index 4174a4b3..95dba64d 100644 --- a/src/django_docutils/lib/settings.py +++ b/src/django_docutils/lib/settings.py @@ -1,5 +1,7 @@ """Settings objects and type-mapping for Django Docutils library package.""" +from __future__ import annotations + import typing as t from django.conf import settings @@ -19,7 +21,7 @@ getattr(settings, "DJANGO_DOCUTILS_LIB_TEXT", {"uncapitalized_word_filters": []}), ) -DJANGO_DOCUTILS_ANONYMOUS_USER_NAME: t.Optional[str] = "AnonymousCoward" +DJANGO_DOCUTILS_ANONYMOUS_USER_NAME: str | None = "AnonymousCoward" def reload_settings( diff --git a/src/django_docutils/lib/tests/test_utils.py b/src/django_docutils/lib/tests/test_utils.py index e249dfc5..703c34a2 100644 --- a/src/django_docutils/lib/tests/test_utils.py +++ b/src/django_docutils/lib/tests/test_utils.py @@ -1,5 +1,7 @@ """Tests for Django Docutil utilities.""" +from __future__ import annotations + from django_docutils.lib.utils import chop_after_docinfo, chop_after_title diff --git a/src/django_docutils/lib/tests/test_writers.py b/src/django_docutils/lib/tests/test_writers.py index d58aa939..c2c3f2d0 100644 --- a/src/django_docutils/lib/tests/test_writers.py +++ b/src/django_docutils/lib/tests/test_writers.py @@ -1,5 +1,7 @@ """Tests for Django Docutils Writers.""" +from __future__ import annotations + from django.utils.encoding import force_bytes from docutils.core import publish_doctree from docutils.writers.html5_polyglot import Writer diff --git a/src/django_docutils/lib/text.py b/src/django_docutils/lib/text.py index 954b5328..ec665133 100644 --- a/src/django_docutils/lib/text.py +++ b/src/django_docutils/lib/text.py @@ -1,5 +1,7 @@ """Text related utilities for Django Docutils.""" +from __future__ import annotations + import re from django.conf import settings diff --git a/src/django_docutils/lib/transforms/code.py b/src/django_docutils/lib/transforms/code.py index 47189f29..3cc1bfe6 100644 --- a/src/django_docutils/lib/transforms/code.py +++ b/src/django_docutils/lib/transforms/code.py @@ -1,5 +1,7 @@ """Code related formatter and transformers.""" +from __future__ import annotations + import re import typing as t @@ -21,7 +23,7 @@ class InlineHtmlFormatter(HtmlFormatter): # type:ignore """HTMLFormatter for inline codeblocks.""" - def format_unencoded(self, tokensource: "TokenStream", outfile: t.Any) -> None: + def format_unencoded(self, tokensource: TokenStream, outfile: t.Any) -> None: r"""Trim inline element of space and newlines. 1. Trailing newline: Final token generated returns ``(Token.Other, '\n')`` @@ -37,7 +39,7 @@ def format_unencoded(self, tokensource: "TokenStream", outfile: t.Any) -> None: the ``InlineHtmlFormatter`` class. """ - def filter_trailing_newline(source: "TokenStream") -> "TokenStream": + def filter_trailing_newline(source: TokenStream) -> TokenStream: tokens = list(source) # filter out the trailing newline token @@ -52,8 +54,8 @@ def filter_trailing_newline(source: "TokenStream") -> "TokenStream": def _wrap_div( self, - inner: "TokenStream", - ) -> t.Union["TokenGenerator", "TokenStream"]: + inner: TokenStream, + ) -> TokenGenerator | TokenStream: styles = [] if ( self.noclasses @@ -77,7 +79,7 @@ def _wrap_div( yield from inner yield 0, "\n" - def _wrap_pre(self, inner: "TokenStream") -> "TokenStream": + def _wrap_pre(self, inner: TokenStream) -> TokenStream: yield from inner diff --git a/src/django_docutils/lib/transforms/toc.py b/src/django_docutils/lib/transforms/toc.py index 11843343..8af47081 100644 --- a/src/django_docutils/lib/transforms/toc.py +++ b/src/django_docutils/lib/transforms/toc.py @@ -1,5 +1,7 @@ """Django docutils table of contents helpers.""" +from __future__ import annotations + import sys import typing as t @@ -16,13 +18,13 @@ class Contents(parts.Contents): - Removed extra nodes.paragraph wrapping of list_item's. """ - startnode: t.Optional[nodes.Node] + startnode: nodes.Node | None def build_contents( self, node: nodes.Node, level: int = 0, - ) -> t.Union[nodes.bullet_list, list[t.Any]]: + ) -> nodes.bullet_list | list[t.Any]: """Build nested bullet list from doctree content.""" assert isinstance(node, nodes.Element) level += 1 diff --git a/src/django_docutils/lib/types.py b/src/django_docutils/lib/types.py index 9fd8247f..dfa15fa7 100644 --- a/src/django_docutils/lib/types.py +++ b/src/django_docutils/lib/types.py @@ -1,5 +1,7 @@ """Typings for Django Docutils settings for django.""" +from __future__ import annotations + from typing_extensions import NotRequired, TypedDict diff --git a/src/django_docutils/lib/utils.py b/src/django_docutils/lib/utils.py index 7d6e9af4..d98244b8 100644 --- a/src/django_docutils/lib/utils.py +++ b/src/django_docutils/lib/utils.py @@ -5,15 +5,20 @@ - explicit_title_re, ws_re, set_role_source_info, split_explicit_title """ +from __future__ import annotations + import re -from collections.abc import Generator +from typing import TYPE_CHECKING from docutils import nodes +if TYPE_CHECKING: + from collections.abc import Generator + # \x00 means the "<" was backslash-escaped (from sphinx) explicit_title_re = re.compile(r"^(.+?)\s*(?$", re.DOTALL) -ws_re: "re.Pattern[str]" = re.compile(r"\s+") +ws_re: re.Pattern[str] = re.compile(r"\s+") def split_explicit_title(text: str) -> tuple[bool, str, str]: diff --git a/src/django_docutils/lib/views.py b/src/django_docutils/lib/views.py index 2603b4dc..db54eb1d 100644 --- a/src/django_docutils/lib/views.py +++ b/src/django_docutils/lib/views.py @@ -1,14 +1,12 @@ """Django view machinery for rendering docutils content as HTML.""" +from __future__ import annotations + import pathlib import typing as t -from django.http import HttpRequest from django.utils.functional import cached_property from django.views.generic.base import ContextMixin, TemplateView -from docutils import nodes - -from django_docutils._internal.types import StrPath from .publisher import ( publish_doctree, @@ -17,6 +15,12 @@ ) from .text import smart_title +if t.TYPE_CHECKING: + from django.http import HttpRequest + from docutils import nodes + + from django_docutils._internal.types import StrPath + class TitleMixin(ContextMixin): """ContextMixin that capitalizes title and subtitle.""" @@ -51,12 +55,12 @@ class RSTMixin: request: HttpRequest @cached_property - def raw_content(self) -> t.Optional[str]: + def raw_content(self) -> str | None: """Raw reStructuredText content.""" raise NotImplementedError @cached_property - def doctree(self) -> t.Optional[nodes.document]: + def doctree(self) -> nodes.document | None: """Return docutils doctree of RST content (pre-HTML).""" if self.raw_content is None: return None @@ -64,7 +68,7 @@ def doctree(self) -> t.Optional[nodes.document]: return publish_doctree(self.raw_content) @cached_property - def sidebar(self, **kwargs: object) -> t.Optional[str]: + def sidebar(self, **kwargs: object) -> str | None: """Return table of contents sidebar of RST content as HTML.""" if self.doctree is None: return None @@ -72,7 +76,7 @@ def sidebar(self, **kwargs: object) -> t.Optional[str]: return publish_toc_from_doctree(self.doctree) @cached_property - def content(self) -> t.Optional[str]: + def content(self) -> str | None: """Return reStructuredText content as HTML.""" if self.doctree is None: return None @@ -110,7 +114,7 @@ class RSTRawView(TemplateTitleView): """ template_name = "rst/raw.html" - file_path: t.Optional[StrPath] = None + file_path: StrPath | None = None title = None def get_context_data(self, **kwargs: object) -> dict[str, t.Any]: @@ -128,11 +132,11 @@ class RSTView(RSTRawView, RSTMixin): """RestructuredText Django View.""" template_name = "rst/base.html" - file_path: t.Optional[StrPath] = None + file_path: StrPath | None = None title = None @cached_property - def raw_content(self) -> t.Optional[str]: + def raw_content(self) -> str | None: """Raw reStructuredText data.""" if self.file_path is None: return None diff --git a/src/django_docutils/lib/writers.py b/src/django_docutils/lib/writers.py index e79a12a9..d35437de 100644 --- a/src/django_docutils/lib/writers.py +++ b/src/django_docutils/lib/writers.py @@ -1,23 +1,27 @@ """Docutils writers for Django Docutils, designed for cleaner output.""" +from __future__ import annotations + import typing as t from django.conf import settings from django.utils.module_loading import import_string from docutils import nodes -from docutils.transforms import Transform from docutils.writers.html5_polyglot import HTMLTranslator, Writer from .settings import DJANGO_DOCUTILS_LIB_RST +if t.TYPE_CHECKING: + from docutils.transforms import Transform + class ParentNodeClassTuple(t.NamedTuple): """Typing for parent node accepting custom arguments.""" - parent_node_type: type[t.Union[nodes.Node, nodes.Body]] + parent_node_type: type[nodes.Node | nodes.Body] args: list[str] kwargs: dict[str, str] - close_tag: t.Optional[str] + close_tag: str | None class DjangoDocutilsHTMLTranslator(HTMLTranslator): @@ -94,7 +98,7 @@ def visit_title(self, node: nodes.Element) -> None: - s/with-subtitle/subtitle for bulma css """ - close_tag: t.Optional[str] = "

\n" + close_tag: str | None = "

\n" # add backlinks to refid (toc header backlinks) # This assures headers link to themselves, so users can copy a link @@ -159,7 +163,7 @@ def visit_title(self, node: nodes.Element) -> None: def _visit_section_title( self, node: nodes.Element, - close_tag: t.Optional[str], + close_tag: str | None, ) -> str: """Our special sauce for section titles. diff --git a/src/django_docutils/template.py b/src/django_docutils/template.py index 2315517f..be25d930 100644 --- a/src/django_docutils/template.py +++ b/src/django_docutils/template.py @@ -1,9 +1,10 @@ """Django template engine for Docutils.""" +from __future__ import annotations + import typing as t from django.conf import settings -from django.http.request import HttpRequest from django.template.backends.base import BaseEngine from django.template.backends.utils import csrf_input_lazy, csrf_token_lazy from django.template.engine import Engine @@ -14,6 +15,7 @@ from django_docutils.lib.directives.code import register_pygments_directive if t.TYPE_CHECKING: + from django.http.request import HttpRequest from django.template.backends.base import _EngineTemplate from django.template.base import Context from django.utils.safestring import SafeString @@ -31,11 +33,11 @@ def __init__(self, params: dict[str, t.Any]) -> None: super().__init__(params) self.engine = Engine(self.dirs, self.app_dirs, **self.options) - def from_string(self, template_code: str) -> "DocutilsTemplate": + def from_string(self, template_code: str) -> DocutilsTemplate: """Return DocutilsTemplate from string.""" return DocutilsTemplate(template_code, self.options) - def get_template(self, template_name: str) -> "_EngineTemplate": + def get_template(self, template_name: str) -> _EngineTemplate: """Return template from template_name.""" for template_file in self.iter_template_filenames(template_name): try: @@ -57,9 +59,9 @@ def __init__(self, source: str, options: dict[str, t.Any]) -> None: def render( self, - context: t.Union["Context", dict[str, t.Any], None] = None, - request: t.Optional[HttpRequest] = None, - ) -> "SafeString": + context: Context | dict[str, t.Any] | None = None, + request: HttpRequest | None = None, + ) -> SafeString: """Render DocutilsTemplate to string.""" context = self.options if request is not None: diff --git a/src/django_docutils/templatetags/django_docutils.py b/src/django_docutils/templatetags/django_docutils.py index 54cf6702..e929f2c4 100644 --- a/src/django_docutils/templatetags/django_docutils.py +++ b/src/django_docutils/templatetags/django_docutils.py @@ -1,6 +1,6 @@ """Django template tag and filter for docutils (rendering reStructuredText as HTML).""" -import typing as t +from __future__ import annotations from django import template from django.template.base import FilterExpression, Node, Parser, Token, kwarg_re @@ -19,17 +19,17 @@ class ReStructuredTextNode(Node): def __init__( self, - content: t.Union[FilterExpression, str], - args: t.Optional[list[FilterExpression]] = None, - kwargs: t.Optional[dict[str, FilterExpression]] = None, - asvar: t.Optional[str] = None, + content: FilterExpression | str, + args: list[FilterExpression] | None = None, + kwargs: dict[str, FilterExpression] | None = None, + asvar: str | None = None, ) -> None: self.content = content self.args = args if args is not None else [] self.kwargs = kwargs if kwargs is not None else {} self.asvar = asvar - def render(self, context: t.Optional[Context] = None) -> str: + def render(self, context: Context | None = None) -> str: """Render Node as string.""" if context is None: context = Context() @@ -105,7 +105,7 @@ def rst(parser: Parser, token: Token) -> ReStructuredTextNode: kwargs = {} asvar = None - content: t.Optional[t.Union[FilterExpression, SafeString]] = None + content: FilterExpression | SafeString | None = None if len(bits) >= 2 and bits[1] == "content": content = parser.compile_filter(bits[1]) diff --git a/src/django_docutils/views.py b/src/django_docutils/views.py index f7cec8d2..ac76de57 100644 --- a/src/django_docutils/views.py +++ b/src/django_docutils/views.py @@ -1,14 +1,18 @@ """Django-docutils class-based view for django (and its' parts).""" +from __future__ import annotations + import typing as t from django.core.exceptions import ImproperlyConfigured -from django.http.request import HttpRequest -from django.http.response import HttpResponse from django.template.loader import select_template from django.template.response import TemplateResponse from django.views.generic.base import TemplateView +if t.TYPE_CHECKING: + from django.http.request import HttpRequest + from django.http.response import HttpResponse + class DocutilsResponse(TemplateResponse): """Docutils TemplateResponse.""" @@ -20,11 +24,11 @@ def __init__( request: HttpRequest, template: list[str], rst: list[str], - context: t.Optional[dict[str, t.Any]] = None, - content_type: t.Optional[str] = None, - status: t.Optional[int] = None, - charset: t.Optional[str] = None, - using: t.Optional[str] = None, + context: dict[str, t.Any] | None = None, + content_type: str | None = None, + status: int | None = None, + charset: str | None = None, + using: str | None = None, ) -> None: self.rst_name = rst super().__init__( @@ -69,15 +73,15 @@ class DocutilsView(TemplateView): """Django-docutils view, renders reStructuredText to HTML via rst_name.""" response_class = DocutilsResponse - rst_name: t.Optional[str] = None + rst_name: str | None = None def render_to_response( self, - context: t.Optional[dict[str, t.Any]] = None, - content_type: t.Optional[str] = None, - status: t.Optional[int] = None, - charset: t.Optional[str] = None, - using: t.Optional[str] = None, + context: dict[str, t.Any] | None = None, + content_type: str | None = None, + status: int | None = None, + charset: str | None = None, + using: str | None = None, **response_kwargs: object, ) -> HttpResponse: """Override to pay in rst content.""" diff --git a/tests/constants.py b/tests/constants.py index c979b1fb..880d83d1 100644 --- a/tests/constants.py +++ b/tests/constants.py @@ -1,5 +1,7 @@ """Constants for Django Docutils test suite.""" +from __future__ import annotations + DEFAULT_RST = r""" hey --- diff --git a/tests/settings.py b/tests/settings.py index 2d1337e0..cf3971db 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -1,5 +1,7 @@ """django-docutils test settings module for django.""" +from __future__ import annotations + import pathlib import typing as t @@ -37,7 +39,7 @@ }, ] DJANGO_DOCUTILS_ANONYMOUS_USER_NAME = "AnonymousCoward" -DJANGO_DOCUTILS_LIB_RST: "DjangoDocutilsLibRSTSettings" = { +DJANGO_DOCUTILS_LIB_RST: DjangoDocutilsLibRSTSettings = { "metadata_processors": [ "django_docutils.lib.metadata.processors.process_datetime", "django_docutils.lib.metadata.processors.process_anonymous_user", diff --git a/tests/test_docutils_roles.py b/tests/test_docutils_roles.py index 156afca3..7fb4cfc4 100644 --- a/tests/test_docutils_roles.py +++ b/tests/test_docutils_roles.py @@ -1,19 +1,24 @@ # ruff: noqa: E501 """Tests for docutils roles.""" +from __future__ import annotations + import typing as t -from collections.abc import Sequence import pytest from django.template import Context, Template -from docutils import nodes -from docutils.parsers.rst.states import Inliner from django_docutils.lib.roles.registry import ( register_django_docutils_roles, register_role_mapping, ) +if t.TYPE_CHECKING: + from collections.abc import Sequence + + from docutils import nodes + from docutils.parsers.rst.states import Inliner + MAIN_TPL = """
{content} @@ -95,7 +100,7 @@ def __call__( text: str, lineno: int, inliner: Inliner, - options: t.Optional[dict[str, t.Any]] = None, + options: dict[str, t.Any] | None = None, content: Sequence[str] = (), ) -> tuple[list[nodes.Node], list[t.Any]]: """Return example class-based role.""" diff --git a/tests/test_template.py b/tests/test_template.py index 97613f4e..34863804 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -1,6 +1,7 @@ """Tests for DocutilsView template view.""" -import pathlib +from __future__ import annotations + import typing as t from django_docutils.views import DocutilsView @@ -8,10 +9,12 @@ from .constants import DEFAULT_RST if t.TYPE_CHECKING: + import pathlib + from django.test import RequestFactory -def test_view(settings: t.Any, tmp_path: pathlib.Path, rf: "RequestFactory") -> None: +def test_view(settings: t.Any, tmp_path: pathlib.Path, rf: RequestFactory) -> None: """Assert DocutilsView renders HTML from reStructuredText.""" request = rf.get("/") template_dir = tmp_path / "templates" diff --git a/tests/test_templatetag.py b/tests/test_templatetag.py index a5d04ca3..a8055037 100644 --- a/tests/test_templatetag.py +++ b/tests/test_templatetag.py @@ -1,5 +1,7 @@ """Tests for rst template filter and tags.""" +from __future__ import annotations + import typing as t import pytest