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