From f2d39b8ed40f2b90ac15fd7ad818b3c59b657a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Fri, 11 Oct 2024 15:21:46 +0200 Subject: [PATCH] refactor: Drop support for Python 3.8 --- .copier-answers.yml | 2 +- .github/workflows/ci.yml | 8 ++++---- .gitpod.dockerfile | 6 ------ .gitpod.yml | 13 ------------- CONTRIBUTING.md | 2 +- README.md | 7 ++----- config/ruff.toml | 2 +- duties.py | 4 +++- pyproject.toml | 10 +++++----- scripts/gen_credits.py | 7 ++++--- scripts/insiders.py | 5 ++++- scripts/make.py | 7 +++++-- src/_griffe/agents/inspector.py | 3 ++- src/_griffe/agents/nodes/ast.py | 5 ++++- src/_griffe/agents/nodes/parameters.py | 7 +++++-- src/_griffe/agents/nodes/runtime.py | 6 ++++-- src/_griffe/agents/nodes/values.py | 8 +------- src/_griffe/c3linear.py | 5 +++-- src/_griffe/cli.py | 4 +++- src/_griffe/collections.py | 3 ++- src/_griffe/diff.py | 4 +++- src/_griffe/docstrings/google.py | 11 ++++++----- src/_griffe/docstrings/numpy.py | 3 ++- src/_griffe/expressions.py | 15 ++------------- src/_griffe/extensions/base.py | 4 ++-- src/_griffe/extensions/dataclasses.py | 4 ++-- src/_griffe/finder.py | 9 +++++---- src/_griffe/git.py | 5 ++++- src/_griffe/importer.py | 3 ++- src/_griffe/loader.py | 4 +++- src/_griffe/logger.py | 5 ++++- src/_griffe/mixins.py | 4 +++- src/_griffe/models.py | 4 +++- src/_griffe/tests.py | 11 ++++------- tests/test_docstrings/conftest.py | 5 ++++- tests/test_docstrings/helpers.py | 5 +++-- tests/test_finder.py | 7 ++++--- tests/test_inspector.py | 5 +++-- tests/test_internals.py | 5 ++++- tests/test_loader.py | 8 ++++---- tests/test_nodes.py | 7 +++++-- tests/test_stdlib.py | 4 +++- 42 files changed, 129 insertions(+), 117 deletions(-) delete mode 100644 .gitpod.dockerfile delete mode 100644 .gitpod.yml diff --git a/.copier-answers.yml b/.copier-answers.yml index d5813bd4..31dbfd95 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier -_commit: 1.4.6 +_commit: 1.4.7 _src_path: gh:pawamoy/copier-uv author_email: dev@pawamoy.fr author_fullname: Timothée Mazzucotelli diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87333415..39269320 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,11 +75,11 @@ jobs: echo 'jobs=[ {"os": "macos-latest"}, {"os": "windows-latest"}, - {"python-version": "3.9"}, {"python-version": "3.10"}, {"python-version": "3.11"}, {"python-version": "3.12"}, - {"python-version": "3.13"} + {"python-version": "3.13"}, + {"python-version": "3.14"} ]' | tr -d '[:space:]' >> $GITHUB_OUTPUT else echo 'jobs=[ @@ -100,18 +100,18 @@ jobs: - macos-latest - windows-latest python-version: - - "3.8" - "3.9" - "3.10" - "3.11" - "3.12" - "3.13" + - "3.14" resolution: - highest - lowest-direct exclude: ${{ fromJSON(needs.exclude-test-jobs.outputs.jobs) }} runs-on: ${{ matrix.os }} - continue-on-error: ${{ matrix.python-version == '3.13' }} + continue-on-error: ${{ matrix.python-version == '3.14' }} steps: - name: Checkout diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile deleted file mode 100644 index 1590b415..00000000 --- a/.gitpod.dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM gitpod/workspace-full -USER gitpod -ENV PIP_USER=no -RUN pip3 install pipx; \ - pipx install uv; \ - pipx ensurepath diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index 23a3c2b7..00000000 --- a/.gitpod.yml +++ /dev/null @@ -1,13 +0,0 @@ -vscode: - extensions: - - ms-python.python - -image: - file: .gitpod.dockerfile - -ports: -- port: 8000 - onOpen: notify - -tasks: -- init: make setup diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 49cb30d1..65db0156 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,4 +10,4 @@ We provide a guide for contributors. If you are reading this locally or directly - Development workflow: [docs/guide/contributors/workflow.md](docs/guide/contributors/workflow.md) - Project architecture: [docs/guide/contributors/architecture.md](docs/guide/contributors/architecture.md) -However we strongly recommend reading the online version at https://mkdocstrings.github.io/griffe/guide/contributors/, as some content is dynamically generated when building the documentation pages. +We strongly recommend reading the online version at https://mkdocstrings.github.io/griffe/guide/contributors/, as some content is dynamically generated when building the documentation pages. diff --git a/README.md b/README.md index 9192c68f..c9eee2f1 100644 --- a/README.md +++ b/README.md @@ -19,17 +19,14 @@ but also "signature" in a familiar way. "On reconnaît bien là sa griffe." ## Installation -With `pip`: - ```bash pip install griffe ``` -With [`pipx`](https://github.com/pipxproject/pipx): +With [`uv`](https://docs.astral.sh/uv/): ```bash -python3.8 -m pip install --user pipx -pipx install griffe +uv tool install griffe ``` ## Usage diff --git a/config/ruff.toml b/config/ruff.toml index 1bee3a61..d3ad4625 100644 --- a/config/ruff.toml +++ b/config/ruff.toml @@ -1,4 +1,4 @@ -target-version = "py38" +target-version = "py39" line-length = 120 [lint] diff --git a/duties.py b/duties.py index 3526cb44..a2533991 100644 --- a/duties.py +++ b/duties.py @@ -8,11 +8,13 @@ from functools import partial from importlib.metadata import version as pkgversion from pathlib import Path -from typing import TYPE_CHECKING, Iterator +from typing import TYPE_CHECKING from duty import duty, tools if TYPE_CHECKING: + from collections.abc import Iterator + from duty.context import Context diff --git a/pyproject.toml b/pyproject.toml index ae57b660..5f779c38 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,8 +8,7 @@ description = "Signatures for entire Python programs. Extract the structure, the authors = [{name = "Timothée Mazzucotelli", email = "dev@pawamoy.fr"}] license = {text = "ISC"} readme = "README.md" -# YORE: EOL 3.8: Remove `3.8` with `3.9` within line. -requires-python = ">=3.8" +requires-python = ">=3.9" keywords = ["api", "signature", "breaking-changes", "static-analysis", "dynamic-analysis"] dynamic = ["version"] classifiers = [ @@ -18,8 +17,6 @@ classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - # YORE: EOL 3.8: Remove line. - "Programming Language :: Python :: 3.8", # YORE: EOL 3.9: Remove line. "Programming Language :: Python :: 3.9", # YORE: EOL 3.10: Remove line. @@ -30,6 +27,8 @@ classifiers = [ "Programming Language :: Python :: 3.12", # YORE: EOL 3.13: Remove line. "Programming Language :: Python :: 3.13", + # YORE: EOL 3.14: Remove line. + "Programming Language :: Python :: 3.14", "Topic :: Documentation", "Topic :: Software Development", "Topic :: Software Development :: Documentation", @@ -87,7 +86,7 @@ dev-dependencies = [ # maintenance "build>=1.2", "git-changelog>=2.5", - "twine>=5.0; python_version < '3.13'", + "twine>=5.1", # ci "duty>=1.4", @@ -120,5 +119,6 @@ dev-dependencies = [ "mkdocs-redirects>=1.2", "mkdocstrings[python]>=0.25", "pydeps>=1.12", + # YORE: EOL 3.10: Remove line. "tomli>=2.0; python_version < '3.11'", ] \ No newline at end of file diff --git a/scripts/gen_credits.py b/scripts/gen_credits.py index f7140431..703609b7 100644 --- a/scripts/gen_credits.py +++ b/scripts/gen_credits.py @@ -5,11 +5,12 @@ import os import sys from collections import defaultdict +from collections.abc import Iterable from importlib.metadata import distributions from itertools import chain from pathlib import Path from textwrap import dedent -from typing import Dict, Iterable, Union +from typing import Union from jinja2 import StrictUndefined from jinja2.sandbox import SandboxedEnvironment @@ -28,8 +29,8 @@ project_name = project["name"] devdeps = [dep for dep in pyproject["tool"]["uv"]["dev-dependencies"] if not dep.startswith("-e")] -PackageMetadata = Dict[str, Union[str, Iterable[str]]] -Metadata = Dict[str, PackageMetadata] +PackageMetadata = dict[str, Union[str, Iterable[str]]] +Metadata = dict[str, PackageMetadata] def _merge_fields(metadata: dict) -> PackageMetadata: diff --git a/scripts/insiders.py b/scripts/insiders.py index 6e765d26..efba86a2 100644 --- a/scripts/insiders.py +++ b/scripts/insiders.py @@ -10,13 +10,16 @@ from datetime import date, datetime, timedelta from itertools import chain from pathlib import Path -from typing import Iterable, cast +from typing import TYPE_CHECKING, cast from urllib.error import HTTPError from urllib.parse import urljoin from urllib.request import urlopen import yaml +if TYPE_CHECKING: + from collections.abc import Iterable + logger = logging.getLogger(f"mkdocs.logs.{__name__}") diff --git a/scripts/make.py b/scripts/make.py index c19a394a..82c8a30e 100755 --- a/scripts/make.py +++ b/scripts/make.py @@ -9,9 +9,12 @@ import sys from contextlib import contextmanager from pathlib import Path -from typing import Any, Callable, Iterator +from typing import TYPE_CHECKING, Any, Callable -PYTHON_VERSIONS = os.getenv("PYTHON_VERSIONS", "3.8 3.9 3.10 3.11 3.12 3.13").split() +if TYPE_CHECKING: + from collections.abc import Iterator + +PYTHON_VERSIONS = os.getenv("PYTHON_VERSIONS", "3.9 3.10 3.11 3.12 3.13 3.14").split() _commands = [] diff --git a/src/_griffe/agents/inspector.py b/src/_griffe/agents/inspector.py index 36e84f97..d0d32dd5 100644 --- a/src/_griffe/agents/inspector.py +++ b/src/_griffe/agents/inspector.py @@ -7,7 +7,7 @@ from inspect import Parameter as SignatureParameter from inspect import Signature, cleandoc, getsourcelines from inspect import signature as getsignature -from typing import TYPE_CHECKING, Any, Sequence +from typing import TYPE_CHECKING, Any from _griffe.agents.nodes.runtime import ObjectNode from _griffe.collections import LinesCollection, ModulesCollection @@ -19,6 +19,7 @@ from _griffe.models import Alias, Attribute, Class, Docstring, Function, Module, Parameter, Parameters if TYPE_CHECKING: + from collections.abc import Sequence from pathlib import Path from _griffe.enumerations import Parser diff --git a/src/_griffe/agents/nodes/ast.py b/src/_griffe/agents/nodes/ast.py index f4bd33bb..a4f6550a 100644 --- a/src/_griffe/agents/nodes/ast.py +++ b/src/_griffe/agents/nodes/ast.py @@ -3,10 +3,13 @@ from __future__ import annotations from ast import AST -from typing import Iterator +from typing import TYPE_CHECKING from _griffe.exceptions import LastNodeError +if TYPE_CHECKING: + from collections.abc import Iterator + def ast_kind(node: AST) -> str: """Return the kind of an AST node. diff --git a/src/_griffe/agents/nodes/parameters.py b/src/_griffe/agents/nodes/parameters.py index 7bb0d86b..e2c5f58b 100644 --- a/src/_griffe/agents/nodes/parameters.py +++ b/src/_griffe/agents/nodes/parameters.py @@ -4,11 +4,14 @@ import ast from itertools import zip_longest -from typing import Iterable, List, Optional, Tuple, Union +from typing import TYPE_CHECKING, Optional, Union from _griffe.enumerations import ParameterKind -ParametersType = List[Tuple[str, Optional[ast.AST], ParameterKind, Optional[Union[str, ast.AST]]]] +if TYPE_CHECKING: + from collections.abc import Iterable + +ParametersType = list[tuple[str, Optional[ast.AST], ParameterKind, Optional[Union[str, ast.AST]]]] """Type alias for the list of parameters of a function.""" diff --git a/src/_griffe/agents/nodes/runtime.py b/src/_griffe/agents/nodes/runtime.py index 880d1665..743c778e 100644 --- a/src/_griffe/agents/nodes/runtime.py +++ b/src/_griffe/agents/nodes/runtime.py @@ -5,11 +5,14 @@ import inspect import sys from functools import cached_property -from typing import Any, ClassVar, Sequence +from typing import TYPE_CHECKING, Any, ClassVar from _griffe.enumerations import ObjectKind from _griffe.logger import logger +if TYPE_CHECKING: + from collections.abc import Sequence + _builtin_module_names = {_.lstrip("_") for _ in sys.builtin_module_names} _cyclic_relationships = { ("os", "nt"), @@ -19,7 +22,6 @@ def _same_components(a: str, b: str, /) -> bool: - # YORE: EOL 3.8: Replace `lstrip` with `removeprefix` within line. return [cpn.lstrip("_") for cpn in a.split(".")] == [cpn.lstrip("_") for cpn in b.split(".")] diff --git a/src/_griffe/agents/nodes/values.py b/src/_griffe/agents/nodes/values.py index 9b102b28..a7d47767 100644 --- a/src/_griffe/agents/nodes/values.py +++ b/src/_griffe/agents/nodes/values.py @@ -3,17 +3,11 @@ from __future__ import annotations import ast -import sys +from ast import unparse from typing import TYPE_CHECKING from _griffe.logger import logger -# YORE: EOL 3.8: Replace block with line 4. -if sys.version_info < (3, 9): - from astunparse import unparse -else: - from ast import unparse - if TYPE_CHECKING: from pathlib import Path diff --git a/src/_griffe/c3linear.py b/src/_griffe/c3linear.py index 6a1816b6..5bdd689f 100644 --- a/src/_griffe/c3linear.py +++ b/src/_griffe/c3linear.py @@ -7,13 +7,14 @@ from __future__ import annotations +from collections import deque from itertools import islice -from typing import Deque, TypeVar +from typing import TypeVar _T = TypeVar("_T") -class _Dependency(Deque[_T]): +class _Dependency(deque[_T]): """A class representing a (doubly-ended) queue of items.""" @property diff --git a/src/_griffe/cli.py b/src/_griffe/cli.py index 8c819d1a..30088764 100644 --- a/src/_griffe/cli.py +++ b/src/_griffe/cli.py @@ -19,7 +19,7 @@ import sys from datetime import datetime, timezone from pathlib import Path -from typing import IO, TYPE_CHECKING, Any, Callable, Sequence +from typing import IO, TYPE_CHECKING, Any, Callable import colorama @@ -34,6 +34,8 @@ from _griffe.logger import logger if TYPE_CHECKING: + from collections.abc import Sequence + from _griffe.extensions.base import Extension, Extensions diff --git a/src/_griffe/collections.py b/src/_griffe/collections.py index e5df2c2b..843b177f 100644 --- a/src/_griffe/collections.py +++ b/src/_griffe/collections.py @@ -3,11 +3,12 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, ItemsView, KeysView, ValuesView +from typing import TYPE_CHECKING, Any from _griffe.mixins import DelMembersMixin, GetMembersMixin, SetMembersMixin if TYPE_CHECKING: + from collections.abc import ItemsView, KeysView, ValuesView from pathlib import Path from _griffe.models import Module diff --git a/src/_griffe/diff.py b/src/_griffe/diff.py index 0cf8fce2..7217d856 100644 --- a/src/_griffe/diff.py +++ b/src/_griffe/diff.py @@ -10,7 +10,7 @@ import contextlib from pathlib import Path -from typing import TYPE_CHECKING, Any, Iterable, Iterator +from typing import TYPE_CHECKING, Any from colorama import Fore, Style @@ -20,6 +20,8 @@ from _griffe.logger import logger if TYPE_CHECKING: + from collections.abc import Iterable, Iterator + from _griffe.models import Alias, Attribute, Class, Function, Object _POSITIONAL = frozenset((ParameterKind.positional_only, ParameterKind.positional_or_keyword)) diff --git a/src/_griffe/docstrings/google.py b/src/_griffe/docstrings/google.py index 414891a7..ed686601 100644 --- a/src/_griffe/docstrings/google.py +++ b/src/_griffe/docstrings/google.py @@ -4,7 +4,7 @@ import re from contextlib import suppress -from typing import TYPE_CHECKING, List, Tuple +from typing import TYPE_CHECKING from _griffe.docstrings.models import ( DocstringAttribute, @@ -38,7 +38,8 @@ from _griffe.enumerations import DocstringSectionKind, LogLevel if TYPE_CHECKING: - from typing import Any, Literal, Pattern + from re import Pattern + from typing import Any, Literal from _griffe.expressions import Expr from _griffe.models import Docstring @@ -70,9 +71,9 @@ "warnings": DocstringSectionKind.warns, } -_BlockItem = Tuple[int, List[str]] -_BlockItems = List[_BlockItem] -_ItemsBlock = Tuple[_BlockItems, int] +_BlockItem = tuple[int, list[str]] +_BlockItems = list[_BlockItem] +_ItemsBlock = tuple[_BlockItems, int] _RE_ADMONITION: Pattern = re.compile(r"^(?P[\w][\s\w-]*):(\s+(?P[^\s].*))?\s*$", re.IGNORECASE) _RE_NAME_ANNOTATION_DESCRIPTION: Pattern = re.compile(r"^(?:(?P<name>\w+)?\s*(?:\((?P<type>.+)\))?:\s*)?(?P<desc>.*)$") diff --git a/src/_griffe/docstrings/numpy.py b/src/_griffe/docstrings/numpy.py index 78b0933d..29612993 100644 --- a/src/_griffe/docstrings/numpy.py +++ b/src/_griffe/docstrings/numpy.py @@ -57,7 +57,8 @@ from _griffe.expressions import ExprName if TYPE_CHECKING: - from typing import Any, Literal, Pattern + from re import Pattern + from typing import Any, Literal from _griffe.expressions import Expr from _griffe.models import Docstring diff --git a/src/_griffe/expressions.py b/src/_griffe/expressions.py index 9ca91220..f507b2af 100644 --- a/src/_griffe/expressions.py +++ b/src/_griffe/expressions.py @@ -12,7 +12,7 @@ from dataclasses import fields as getfields from functools import partial from itertools import zip_longest -from typing import TYPE_CHECKING, Any, Callable, Iterable, Iterator, Sequence +from typing import TYPE_CHECKING, Any, Callable from _griffe.agents.nodes.parameters import get_parameters from _griffe.enumerations import LogLevel, ParameterKind @@ -20,6 +20,7 @@ from _griffe.logger import logger if TYPE_CHECKING: + from collections.abc import Iterable, Iterator, Sequence from pathlib import Path from _griffe.models import Class, Module @@ -1171,18 +1172,6 @@ def _build_yield_from(node: ast.YieldFrom, parent: Module | Class, **kwargs: Any ast.YieldFrom: _build_yield_from, } -# YORE: EOL 3.8: Remove block. -if sys.version_info < (3, 9): - - def _build_extslice(node: ast.ExtSlice, parent: Module | Class, **kwargs: Any) -> Expr: - return ExprExtSlice([_build(dim, parent, **kwargs) for dim in node.dims]) - - def _build_index(node: ast.Index, parent: Module | Class, **kwargs: Any) -> Expr: - return _build(node.value, parent, **kwargs) - - _node_map[ast.ExtSlice] = _build_extslice - _node_map[ast.Index] = _build_index - def _build(node: ast.AST, parent: Module | Class, **kwargs: Any) -> Expr: return _node_map[type(node)](node, parent, **kwargs) diff --git a/src/_griffe/extensions/base.py b/src/_griffe/extensions/base.py index 0499af6c..48323877 100644 --- a/src/_griffe/extensions/base.py +++ b/src/_griffe/extensions/base.py @@ -8,7 +8,7 @@ from importlib.util import module_from_spec, spec_from_file_location from inspect import isclass from pathlib import Path -from typing import TYPE_CHECKING, Any, Dict, Type, Union +from typing import TYPE_CHECKING, Any, Union from _griffe.agents.nodes.ast import ast_children, ast_kind from _griffe.exceptions import ExtensionNotLoadedError @@ -277,7 +277,7 @@ def on_wildcard_expansion( """ -LoadableExtensionType = Union[str, Dict[str, Any], Extension, Type[Extension]] +LoadableExtensionType = Union[str, dict[str, Any], Extension, type[Extension]] """All the types that can be passed to `load_extensions`.""" diff --git a/src/_griffe/extensions/dataclasses.py b/src/_griffe/extensions/dataclasses.py index c6d086b8..144fc0fe 100644 --- a/src/_griffe/extensions/dataclasses.py +++ b/src/_griffe/extensions/dataclasses.py @@ -7,7 +7,7 @@ import ast from contextlib import suppress -from functools import lru_cache +from functools import cache from typing import Any, cast from _griffe.enumerations import ParameterKind @@ -62,7 +62,7 @@ def _field_arguments(attribute: Attribute) -> dict[str, Any]: return {} -@lru_cache(maxsize=None) +@cache def _dataclass_parameters(class_: Class) -> list[Parameter]: # Fetch `@dataclass` arguments if any. dec_args = _dataclass_arguments(class_.decorators) diff --git a/src/_griffe/finder.py b/src/_griffe/finder.py index 8613dc76..5f3102ba 100644 --- a/src/_griffe/finder.py +++ b/src/_griffe/finder.py @@ -25,13 +25,14 @@ from dataclasses import dataclass from itertools import chain from pathlib import Path -from typing import TYPE_CHECKING, ClassVar, Iterator, Sequence, Tuple +from typing import TYPE_CHECKING, ClassVar from _griffe.exceptions import UnhandledEditableModuleError from _griffe.logger import logger if TYPE_CHECKING: - from typing import Pattern + from collections.abc import Iterator, Sequence + from re import Pattern from _griffe.models import Module @@ -41,9 +42,9 @@ _editable_scikit_build_core_patterns = [re.compile(pat) for pat in (r"^_\w+_editable.py$",)] _editable_meson_python_patterns = [re.compile(pat) for pat in (r"^_\w+_editable_loader.py$",)] -NamePartsType = Tuple[str, ...] +NamePartsType = tuple[str, ...] """Type alias for the parts of a module name.""" -NamePartsAndPathType = Tuple[NamePartsType, Path] +NamePartsAndPathType = tuple[NamePartsType, Path] """Type alias for the parts of a module name and its path.""" diff --git a/src/_griffe/git.py b/src/_griffe/git.py index 62370260..8b2716f7 100644 --- a/src/_griffe/git.py +++ b/src/_griffe/git.py @@ -12,10 +12,13 @@ from contextlib import contextmanager from pathlib import Path from tempfile import TemporaryDirectory -from typing import Iterator +from typing import TYPE_CHECKING from _griffe.exceptions import GitError +if TYPE_CHECKING: + from collections.abc import Iterator + _WORKTREE_PREFIX = "griffe-worktree-" diff --git a/src/_griffe/importer.py b/src/_griffe/importer.py index 48fb5848..aac5f8cd 100644 --- a/src/_griffe/importer.py +++ b/src/_griffe/importer.py @@ -7,9 +7,10 @@ import sys from contextlib import contextmanager from importlib import import_module -from typing import TYPE_CHECKING, Any, Iterator, Sequence +from typing import TYPE_CHECKING, Any if TYPE_CHECKING: + from collections.abc import Iterator, Sequence from pathlib import Path diff --git a/src/_griffe/loader.py b/src/_griffe/loader.py index 0958f590..ebd54a92 100644 --- a/src/_griffe/loader.py +++ b/src/_griffe/loader.py @@ -6,7 +6,7 @@ from contextlib import suppress from datetime import datetime, timezone from pathlib import Path -from typing import TYPE_CHECKING, Any, ClassVar, Sequence, cast +from typing import TYPE_CHECKING, Any, ClassVar, cast from _griffe.agents.inspector import inspect from _griffe.agents.visitor import visit @@ -29,6 +29,8 @@ from _griffe.stats import Stats if TYPE_CHECKING: + from collections.abc import Sequence + from _griffe.enumerations import Parser _builtin_modules: set[str] = set(sys.builtin_module_names) diff --git a/src/_griffe/logger.py b/src/_griffe/logger.py index f5a1f6d2..6a7290fc 100644 --- a/src/_griffe/logger.py +++ b/src/_griffe/logger.py @@ -11,7 +11,10 @@ import logging from contextlib import contextmanager -from typing import Any, Callable, ClassVar, Iterator +from typing import TYPE_CHECKING, Any, Callable, ClassVar + +if TYPE_CHECKING: + from collections.abc import Iterator class Logger: diff --git a/src/_griffe/mixins.py b/src/_griffe/mixins.py index 1eddecab..339efa46 100644 --- a/src/_griffe/mixins.py +++ b/src/_griffe/mixins.py @@ -5,13 +5,15 @@ import json from contextlib import suppress -from typing import TYPE_CHECKING, Any, Sequence, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar from _griffe.enumerations import Kind from _griffe.exceptions import AliasResolutionError, BuiltinModuleError, CyclicAliasError from _griffe.merger import merge_stubs if TYPE_CHECKING: + from collections.abc import Sequence + from _griffe.models import Alias, Attribute, Class, Function, Module, Object _ObjType = TypeVar("_ObjType") diff --git a/src/_griffe/models.py b/src/_griffe/models.py index 0c7b1e91..83794214 100644 --- a/src/_griffe/models.py +++ b/src/_griffe/models.py @@ -8,7 +8,7 @@ from contextlib import suppress from pathlib import Path from textwrap import dedent -from typing import TYPE_CHECKING, Any, Callable, Sequence, Union, cast +from typing import TYPE_CHECKING, Any, Callable, Union, cast from _griffe.c3linear import c3linear_merge from _griffe.docstrings.parsers import DocstringStyle, parse @@ -19,6 +19,8 @@ from _griffe.mixins import ObjectAliasMixin if TYPE_CHECKING: + from collections.abc import Sequence + from _griffe.collections import LinesCollection, ModulesCollection from _griffe.docstrings.models import DocstringSection from _griffe.expressions import Expr diff --git a/src/_griffe/tests.py b/src/_griffe/tests.py index a8ab7cf8..d4c07bc6 100644 --- a/src/_griffe/tests.py +++ b/src/_griffe/tests.py @@ -11,7 +11,7 @@ from importlib import invalidate_caches from pathlib import Path from textwrap import dedent -from typing import TYPE_CHECKING, Any, Iterator, Mapping, Sequence +from typing import TYPE_CHECKING, Any from _griffe.agents.inspector import inspect from _griffe.agents.visitor import visit @@ -20,6 +20,8 @@ from _griffe.models import Module, Object if TYPE_CHECKING: + from collections.abc import Iterator, Mapping, Sequence + from _griffe.collections import ModulesCollection from _griffe.enumerations import Parser from _griffe.extensions.base import Extensions @@ -408,11 +410,6 @@ def module_vtree(path: str, *, leaf_package: bool = True, return_leaf: bool = Fa parts = path.split(".") modules = [Module(name, filepath=Path(*parts[:index], "__init__.py")) for index, name in enumerate(parts)] if not leaf_package: - # YORE: EOL 3.8: Replace block with line 2. - try: - filepath = modules[-1].filepath.with_stem(parts[-1]) # type: ignore[union-attr] - except AttributeError: - filepath = modules[-1].filepath.with_name(f"{parts[-1]}.py") # type: ignore[union-attr] - + filepath = modules[-1].filepath.with_stem(parts[-1]) # type: ignore[union-attr] modules[-1]._filepath = filepath return vtree(*modules, return_leaf=return_leaf) # type: ignore[return-value] diff --git a/tests/test_docstrings/conftest.py b/tests/test_docstrings/conftest.py index 86043893..c1ee50fb 100644 --- a/tests/test_docstrings/conftest.py +++ b/tests/test_docstrings/conftest.py @@ -2,13 +2,16 @@ from __future__ import annotations -from typing import Iterator +from typing import TYPE_CHECKING import pytest from _griffe.docstrings import google, numpy, sphinx from tests.test_docstrings.helpers import ParserType, parser +if TYPE_CHECKING: + from collections.abc import Iterator + @pytest.fixture def parse_google() -> Iterator[ParserType]: diff --git a/tests/test_docstrings/helpers.py b/tests/test_docstrings/helpers.py index 985d0971..3fd9aa64 100644 --- a/tests/test_docstrings/helpers.py +++ b/tests/test_docstrings/helpers.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Iterator, List, Protocol, Tuple, Union +from typing import TYPE_CHECKING, Any, Protocol, Union from griffe import ( Attribute, @@ -15,11 +15,12 @@ ) if TYPE_CHECKING: + from collections.abc import Iterator from types import ModuleType ParentType = Union[Module, Class, Function, Attribute, None] -ParseResultType = Tuple[List[DocstringSection], List[str]] +ParseResultType = tuple[list[DocstringSection], list[str]] class ParserType(Protocol): # noqa: D101 diff --git a/tests/test_finder.py b/tests/test_finder.py index 861fcd8c..71151a38 100644 --- a/tests/test_finder.py +++ b/tests/test_finder.py @@ -60,9 +60,10 @@ def test_find_pkg_style_namespace_packages(statement: str) -> None: Parameters: statement: The statement in the `__init__` module allowing to mark the package as namespace. """ - with temporary_pypackage("namespace/package1") as tmp_package1, temporary_pypackage( - "namespace/package2", - ) as tmp_package2: + with ( + temporary_pypackage("namespace/package1") as tmp_package1, + temporary_pypackage("namespace/package2") as tmp_package2, + ): tmp_package1.path.parent.joinpath("__init__.py").write_text(statement) tmp_package2.path.parent.joinpath("__init__.py").write_text(statement) finder = ModuleFinder(search_paths=[tmp_package1.tmpdir, tmp_package2.tmpdir]) diff --git a/tests/test_inspector.py b/tests/test_inspector.py index 91a0db25..8e634a74 100644 --- a/tests/test_inspector.py +++ b/tests/test_inspector.py @@ -48,8 +48,9 @@ def method(self, p: StringIO): def test_missing_dependency() -> None: """Assert missing dependencies are handled during dynamic imports.""" - with pytest.raises(ImportError, match="ModuleNotFoundError: No module named 'missing'"), temporary_inspected_module( - "import missing", + with ( + pytest.raises(ImportError, match="ModuleNotFoundError: No module named 'missing'"), + temporary_inspected_module("import missing"), ): pass diff --git a/tests/test_internals.py b/tests/test_internals.py index c5ec4a08..aeff5f8e 100644 --- a/tests/test_internals.py +++ b/tests/test_internals.py @@ -5,13 +5,16 @@ from collections import defaultdict from fnmatch import fnmatch from pathlib import Path -from typing import Iterator +from typing import TYPE_CHECKING import pytest from mkdocstrings.inventory import Inventory import griffe +if TYPE_CHECKING: + from collections.abc import Iterator + @pytest.fixture(name="loader", scope="module") def _fixture_loader() -> griffe.GriffeLoader: diff --git a/tests/test_loader.py b/tests/test_loader.py index ccd2930c..0903a500 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -461,10 +461,10 @@ def test_side_loading_sibling_private_module(wildcard: bool, external: bool | No def test_forcing_inspection() -> None: """Load a package with forced dynamic analysis.""" modules = {"__init__.py": "a = 0", "mod.py": "b = 1"} - with temporary_visited_package("static_pkg", modules) as static_package, temporary_inspected_package( - "dynamic_pkg", - modules, - ) as dynamic_package: + with ( + temporary_visited_package("static_pkg", modules) as static_package, + temporary_inspected_package("dynamic_pkg", modules) as dynamic_package, + ): for name in static_package.members: assert name in dynamic_package.members for name in static_package["mod"].members: diff --git a/tests/test_nodes.py b/tests/test_nodes.py index 54f9b930..f2ee1df3 100644 --- a/tests/test_nodes.py +++ b/tests/test_nodes.py @@ -264,12 +264,15 @@ def test_parsing_dynamic_base_classes(caplog: pytest.LogCaptureFixture) -> None: Parameters: caplog: Pytest fixture to capture logs. """ - with caplog.at_level(logging.ERROR), temporary_visited_module( - """ + with ( + caplog.at_level(logging.ERROR), + temporary_visited_module( + """ from collections import namedtuple class Thing(namedtuple('Thing', 'attr1 attr2')): ... """, + ), ): pass assert not caplog.records diff --git a/tests/test_stdlib.py b/tests/test_stdlib.py index e88bc189..5dfbc743 100644 --- a/tests/test_stdlib.py +++ b/tests/test_stdlib.py @@ -4,13 +4,15 @@ import sys from contextlib import suppress -from typing import TYPE_CHECKING, Iterator +from typing import TYPE_CHECKING import pytest from griffe import GriffeLoader, LoadingError if TYPE_CHECKING: + from collections.abc import Iterator + from griffe import Alias, Object