Skip to content

Commit

Permalink
Merge pull request #3 from AntoineD/develop
Browse files Browse the repository at this point in the history
New release candidate
  • Loading branch information
AntoineD committed Jun 6, 2023
2 parents ed60d96 + 86444d4 commit ca3e6ce
Show file tree
Hide file tree
Showing 16 changed files with 220 additions and 170 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v2
- name: Setup Python
Expand Down
21 changes: 9 additions & 12 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ repos:
- id: rst-inline-touching-normal

- repo: https://github.com/PyCQA/autoflake
rev: v2.0.0
rev: v2.1.1
hooks:
- id: autoflake
args: [
Expand All @@ -34,32 +34,29 @@ repos:
args: [
--application-directories,
src,
--py37-plus,
--py38-plus,
--add-import,
"from __future__ import annotations",
]

- repo: https://github.com/myint/docformatter
rev: v1.5.1
rev: v1.7.1
hooks:
- id: docformatter
exclude: ^tests/
args: [
--in-place,
--wrap-summaries,
"88",
--wrap-descriptions,
"88",
--black,
]

- repo: https://github.com/asottile/pyupgrade
rev: v3.3.1
rev: v3.4.0
hooks:
- id: pyupgrade
args: [--py37-plus]
args: [--py38-plus]

- repo: https://github.com/psf/black
rev: 22.12.0
rev: 23.3.0
hooks:
- id: black

Expand All @@ -74,15 +71,15 @@ repos:
- pep8-naming==0.13.3

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.991
rev: v1.3.0
hooks:
- id: mypy
exclude: ^(tests/|setup\.py)
args:
- --strict

- repo: https://github.com/Lucas-C/pre-commit-hooks
rev: v1.3.1
rev: v1.5.1
hooks:
- id: insert-license
name: insert MIT license
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.0.0rc0] - 2023-06
### Changed
- Docstring inheritance for methods only inherit from the first found parent.
### Fixed
- Docstring inheritance for methods with no argument descriptions.
- Format of the arguments provided with the default description for the Numpy style.

## [1.1.1] - 2023-01
### Fixed
- Docstring inheritance for methods with multiple parents.
Expand Down
46 changes: 44 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,50 @@
[build-system]
requires = ["setuptools>=45", "wheel", "setuptools_scm>=6.2"]
requires = ["setuptools", "setuptools_scm"]
build-backend = "setuptools.build_meta"

[project]
name = "docstring-inheritance"
dynamic = ["version"]
description = "Avoid writing and maintaining duplicated docstrings."
readme = "README.md"
license = {text = "MIT"}
requires-python = ">=3.8, <3.12"
authors = [
{name = "Antoine Dechaume"},
]
classifiers = [
"License :: OSI Approved :: MIT License",
"Operating System :: MacOS",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
]

[project.optional-dependencies]
test = [
"covdefaults",
"pytest",
"pytest-cov",
]

[project.urls]
Documentation = "https://antoined.github.io/docstring-inheritance"
Homepage = "https://github.com/AntoineD/docstring-inheritance"
Source = "https://github.com/AntoineD/docstring-inheritance"
Tracker = "https://github.com/AntoineD/docstring-inheritance/issues"

[tool.setuptools_scm]

[tool.black]
target-version = ['py37']
target-version = ['py38']

[tool.pytest.ini_options]
testpaths = ["tests"]

[tool.coverage.run]
plugins = ["covdefaults"]
source = ["docstring_inheritance"]
28 changes: 8 additions & 20 deletions requirements/test.txt
Original file line number Diff line number Diff line change
@@ -1,40 +1,28 @@
#
# This file is autogenerated by pip-compile with Python 3.7
# This file is autogenerated by pip-compile with Python 3.8
# by the following command:
#
# pip-compile --extra=test --output-file=requirements/test.txt
#
attrs==22.2.0
# via pytest
covdefaults==2.2.2
covdefaults==2.3.0
# via docstring-inheritance (setup.py)
coverage[toml]==7.0.5
coverage[toml]==7.2.7
# via
# covdefaults
# pytest-cov
exceptiongroup==1.1.0
exceptiongroup==1.1.1
# via pytest
importlib-metadata==6.0.0
# via
# pluggy
# pytest
iniconfig==2.0.0
# via pytest
packaging==23.0
packaging==23.1
# via pytest
pluggy==1.0.0
# via pytest
pytest==7.2.0
pytest==7.3.1
# via
# docstring-inheritance (setup.py)
# pytest-cov
pytest-cov==4.0.0
pytest-cov==4.1.0
# via docstring-inheritance (setup.py)
tomli==2.0.1
# via
# coverage
# pytest
typing-extensions==4.4.0
# via importlib-metadata
zipp==3.11.0
# via importlib-metadata
# via pytest
52 changes: 0 additions & 52 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,55 +1,3 @@
[metadata]
name = docstring-inheritance
author = Antoine Dechaume
url = https://github.com/AntoineD/docstring-inheritance
project_urls =
Documentation = https://antoined.github.io/docstring-inheritance
Source = https://github.com/AntoineD/docstring-inheritance
Tracker = https://github.com/AntoineD/docstring-inheritance/issues
description = Avoid writing and maintaining duplicated docstrings.
long_description = file: README.md
long_description_content_type = text/markdown
license = MIT
license_files =
LICENSE.txt
CREDITS.md
classifiers =
License :: OSI Approved :: MIT License
Operating System :: POSIX :: Linux
Operating System :: MacOS
Operating System :: Microsoft :: Windows
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11

[options]
package_dir =
=src
packages = find:
python_requires = >=3.7, <3.12

[options.packages.find]
where = src

[options.extras_require]
# Dependencies for testing.
test =
covdefaults
pytest
pytest-cov

# Tools settings

[tool:pytest]
testpaths = tests

[coverage:run]
plugins = covdefaults
source = docstring_inheritance

[flake8]
ignore =
# No docstring for standard and private methods.
Expand Down
24 changes: 0 additions & 24 deletions setup.py

This file was deleted.

23 changes: 14 additions & 9 deletions src/docstring_inheritance/class_docstrings_inheritor.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,11 @@ def _inherit_class_docstring(
if func is None:
func = self._create_dummy_func_with_doc(self._cls.__doc__)

for cls_ in self.__mro_classes:
self._docstring_inheritor(cls_.__doc__, func)
for parent_cls in self.__mro_classes:
# As opposed to the attribute inheritance, and following the way a class is
# assembled by type(), the docstring of a class is the combination of the
# docstrings of its parents.
self._docstring_inheritor(parent_cls.__doc__, func)

self._cls.__doc__ = func.__doc__

Expand All @@ -119,13 +122,15 @@ def _inherit_attrs_docstrings(
if not isinstance(attr, FunctionType):
continue

for cls_ in self.__mro_classes:
method = getattr(cls_, attr_name, None)
if method is None:
continue
parent_doc = method.__doc__
if parent_doc is not None:
self._docstring_inheritor(parent_doc, attr)
for parent_cls in self.__mro_classes:
parent_method = getattr(parent_cls, attr_name, None)
if parent_method is not None:
parent_doc = parent_method.__doc__
if parent_doc is not None:
self._docstring_inheritor(parent_doc, attr)
# As opposed to the class docstring inheritance, and following
# the MRO for methods, we inherit only from the first found parent.
break

@staticmethod
def _create_dummy_func_with_doc(docstring: str | None) -> Callable[..., Any]:
Expand Down
33 changes: 20 additions & 13 deletions src/docstring_inheritance/docstring_inheritors/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,16 @@ class AbstractDocstringInheritor:
"References",
"Examples",
]
_ARGS_SECTION_ITEMS_NAMES: ClassVar[set[str]]
_SECTION_ITEMS_NAMES: ClassVar[set[str]]
"""Names of the sections."""

_ARGS_SECTION_NAMES: ClassVar[set[str]]
"""Names of the sections for method and function arguments."""

_SECTION_NAMES_WITH_ITEMS: ClassVar[set[str]]
"""Names of the sections with items."""

MISSING_ARG_DESCRIPTION: ClassVar[str] = "The description is missing."
"""Fall back description for an argument without a given description."""

def __call__(self, parent_doc: str | None, child_func: Callable[..., Any]) -> None:
"""
Expand Down Expand Up @@ -165,7 +171,7 @@ def _parse_sections(cls, docstring: str | None) -> SectionsType:
line1, line2_rstripped, reversed_section_body_lines
)
if section_name is not None and section_body is not None:
if section_name in cls._SECTION_ITEMS_NAMES:
if section_name in cls._SECTION_NAMES_WITH_ITEMS:
reversed_sections[section_name] = cls._parse_section_items(
section_body
)
Expand Down Expand Up @@ -249,7 +255,7 @@ def _inherit_sections(

# For sections with items, the sections common to parent and child are merged.
common_section_names_with_items = (
parent_section_names & child_section_names & cls._SECTION_ITEMS_NAMES
parent_section_names & child_section_names & cls._SECTION_NAMES_WITH_ITEMS
)

for section_name in common_section_names_with_items:
Expand All @@ -260,15 +266,16 @@ def _inherit_sections(
cast(Dict[str, str], child_sections[section_name])
)

if section_name in cls._ARGS_SECTION_ITEMS_NAMES:
temp_section_items = cls._inherit_section_items_with_args(
child_func,
temp_section_items,
)

temp_sections[section_name] = temp_section_items

# Order the standard sections.
# Args section shall be filtered.
for section_name in temp_sections.keys() & cls._ARGS_SECTION_NAMES:
temp_sections[section_name] = cls._filter_args_section(
child_func,
cast(Dict[str, str], temp_sections[section_name]),
)

# Reorder the standard sections.
new_child_sections = {
section_name: temp_sections.pop(section_name)
for section_name in cls._SECTION_NAMES
Expand All @@ -281,12 +288,12 @@ def _inherit_sections(
return new_child_sections

@classmethod
def _inherit_section_items_with_args(
def _filter_args_section(
cls,
func: Callable[..., Any],
section_items: dict[str, str],
) -> dict[str, str]:
"""Inherit section items for the args of a signature.
"""Filter the args section items with the args of a signature.
The argument ``self`` is removed. The arguments are ordered according to the
signature of ``func``. An argument of ``func`` missing in ``section_items`` gets
Expand Down
4 changes: 2 additions & 2 deletions src/docstring_inheritance/docstring_inheritors/google.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ class GoogleDocstringInheritor(AbstractDocstringInheritor):
)
_SECTION_NAMES[1] = "Args"

_ARGS_SECTION_ITEMS_NAMES: ClassVar[set[str]] = {"Args"}
_ARGS_SECTION_NAMES: ClassVar[set[str]] = {"Args"}

_SECTION_ITEMS_NAMES: ClassVar[set[str]] = _ARGS_SECTION_ITEMS_NAMES | {
_SECTION_NAMES_WITH_ITEMS: ClassVar[set[str]] = _ARGS_SECTION_NAMES | {
"Attributes",
"Methods",
}
Expand Down
Loading

0 comments on commit ca3e6ce

Please sign in to comment.