diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index eb7fa3ee..1c7dbd2a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,5 +1,9 @@ name: numpydoc tests +concurrency: + group: ${{ github.workflow }}-${{ github.event.number }}-${{ github.event.ref }} + cancel-in-progress: true + on: push: branches: [main] @@ -14,7 +18,21 @@ jobs: os: [Ubuntu] python-version: ["3.7", "3.8", "3.9", "3.10", "3.11-dev"] sphinx-version: - ["sphinx==4.2", "sphinx==4.5", "sphinx==5.0", "sphinx>=5.0"] + [ + "sphinx==4.2", + "sphinx==4.5", + "sphinx==5.0", + "sphinx==5.3", + "sphinx==6.0", + "sphinx>6.0", + ] + exclude: + - os: Ubuntu + python-version: "3.7" + sphinx-version: "sphinx==6.0" + - os: Ubuntu + python-version: "3.7" + sphinx-version: "sphinx>6.0" steps: - uses: actions/checkout@v3 @@ -55,6 +73,7 @@ jobs: run: | sudo apt-get update sudo apt install texlive texlive-latex-extra latexmk dvipng + pip install "sphinx<6" - name: Build documentation run: | @@ -106,6 +125,7 @@ jobs: run: | sudo apt-get update sudo apt install texlive texlive-latex-extra latexmk dvipng + pip install "sphinx<6" - name: Build documentation run: | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 611379ed..0611ae01 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.4.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -17,7 +17,7 @@ repos: - id: check-added-large-files - repo: https://github.com/psf/black - rev: 22.8.0 + rev: 23.1.0 hooks: - id: black @@ -28,13 +28,13 @@ repos: files: \.(html|md|yml|yaml) args: [--prose-wrap=preserve] - - repo: https://github.com/asottile/blacken-docs - rev: v1.12.1 + - repo: https://github.com/adamchainz/blacken-docs + rev: 1.13.0 hooks: - id: blacken-docs - repo: https://github.com/asottile/pyupgrade - rev: v2.38.2 + rev: v3.3.1 hooks: - id: pyupgrade args: [--py37-plus] diff --git a/doc/conf.py b/doc/conf.py index 560334d9..315bac73 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -81,23 +81,17 @@ html_theme = "pydata_sphinx_theme" html_theme_options = { - "github_url": "https://github.com/numpy/numpydoc", "show_prev_next": False, - "navbar_end": ["search-field.html", "navbar-icon-links.html"], + "navbar_end": ["theme-switcher", "search-field.html", "navbar-icon-links.html"], + "icon_links": [ + { + "name": "GitHub", + "url": "https://github.com/numpy/numpydoc", + "icon": "fab fa-github-square", + "type": "fontawesome", + }, + ], } -# NOTE: The following is required for supporting of older sphinx toolchains. -# The "theme-switcher" templated should be added directly to navbar_end -# above and the following lines removed when the minimum supported -# version of pydata_sphinx_theme is 0.9.0 -# Add version switcher for versions of pydata_sphinx_theme that support it -import packaging -import pydata_sphinx_theme - -if packaging.version.parse(pydata_sphinx_theme.__version__) >= packaging.version.parse( - "0.9.0" -): - html_theme_options["navbar_end"].insert(0, "theme-switcher") - html_sidebars = { "**": [], diff --git a/numpydoc/docscrape.py b/numpydoc/docscrape.py index e5c07f59..317bdab2 100644 --- a/numpydoc/docscrape.py +++ b/numpydoc/docscrape.py @@ -408,7 +408,7 @@ def _parse(self): msg = "Docstring contains a Receives section but not Yields." raise ValueError(msg) - for (section, content) in sections: + for section, content in sections: if not section.startswith(".."): section = (s.capitalize() for s in section.split(" ")) section = " ".join(section) @@ -631,7 +631,6 @@ def __init__(self, obj, doc=None, config=None): class ClassDoc(NumpyDocString): - extra_public_methods = ["__call__"] def __init__(self, cls, doc=None, modulename="", func_doc=FunctionDoc, config=None): @@ -728,7 +727,15 @@ def _is_show_member(self, name): return True -def get_doc_object(obj, what=None, doc=None, config=None): +def get_doc_object( + obj, + what=None, + doc=None, + config=None, + class_doc=ClassDoc, + func_doc=FunctionDoc, + obj_doc=ObjDoc, +): if what is None: if inspect.isclass(obj): what = "class" @@ -742,10 +749,10 @@ def get_doc_object(obj, what=None, doc=None, config=None): config = {} if what == "class": - return ClassDoc(obj, func_doc=FunctionDoc, doc=doc, config=config) + return class_doc(obj, func_doc=func_doc, doc=doc, config=config) elif what in ("function", "method"): - return FunctionDoc(obj, doc=doc, config=config) + return func_doc(obj, doc=doc, config=config) else: if doc is None: doc = pydoc.getdoc(obj) - return ObjDoc(obj, doc, config=config) + return obj_doc(obj, doc, config=config) diff --git a/numpydoc/docscrape_sphinx.py b/numpydoc/docscrape_sphinx.py index 9a62cff9..26a8e6b3 100644 --- a/numpydoc/docscrape_sphinx.py +++ b/numpydoc/docscrape_sphinx.py @@ -11,6 +11,7 @@ from sphinx.jinja2glue import BuiltinTemplateLoader from .docscrape import NumpyDocString, FunctionDoc, ClassDoc, ObjDoc +from .docscrape import get_doc_object as get_doc_object_orig from .xref import make_xref @@ -407,20 +408,10 @@ def __init__(self, obj, doc=None, config=None): ObjDoc.__init__(self, obj, doc=doc, config=config) -# TODO: refactor to use docscrape.get_doc_object def get_doc_object(obj, what=None, doc=None, config=None, builder=None): - if what is None: - if inspect.isclass(obj): - what = "class" - elif inspect.ismodule(obj): - what = "module" - elif isinstance(obj, Callable): - what = "function" - else: - what = "object" - if config is None: config = {} + template_dirs = [os.path.join(os.path.dirname(__file__), "templates")] if builder is not None: template_loader = BuiltinTemplateLoader() @@ -430,11 +421,12 @@ def get_doc_object(obj, what=None, doc=None, config=None, builder=None): template_env = SandboxedEnvironment(loader=template_loader) config["template"] = template_env.get_template("numpydoc_docstring.rst") - if what == "class": - return SphinxClassDoc(obj, func_doc=SphinxFunctionDoc, doc=doc, config=config) - elif what in ("function", "method"): - return SphinxFunctionDoc(obj, doc=doc, config=config) - else: - if doc is None: - doc = pydoc.getdoc(obj) - return SphinxObjDoc(obj, doc, config=config) + return get_doc_object_orig( + obj, + what=what, + doc=doc, + config=config, + class_doc=SphinxClassDoc, + func_doc=SphinxFunctionDoc, + obj_doc=SphinxObjDoc, + ) diff --git a/numpydoc/tests/test_docscrape.py b/numpydoc/tests/test_docscrape.py index 227f8724..73dea61d 100644 --- a/numpydoc/tests/test_docscrape.py +++ b/numpydoc/tests/test_docscrape.py @@ -1443,7 +1443,6 @@ def __set__(self, obj, value): obj._set_axis(self.axis, value) class Dummy: - attr = SpecialProperty(doc="test attribute") doc = get_doc_object(Dummy) diff --git a/numpydoc/tests/test_validate.py b/numpydoc/tests/test_validate.py index 080affab..f01cde50 100644 --- a/numpydoc/tests/test_validate.py +++ b/numpydoc/tests/test_validate.py @@ -506,12 +506,45 @@ def parameters_with_trailing_underscores(self, str_): """ pass + def parameter_with_wrong_types_as_substrings(self, a, b, c, d, e, f): + r""" + Ensure PR06 doesn't fail when non-preferable types are substrings. + + While PR06 checks for parameter types which contain non-preferable type + names like integer (int), string (str), and boolean (bool), PR06 should + not fail if those types are used only as susbtrings in, for example, + custom type names. + + Parameters + ---------- + a : Myint + Some text. + b : intClass + Some text. + c : Mystring + Some text. + d : stringClass + Some text. + e : Mybool + Some text. + f : boolClass + Some text. + + See Also + -------- + related : Something related. + + Examples + -------- + >>> result = 1 + 1 + """ + pass + class BadGenericDocStrings: """Everything here has a bad docstring""" def func(self): - """Some function. With several mistakes in the docstring. @@ -1145,6 +1178,7 @@ def test_good_class(self, capsys): "warnings", "valid_options_in_parameter_description_sets", "parameters_with_trailing_underscores", + "parameter_with_wrong_types_as_substrings", ], ) def test_good_functions(self, capsys, func): diff --git a/numpydoc/validate.py b/numpydoc/validate.py index cc058f0d..b975f831 100644 --- a/numpydoc/validate.py +++ b/numpydoc/validate.py @@ -584,7 +584,7 @@ def validate(obj_name): ("string", "str"), ] for wrong_type, right_type in common_type_errors: - if wrong_type in doc.parameter_type(param): + if wrong_type in set(re.split(r"\W", doc.parameter_type(param))): errs.append( error( "PR06", diff --git a/requirements/developer.txt b/requirements/developer.txt index db79816f..b8de207e 100644 --- a/requirements/developer.txt +++ b/requirements/developer.txt @@ -1 +1 @@ -pre-commit>=2.20 +pre-commit>=3.0