diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e842f87..4994966 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,29 +5,21 @@ exclude: ^tests/.*\.md|tests/.*\.rst|tests/.*\.xml|docs/apidocs/.* repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - - repo: https://github.com/pycqa/isort - rev: 5.12.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.1.6 hooks: - - id: isort - - - repo: https://github.com/psf/black - rev: 23.1.0 - hooks: - - id: black - - - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.249 - hooks: - - id: ruff + - id: ruff + args: [--fix] + - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.0.1 + rev: v1.7.1 hooks: - id: mypy args: [--config-file=pyproject.toml] diff --git a/docs/conf.py b/docs/conf.py index f9960d8..f010f74 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -95,12 +95,11 @@ import typing as t # noqa: E402 +from autodoc2.config import CONFIG_PREFIX, Config, PackageConfig # noqa: E402 from docutils import nodes # noqa: E402 from sphinx.application import Sphinx # noqa: E402 from sphinx.util.docutils import SphinxDirective # noqa: E402 -from autodoc2.config import CONFIG_PREFIX, Config, PackageConfig # noqa: E402 - def setup(app: Sphinx) -> None: app.add_object_type( diff --git a/pyproject.toml b/pyproject.toml index 312d040..aab6dff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,19 +44,17 @@ docs = [ [project.scripts] autodoc2 = "autodoc2.cli:app_main" -[tool.isort] -profile = "black" -force_sort_within_sections = true - [tool.ruff] -line-length = 110 -extend-select = ["B0", "C4", "ICN", "ISC", "N", "RUF", "SIM", "T20"] +extend-select = ["B0", "C4", "I", "ICN", "ISC", "N", "RUF", "SIM", "T20", "UP"] [tool.ruff.per-file-ignores] # ignore: Do not perform function call `typer.Option` in argument defaults "src/autodoc2/cli.py" = ["B008"] "tests/test_analyse_module.py" = ["E501"] +[tool.ruff.lint.isort] +force-sort-within-sections = true + [tool.mypy] show_error_codes = true strict = true diff --git a/src/autodoc2/analysis.py b/src/autodoc2/analysis.py index d822c68..9388b9a 100644 --- a/src/autodoc2/analysis.py +++ b/src/autodoc2/analysis.py @@ -287,9 +287,9 @@ def yield_class_def(node: nodes.ClassDef, state: State) -> t.Iterable[ItemData]: new_state = state.copy(name_stack=[*state.name_stack, node.name]) - overridden: t.Set[str] = set() # a list of methods overridden by class inheritance + overridden: set[str] = set() # a list of methods overridden by class inheritance for base in itertools.chain(iter((node,)), node.ancestors()): - seen: t.Set[str] = set() + seen: set[str] = set() if base.qname() in ( "__builtins__.object", "builtins.object", diff --git a/src/autodoc2/astroid_utils.py b/src/autodoc2/astroid_utils.py index 70d48a5..da1e638 100644 --- a/src/autodoc2/astroid_utils.py +++ b/src/autodoc2/astroid_utils.py @@ -589,7 +589,7 @@ def _iter_args( args: list[nodes.NodeNG], annotations: list[nodes.NodeNG], defaults: list[nodes.NodeNG], -) -> t.Iterable[t.Tuple[str, None | str, str | None]]: +) -> t.Iterable[tuple[str, None | str, str | None]]: """Iterate over arguments.""" default_offset = len(args) - len(defaults) packed = itertools.zip_longest(args, annotations) diff --git a/src/autodoc2/config.py b/src/autodoc2/config.py index 79fe011..0970e6e 100644 --- a/src/autodoc2/config.py +++ b/src/autodoc2/config.py @@ -120,7 +120,7 @@ def _coerce_packages(name: str, item: t.Any) -> list[PackageConfig]: return [PackageConfig(**p) for p in new] -def _validate_replace_list(name: str, item: t.Any) -> list[t.Tuple[str, str]]: +def _validate_replace_list(name: str, item: t.Any) -> list[tuple[str, str]]: """Validate that an item is a list of tuples.""" if not isinstance(item, list) or not all( isinstance(x, (list, tuple)) and len(x) == 2 for x in item diff --git a/src/autodoc2/db.py b/src/autodoc2/db.py index 662ce90..33d07ec 100644 --- a/src/autodoc2/db.py +++ b/src/autodoc2/db.py @@ -32,7 +32,7 @@ def remove(self, full_name: str, descendants: bool) -> None: def __contains__(self, full_name: str) -> bool: """Check if an item is in the database, by full_name.""" - def get_item(self, full_name: str) -> t.Optional[ItemData]: + def get_item(self, full_name: str) -> ItemData | None: """Get an item from the database, by full_name.""" def get_items_like(self, full_name: str) -> t.Iterable[ItemData]: @@ -90,8 +90,8 @@ class InMemoryDb(Database): def __init__(self) -> None: """Create the database.""" - self._items: t.Dict[str, ItemData] = {} - self._overloads: t.Dict[str, t.List[ItemData]] = {} + self._items: dict[str, ItemData] = {} + self._overloads: dict[str, list[ItemData]] = {} def add(self, item: ItemData) -> None: if item["type"] == "overload": @@ -118,7 +118,7 @@ def remove(self, full_name: str, descendants: bool) -> None: def __contains__(self, full_name: str) -> bool: return full_name in self._items - def get_item(self, full_name: str) -> t.Optional[ItemData]: + def get_item(self, full_name: str) -> ItemData | None: return self._items.get(full_name) def get_items_like(self, full_name: str) -> t.Iterable[ItemData]: diff --git a/src/autodoc2/render/base.py b/src/autodoc2/render/base.py index 74c91ef..6565c05 100644 --- a/src/autodoc2/render/base.py +++ b/src/autodoc2/render/base.py @@ -69,7 +69,7 @@ def warn( """Warn the user.""" self._warn(msg, type_) - def get_item(self, full_name: str) -> t.Optional[ItemData]: + def get_item(self, full_name: str) -> ItemData | None: """Get an item from the database, by full_name.""" return self._db.get_item(full_name) diff --git a/src/autodoc2/sphinx/autodoc.py b/src/autodoc2/sphinx/autodoc.py index 37898ae..380ff2a 100644 --- a/src/autodoc2/sphinx/autodoc.py +++ b/src/autodoc2/sphinx/autodoc.py @@ -33,7 +33,7 @@ class AutodocObject(SphinxDirective): has_content = True # TODO autogenerate this from the config - option_spec = { + option_spec: t.ClassVar[dict[str, t.Any]] = { "literal": directives.flag, # return the literal render string "literal-lexer": directives.unchanged, # the lexer to use for literal } diff --git a/src/autodoc2/sphinx/docstring.py b/src/autodoc2/sphinx/docstring.py index 1cb9951..bd3f39d 100644 --- a/src/autodoc2/sphinx/docstring.py +++ b/src/autodoc2/sphinx/docstring.py @@ -58,7 +58,7 @@ class DocstringRenderer(SphinxDirective): required_arguments = 1 # the full name optional_arguments = 0 final_argument_whitespace = True - option_spec = { + option_spec: t.ClassVar[dict[str, t.Any]] = { "parser": parser_options, "allowtitles": directives.flag, # used for module docstrings "summary": summary_option, # number of children to return diff --git a/src/autodoc2/sphinx/extension.py b/src/autodoc2/sphinx/extension.py index 2feb88c..44db12a 100644 --- a/src/autodoc2/sphinx/extension.py +++ b/src/autodoc2/sphinx/extension.py @@ -107,7 +107,7 @@ def run_autodoc_package(app: Sphinx, config: Config, pkg_index: int) -> str | No return None path = root_path / PurePosixPath(package.path) - modules: t.Iterable[t.Tuple[Path, str]] + modules: t.Iterable[tuple[Path, str]] if path.is_file(): root_module = package.module or path.stem modules = [(path, root_module)] @@ -180,7 +180,7 @@ def run_autodoc_package(app: Sphinx, config: Config, pkg_index: int) -> str | No # find all the package/module, so we know what files to write LOGGER.info("[Autodoc2] Determining files to write ...") - to_write: t.List[str] = [] + to_write: list[str] = [] stack = [root_module] while stack: item = stack.pop() diff --git a/src/autodoc2/sphinx/summary.py b/src/autodoc2/sphinx/summary.py index 29940ad..3bca353 100644 --- a/src/autodoc2/sphinx/summary.py +++ b/src/autodoc2/sphinx/summary.py @@ -1,6 +1,8 @@ """Directive to generate a summary of listed objects.""" from __future__ import annotations +from typing import Any, ClassVar + from docutils import nodes from docutils.parsers.rst import directives from sphinx.util.docutils import SphinxDirective @@ -22,7 +24,7 @@ class AutodocSummary(SphinxDirective): required_arguments = 0 optional_arguments = 0 final_argument_whitespace = False - option_spec = { + option_spec: ClassVar[dict[str, Any]] = { "renderer": directives.unchanged_required, } diff --git a/tests/test_analyse_module.py b/tests/test_analyse_module.py index a63ef9c..81231c0 100644 --- a/tests/test_analyse_module.py +++ b/tests/test_analyse_module.py @@ -3,9 +3,8 @@ import typing as t -import pytest - from autodoc2.analysis import analyse_module +import pytest def clean_item(item: dict[str, t.Any]) -> dict[str, t.Any]: diff --git a/tests/test_render.py b/tests/test_render.py index 82e4646..219699d 100644 --- a/tests/test_render.py +++ b/tests/test_render.py @@ -3,10 +3,6 @@ from pathlib import Path from textwrap import dedent -import pytest -from sphinx.testing.util import SphinxTestApp -from sphinx.testing.util import path as sphinx_path - from autodoc2.analysis import analyse_module from autodoc2.config import Config from autodoc2.db import InMemoryDb @@ -14,6 +10,9 @@ from autodoc2.render.myst_ import MystRenderer from autodoc2.render.rst_ import RstRenderer from autodoc2.utils import yield_modules +import pytest +from sphinx.testing.util import SphinxTestApp +from sphinx.testing.util import path as sphinx_path @pytest.mark.parametrize(