diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 147c904..abb9087 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,3 @@ -# enable pre-commit.ci at https://pre-commit.ci/ -# it adds: -# 1. auto fixing pull requests -# 2. auto updating the pre-commit configuration ci: autoupdate_schedule: monthly autofix_commit_msg: "style(pre-commit.ci): auto fixes [...]" @@ -17,18 +13,14 @@ repos: rev: v0.6.1 hooks: - id: ruff - args: [--fix] - - - repo: https://github.com/psf/black - rev: 24.8.0 - hooks: - - id: black + args: [--fix, --unsafe-fixes] + - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.11.1 hooks: - id: mypy files: "^src/" - # # you have to add the things you want to type check against here - # additional_dependencies: - # - numpy + additional_dependencies: + - griffe>=1 + - fieldz diff --git a/pyproject.toml b/pyproject.toml index 2670805..600990d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,14 +37,13 @@ classifiers = [ "Topic :: Utilities", "Typing :: Typed", ] -dependencies = ["griffe>=0.35", "fieldz>=0.0.2"] +dependencies = ["griffe>=1.0", "fieldz>=0.1.0"] # https://peps.python.org/pep-0621/#dependencies-optional-dependencies [project.optional-dependencies] test = ["pytest", "pytest-cov"] dev = [ - "black", "ipython", "mypy", "pdbpp", # https://github.com/pdbpp/pdbpp @@ -62,12 +61,15 @@ repository = "https://github.com/pyapp-kit/griffe-fieldz" line-length = 88 target-version = "py38" src = ["src"] -# https://docs.astral.sh/ruff/rules + +[tool.ruff.lint] +pydocstyle = { convention = "numpy" } select = [ "E", # style errors "W", # style warnings "F", # flakes "D", # pydocstyle + "D417", # Missing argument descriptions in Docstrings "I", # isort "UP", # pyupgrade "C4", # flake8-comprehensions @@ -78,19 +80,16 @@ select = [ "TID", # flake8-tidy-imports ] ignore = [ - "D100", # Missing docstring in public module - "D107", # Missing docstring in __init__ - "D203", # 1 blank line required before class docstring - "D212", # Multi-line docstring summary should start at the first line - "D213", # Multi-line docstring summary should start at the second line - "D401", # First line should be in imperative mood - "D413", # Missing blank line after last section - "D416", # Section name should end with a colon + "D401", # First line should be in imperative mood (remove to opt in) ] -[tool.ruff.per-file-ignores] +[tool.ruff.lint.per-file-ignores] "tests/*.py" = ["D", "S"] -"setup.py" = ["D"] + +# https://docs.astral.sh/ruff/formatter/ +[tool.ruff.format] +docstring-code-format = true +skip-magic-trailing-comma = false # default is false # https://mypy.readthedocs.io/en/stable/config_file.html [tool.mypy] @@ -103,7 +102,7 @@ pretty = true # https://docs.pytest.org/en/6.2.x/customize.html [tool.pytest.ini_options] -minversion = "6.0" +minversion = "7.0" testpaths = ["tests"] filterwarnings = ["error"] diff --git a/src/griffe_fieldz/_extension.py b/src/griffe_fieldz/_extension.py index c7e49c2..e8ef3dc 100644 --- a/src/griffe_fieldz/_extension.py +++ b/src/griffe_fieldz/_extension.py @@ -8,28 +8,32 @@ import fieldz from fieldz._repr import display_as_type -from griffe import Class, Extension, Object, ObjectNode, dynamic_import, get_logger -from griffe.dataclasses import Docstring -from griffe.docstrings.dataclasses import ( +from griffe import ( + Class, + Docstring, DocstringAttribute, DocstringParameter, DocstringSection, DocstringSectionAttributes, DocstringSectionParameters, + Extension, + Object, + ObjectNode, + dynamic_import, + get_logger, + parse_docstring_annotation, ) -from griffe.docstrings.utils import parse_annotation if TYPE_CHECKING: import ast - from griffe.expressions import Expr - from pydantic import BaseModel + from griffe import Expr, Inspector, Visitor logger = get_logger(__name__) class FieldzExtension(Extension): - """Griffe extension that reads documentation from `typing.Doc`.""" + """Griffe extension that injects field information for dataclass-likes.""" def __init__( self, @@ -43,7 +47,14 @@ def __init__( self.include_private = include_private self.include_inherited = include_inherited - def on_class_instance(self, *, node: ast.AST | ObjectNode, cls: Class) -> None: + def on_class_instance( + self, + *, + node: ast.AST | ObjectNode, + cls: Class, + agent: Visitor | Inspector, + **kwargs: Any, + ) -> None: if isinstance(node, ObjectNode): return # skip runtime objects @@ -63,7 +74,9 @@ def on_class_instance(self, *, node: ast.AST | ObjectNode, cls: Class) -> None: return self._inject_fields(cls, runtime_obj) - def _inject_fields(self, obj: Object, runtime_obj: type[BaseModel]) -> None: + # ------------------------------ + + def _inject_fields(self, obj: Object, runtime_obj: Any) -> None: # update the object instance with the evaluated docstring docstring = inspect.cleandoc(getattr(runtime_obj, "__doc__", "") or "") if not obj.docstring: @@ -98,7 +111,9 @@ def _inject_fields(self, obj: Object, runtime_obj: type[BaseModel]) -> None: def _to_annotation(type_: Any, docstring: Docstring) -> str | Expr | None: """Create griffe annotation for a type.""" if type_: - return parse_annotation(display_as_type(type_, modern_union=True), docstring) + return parse_docstring_annotation( + display_as_type(type_, modern_union=True), docstring + ) return None @@ -120,7 +135,7 @@ def _fields_to_params( params: list[DocstringParameter] = [] attrs: list[DocstringAttribute] = [] for field in fields: - description = field.description or field.metadata.get("description", "") + description = field.description or field.metadata.get("description", "") or "" kwargs: dict = { "name": field.name, "annotation": _to_annotation(field.type, docstring), diff --git a/tests/test_griffe_fieldz.py b/tests/test_griffe_fieldz.py index 944befb..0c10a86 100644 --- a/tests/test_griffe_fieldz.py +++ b/tests/test_griffe_fieldz.py @@ -1,9 +1,12 @@ """Tests for the Griffe extension.""" -from griffe.docstrings.dataclasses import DocstringParameter, DocstringSectionParameters -from griffe.expressions import ExprName -from griffe.extensions import Extensions -from griffe.loader import GriffeLoader +from griffe import ( + DocstringParameter, + DocstringSectionParameters, + ExprName, + Extensions, + GriffeLoader, +) from griffe_fieldz import FieldzExtension