diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 12f9e2c..f4b9d34 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,6 +3,16 @@ Changelog Versions follow `Semantic Versioning `_ (``..``). +v1.8.1 (TBC) +------------ + +Bug Fixes +^^^^^^^^^ + +* `#273 `: + Fixed type annotations being shown for only a single module. + + v1.8.0 (2021-04-12) ------------------- diff --git a/autoapi/extension.py b/autoapi/extension.py index 54bc014..a80dbab 100644 --- a/autoapi/extension.py +++ b/autoapi/extension.py @@ -169,10 +169,6 @@ def run_autoapi(app): # pylint: disable=too-many-branches if app.config.autoapi_generate_api_docs: sphinx_mapper_obj.output_rst(root=normalized_root, source_suffix=out_suffix) - if app.config.autoapi_type == "python": - app.env.autoapi_objects = sphinx_mapper_obj.objects - app.env.autoapi_all_objects = sphinx_mapper_obj.all_objects - def build_finished(app, exception): if not app.config.autoapi_keep_files and app.config.autoapi_generate_api_docs: @@ -188,6 +184,12 @@ def build_finished(app, exception): sphinx_mapper.build_finished(app, exception) +def source_read(app, docname, source): # pylint: disable=unused-argument + # temp_data is cleared after each source file has been processed, + # so populate the annotations at the beginning of every file read. + app.env.temp_data["annotations"] = getattr(app.env, "autoapi_annotations", {}) + + def doctree_read(app, doctree): """ Inject AutoAPI into the TOC Tree dynamically. @@ -282,6 +284,7 @@ def viewcode_follow_imported(app, modname, attribute): def setup(app): app.connect("builder-inited", run_autoapi) + app.connect("source-read", source_read) app.connect("doctree-read", doctree_read) app.connect("build-finished", build_finished) if "viewcode-find-source" in app.events.events: diff --git a/autoapi/mappers/python/mapper.py b/autoapi/mappers/python/mapper.py index 57dd50c..655e5c8 100644 --- a/autoapi/mappers/python/mapper.py +++ b/autoapi/mappers/python/mapper.py @@ -340,6 +340,7 @@ class PythonSphinxMapper(SphinxMapperBase): def map(self, options=None): self._resolve_placeholders() + self.app.env.autoapi_annotations = {} super(PythonSphinxMapper, self).map(options) @@ -355,6 +356,9 @@ class PythonSphinxMapper(SphinxMapperBase): obj.submodules.sort() obj.subpackages.sort() + self.app.env.autoapi_objects = self.objects + self.app.env.autoapi_all_objects = self.all_objects + def create_class(self, data, options=None, **kwargs): """Create a class from the passed in data @@ -411,5 +415,4 @@ class PythonSphinxMapper(SphinxMapperBase): if return_annotation: obj_annotations["return"] = return_annotation - annotations = self.app.env.temp_data.setdefault("annotations", {}) - annotations[obj.id] = obj_annotations + self.app.env.autoapi_annotations[obj.id] = obj_annotations diff --git a/tests/python/pyautodoc_typehints/conf.py b/tests/python/pyautodoc_typehints/conf.py new file mode 100644 index 0000000..4d34f5a --- /dev/null +++ b/tests/python/pyautodoc_typehints/conf.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- + +templates_path = ["_templates"] +source_suffix = ".rst" +master_doc = "index" +project = u"pyexample" +copyright = u"2015, readthedocs" +author = u"readthedocs" +version = "0.1" +release = "0.1" +language = None +exclude_patterns = ["_build"] +pygments_style = "sphinx" +todo_include_todos = False +html_theme = "alabaster" +html_static_path = ["_static"] +htmlhelp_basename = "pyexampledoc" +extensions = ["sphinx.ext.autodoc", "autoapi.extension", "sphinx.ext.napoleon"] +autoapi_type = "python" +autoapi_dirs = ["example"] +autoapi_python_class_content = "both" +autoapi_options = [ + "members", + "undoc-members", # this is temporary until we add docstrings across the codebase + "show-inheritance", + "show-module-summary", + "special-members", + "imported-members", + "inherited-members", +] + +autodoc_typehints = "description" diff --git a/tests/python/pyautodoc_typehints/example/example.py b/tests/python/pyautodoc_typehints/example/example.py new file mode 100644 index 0000000..d1ffba5 --- /dev/null +++ b/tests/python/pyautodoc_typehints/example/example.py @@ -0,0 +1,7 @@ +class A: + def test(a: int) -> bool: + """Test. + Args: + a: Argument + """ + return False diff --git a/tests/python/pyautodoc_typehints/example/example2.py b/tests/python/pyautodoc_typehints/example/example2.py new file mode 100644 index 0000000..1d0dd65 --- /dev/null +++ b/tests/python/pyautodoc_typehints/example/example2.py @@ -0,0 +1,7 @@ +class B: + def test(a: int) -> bool: + """Test. + Args: + a: Argument + """ + return False diff --git a/tests/python/pyautodoc_typehints/index.rst b/tests/python/pyautodoc_typehints/index.rst new file mode 100644 index 0000000..5d8a591 --- /dev/null +++ b/tests/python/pyautodoc_typehints/index.rst @@ -0,0 +1,25 @@ +.. pyexample documentation master file, created by + sphinx-quickstart on Fri May 29 13:34:37 2015. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to pyexample's documentation! +===================================== + +.. toctree:: + + autoapi/index + +Contents: + +.. toctree:: + :maxdepth: 2 + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/tests/python/test_pyintegration.py b/tests/python/test_pyintegration.py index d9b6acd..cc8f0fd 100644 --- a/tests/python/test_pyintegration.py +++ b/tests/python/test_pyintegration.py @@ -834,3 +834,25 @@ def test_string_module_attributes(builder): " ", ] assert "\n".join(code_snippet_contents) in example_file + + +class TestAutodocTypehintsPackage: + """Test integrations with the autodoc.typehints extension.""" + + @pytest.fixture(autouse=True, scope="class") + def built(self, builder): + builder("pyautodoc_typehints") + + def test_renders_typehint(self): + example_path = "_build/text/autoapi/example/index.txt" + with io.open(example_path, encoding="utf8") as example_handle: + example_file = example_handle.read() + + assert "(*int*)" in example_file + + def test_renders_typehint_in_second_module(self): + example2_path = "_build/text/autoapi/example2/index.txt" + with io.open(example2_path, encoding="utf8") as example2_handle: + example2_file = example2_handle.read() + + assert "(*int*)" in example2_file