pax_global_header00006660000000000000000000000064141065201410014504gustar00rootroot0000000000000052 comment=19d217e177d76b40318a30a7cd25195d09530551 sphinx-autoapi-1.8.4/000077500000000000000000000000001410652014100144675ustar00rootroot00000000000000sphinx-autoapi-1.8.4/.github/000077500000000000000000000000001410652014100160275ustar00rootroot00000000000000sphinx-autoapi-1.8.4/.github/workflows/000077500000000000000000000000001410652014100200645ustar00rootroot00000000000000sphinx-autoapi-1.8.4/.github/workflows/main.yml000066400000000000000000000016711410652014100215400ustar00rootroot00000000000000name: tests on: [push, pull_request] jobs: test: strategy: matrix: python-version: [3.6, 3.7, 3.8, 3.9] platform: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel python -m pip install tox - name: Run tests run: tox -e py lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel python -m pip install tox - name: Lint run: tox -e formatting,lint sphinx-autoapi-1.8.4/.gitignore000066400000000000000000000003121410652014100164530ustar00rootroot00000000000000*.egg-info *.pyc *.swp .doctrees _build_rtd _build docs/autoapi readthedocs_build tests/*/autoapi tests/dotnetexample/example/Identity/ _api_ .tox .eggs .ropeproject/ .cache .pytest_cache/ build/ dist/ sphinx-autoapi-1.8.4/.pre-commit-config.yaml000066400000000000000000000005601410652014100207510ustar00rootroot00000000000000repos: - repo: https://github.com/psf/black rev: 19.10b0 hooks: - id: black language_version: python3 - repo: https://github.com/PyCQA/pylint rev: 'pylint-2.5.3' hooks: - id: pylint - repo: https://github.com/pre-commit/pre-commit-hooks rev: v3.1.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer sphinx-autoapi-1.8.4/.readthedocs.yml000066400000000000000000000007051410652014100175570ustar00rootroot00000000000000version: 2 # Build documentation in the docs/ directory with Sphinx sphinx: configuration: docs/conf.py # Build documentation with MkDocs #mkdocs: # configuration: mkdocs.yml # Optionally build your docs in additional formats such as PDF formats: - pdf # Optionally set the version of Python and requirements required to build your docs python: version: 3.8 install: - method: pip path: . extra_requirements: - docs sphinx-autoapi-1.8.4/CHANGELOG.rst000066400000000000000000000403301410652014100165100ustar00rootroot00000000000000Changelog ========= Versions follow `Semantic Versioning `_ (``..``). v1.8.4 (2021-08-16) ------------------- Bug Fixes ^^^^^^^^^ * `#301 `: (Python) Fixed compatibility with astroid 2.7+. v1.8.3 (2021-07-31) ------------------- Bug Fixes ^^^^^^^^^ * `#299 `: (Python) Fixed incorrect indentation in generated documentation when a class with no constructor has a summary line spanning multiple lines. Trivial/Internal Changes ^^^^^^^^^^^^^^^^^^^^^^^^ * Fixed broken link to Jinja objects.inv. v1.8.2 (2021-07-26) ------------------- Bug Fixes ^^^^^^^^^ * Fixed error when parsing a class with no constructor. * `#293 `: Fixed failure to build out of source conf.py files. Configuration values using relative values are now relative to the source directory instead of relative to the conf.py file. * `#289 `: (Python) Fixed AttributeError using inheritance diagrams on a module with plain imports. * `#292 `: Explicitly use the domain for generated directives. v1.8.1 (2021-04-24) ------------------- Bug Fixes ^^^^^^^^^ * `#273 `: Fixed type annotations being shown for only a single module. v1.8.0 (2021-04-12) ------------------- Features ^^^^^^^^ * Expandable value for multi-line string attributes. * `#265 `: Can resolve the qualified paths of parameters to generics. * `#275 `: Warnings have been categorised and can be suppressed through ``suppress_warnings``. * `#280 `: Data attributes are documentated in module summaries. Bug Fixes ^^^^^^^^^ * `#273 `: Fixed setting ``autodoc_typehints`` to ``none`` or ``description`` not turning off signature type hints. ``autodoc_typehints`` integration is consisidered experimental until the extension properly supports overload functions. * `#261 `: Fixed data annotations causing pickle or deepcopy errors. * Documentation can be generated when multiple source directories share a single ``conf.py`` file. Trivial/Internal Changes ^^^^^^^^^^^^^^^^^^^^^^^^ * Fixed ``DeprecationWarning`` for invalid escape sequence ``\s`` in tests. * Fixed ``FutureWarning`` for ``Node.traverse()`` becoming an iterator instead of list. * New example implementation of ``autoapi-skip-member`` Sphinx event. * Can run tests with tox 4. * Updated packaging to use PEP-517. * All unittest style tests have been converted to pytest style tests. * An exception raised by docfx is raised directly instead of wrapping it. * Started using Github Actions for continuous integration. V1.7.0 (2021-01-31) ------------------- Features ^^^^^^^^ * The fully qualified path of objects are included type annotations so that Sphinx can link to them. * Added support for Sphinx 3.3. and 3.4. * `#240 `: The docstrings of ``object.__init__``, ``object.__new__``, ``type.__init__``, and ``type.__new__`` are not inherited. Bug Fixes ^^^^^^^^^ * `#260 `: The overload signatures of ``__init__`` methods are documented. V1.6.0 (2021-01-20) ------------------- Breaking Changes ^^^^^^^^^^^^^^^^ * Dropped support for Python 2 and Sphinx 1.x/2.x. Python 2 source code can still be parsed. Features ^^^^^^^^ * (Python) Added support for using type hints as parameter types and return types via the ``sphinx.ext.autodoc.typehints`` extension. * `#191 `: Basic incremental build support is enabled ``autoapi_keep_files`` is enabled. Providing none of the source files have changed, AutoAPI will skip parsing the source code and regenerating the API documentation. * `#200 `: Can pass a callback that edits the Jinja Environment object before template rendering begins. This allows custom filters, tests, and globals to be added to the environment. * Added support for Python 3.9. Bug Fixes ^^^^^^^^^ * `#246 `: (Python) Fixed TypeError when parsing a class that inherits from ``type``. * `#244 `: Fixed an unnecessary deprecation warning being raised when running sphinx-build from the same directory as conf.py. * (Python) Fixed properties documented by Autodoc directives geting documented as methods. V1.5.1 (2020-10-01) ------------------- Bug Fixes ^^^^^^^^^ * Fixed AttributeError when generating an inheritance diagram for a module. V1.5.0 (2020-08-31) ------------------- This will be the last minor version to support Python 2 and Sphinx 1.x/2.x. Features ^^^^^^^^ * `#222 `: Declare the extension as parallel unsafe. * `#217 `: (Python) All overload signatures are documented. * `#243 `: Files are found in order of preference according to ``autoapi_file_patterns``. * Added support for Sphinx 3.2. Bug Fixes ^^^^^^^^^ * `#219 `: (Python) Fixed return types not showing for methods. * (Python) Fixed incorrect formatting of properties on generated method directives. * Fixed every toctree entry getting added as a new list. * `#234 `: Fixed only some entries getting added to the toctree. Trivial/Internal Changes ^^^^^^^^^^^^^^^^^^^^^^^^ * autoapisummary directive inherits from autosummary for future stability. v1.4.0 (2020-06-07) ------------------- Features ^^^^^^^^ * `#197 `: Added ``autoapi.__version__`` and ``autoapi.__version_info__`` attributes for accessing version information. * `#201 `: (Python) Added the ``autoapi_member_order`` option to allow the order that members are documentated to be configurable. * `#203 `: (Python) A class without a docstring inherits one from its parent. A methods without a docstring inherits one from the method that it overrides. * `#204 `: (Python) Added the ``imported-members`` AutoAPI option to be able to enable or disable documenting objects imported from the same top-level package or module without needing to override templates. Bug Fixes ^^^^^^^^^ * `#198 `: Documentation describes the required layout for template override directories. * `#195 `: (Python) Fixed incorrect formatting when ``show-inheritance-diagram`` and ``private-members`` are turned on. * `#193 ` and `#208 `: (Python) Inheritance diagrams can follow imports to find classes to document. * `#213 `: (Python) Fixed module summary never showing. Trivial/Internal Changes ^^^^^^^^^^^^^^^^^^^^^^^^ * black shows diffs by default * `#207 `: Fixed a typo in the code of the golang tutorial. v1.3.0 (2020-04-05) ------------------- Breaking Changes ^^^^^^^^^^^^^^^^ * Dropped support for Python 3.4 and 3.5. Features ^^^^^^^^ * `#151 `: (Python) Added the ``autoapi_python_use_implicit_namespaces`` option to allow AutoAPI to search for implicit namespace packages. * Added support for Sphinx 2.2 and 2.3. * Added support for Python 3.8. * `#140 `: (Python) Added the ``autoapi-inheritance-diagram`` directive to create inheritance diagrams without importing modules. Enable the ``show-inheritance-diagram`` AutoAPI option to turn the diagrams on in generated documentation. * `#183 `: (Python) Added the ``show-inheritance`` AutoAPI option to be able to enable or disable the display of a list of base classes in generated documentation about a class. Added the ``inherited-members`` AutoAPI option to be able to enable or disable the display of members inherited from a base class in generated documentation about a class. * The ``autoapi_include_summaries`` option has been replaced with the ``show-module-summary`` AutoAPI option. ``autoapi_include_summaries`` will stop working in the next major version. * Added support for Sphinx 2.4 and 3.0 Bug Fixes ^^^^^^^^^ * `#186 `: (Python) Fixed an exception when there are too many argument type annotations in a type comment. * (Python) args and kwargs type annotations can be read from the function type comment. Trivial/Internal Changes ^^^^^^^^^^^^^^^^^^^^^^^^ * Tests are now included in the sdist. v1.2.1 (2019-10-09) ------------------- Bug Fixes ^^^^^^^^^ * (Python) "Invalid desc node" warning no longer raised for autodoc-style directives. v1.2.0 (2019-10-05) ------------------- Features ^^^^^^^^ * (Python) Can read per argument type comments with astroid > 2.2.5. * (Python) Added autoapidecorator directive with Sphinx >= 2.0. * (Python) Can use autodoc_docstring_signature with Autodoc-style directives. * (Python) Added autoapi-skip-member event. * Made it more clear which file causes an error, when an error occurs. * Sphinx language domains are now optional dependencies. Bug Fixes ^^^^^^^^^ * (Python) Forward reference annotations are no longer rendered as strings. * (Python) autoapifunction directive no longer documents async functions as a normal function. * (Python) Fixed unicode decode errors in some Python 3 situations. * Documentation more accurately describes what configuration accepts relative paths and where they are relative to. v1.1.0 (2019-06-23) ------------------- Features ^^^^^^^^ * (Python) Can override ignoring local imports in modules by using __all__. Bug Fixes ^^^^^^^^^ * (Python) Fixed incorrect formatting of functions and methods. * Added support for Sphinx 2.1. Trivial/Internal Changes ^^^^^^^^^^^^^^^^^^^^^^^^ * Fixed some dead links in the README. * Fixed lint virtualenv. v1.0.0 (2019-04-24) ------------------- Features ^^^^^^^^ * `#100 `: (Python) Added support for documenting C extensions via ``.pyi`` stub files. * Added support for Sphinx 2.0. * Toned down the API reference index page. * (Go) Patterns configured in ``autoapi_ignore`` are passed to godocjson. * New and improved documentation. * No longer need to set ``autoapi_add_toctree_entry`` to False when ``autoapi_generate_api_docs`` is False. * `#139 ` Added support for basic type annotations in documentation generation and autodoc-style directives. Bug Fixes ^^^^^^^^^ * `#159 `: (Python) Fixed ``UnicodeDecodeError`` on Python 2 when a documenting an attribute that contains binary data. * (Python) Fixed private submodules displaying when ``private-members`` is turned off. * Templates no longer produce excessive whitespace. * (Python) Fixed an error when giving an invalid object to an autodoc-style directive. Trivial/Internal Changes ^^^^^^^^^^^^^^^^^^^^^^^^ * No longer pin the version of black. * Added missing test environments to travis. v0.7.1 (2019-02-04) ------------------- Bug Fixes ^^^^^^^^^ * (Python) Fixed a false warning when importing a local module. v0.7.0 (2019-01-30) ------------------- Breaking Changes ^^^^^^^^^^^^^^^^ * Dropped support for Sphinx<1.6. Features ^^^^^^^^ * Added debug messages about what AutoAPI is doing. Bug Fixes ^^^^^^^^^ * `#156 `: (Python) Made import resolution more stable. Also capable of giving more detailed warnings. Trivial/Internal Changes ^^^^^^^^^^^^^^^^^^^^^^^^ * Code is now formatted using black. * Removed references to old css and js files. * Replaced usage of deprecated Sphinx features. * Reorganised tests to be more pytest-like. v0.6.2 (2018-11-15) ------------------- Bug Fixes ^^^^^^^^^ * (Python) Fixed some import chains failing to resolve depending on resolution order. v0.6.1 (2018-11-14) ------------------- Bug Fixes ^^^^^^^^^ * (Python) Fixed unicode decoding on Python 3.7. * (Python) Fixed autodoc directives not documenting anything in submodules or subpackages. * (Python) Fixed error parsing files with unicode docstrings. * (Python) Fixed error when documenting something that's imported in more than one place. Trivial/Internal Changes ^^^^^^^^^^^^^^^^^^^^^^^^ * (Python) Added Python 3.7 testing. * Started testing against stable version of Sphinx 1.8. * Fixed all "no title" warnings during tests. v0.6.0 (2018-08-20) ------------------- Breaking Changes ^^^^^^^^^^^^^^^^ * `#152 `: Removed the ``autoapi_add_api_root_toctree`` option. This has been replaced with the ``autoapi_add_toctree_entry`` option. * `#25 `: Removed distutils support. * Removed redundant ``package_dir`` and ``package_data`` options. Features ^^^^^^^^ * (Python) Added viewcode support for imported members. * `#146 `: (Python) No longer documents ``__init__()`` attributes without a docstring. * `#153 `: (Python) Can document a public python API. * `#111 `: (Python) Can opt to write manual documentation through new autodoc-style directives. * `#152 `: Made it easier to remove default index page. Also removed autoapi_add_api_root_toctree config option * `#150 `: (Python) ``private-members`` also controls private subpackages and submodules. * (Python) Added support for static and class methods. * (Python) Methods include ``self`` in their arguments. This more closely matches autodoc behaviour. * `#145 `: (Python) Added support for detecting Python exceptions. * (Python) Can control how __init__ docstring is displayed. * (Python) Added support for viewcode. * (Python) Source files no longer need to be in ``sys.path``. Bug Fixes ^^^^^^^^^ * (Python) Fixed linking to builtin bases. * (Python) Fixed properties being documented more than once when set in ``__init__()``. * (Python) Fixed nested classes not getting displayed. * `#148 `: (Python) Fixed astroid 2.0 compatibility. * (Python) Fixed filtered classes and attributes getting displayed. * (Python) Fixed incorrect display of long lists. * `#125 `: (Javacript) Fixed running incorrect jsdoc command on Windows. * `#125 `: (Python) Support specifying package directories in ``autoapi_dirs``. Trivial/Internal Changes ^^^^^^^^^^^^^^^^^^^^^^^^ * Added Sphinx 1.7 and 1.8.0b1 testing. * `#120 `: Updated documentation to remove outdated references. * Removed old testing dependencies. * `#143 `: Removed unnecessary wheel dependency. sphinx-autoapi-1.8.4/LICENSE.rst000066400000000000000000000021241410652014100163020ustar00rootroot00000000000000The MIT License (MIT) ===================== Copyright (c) 2015 Read the Docs, Inc Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. sphinx-autoapi-1.8.4/MANIFEST.in000066400000000000000000000001341410652014100162230ustar00rootroot00000000000000recursive-include autoapi *.rst include *.rst include LICENSE.mit recursive-include tests * sphinx-autoapi-1.8.4/README.rst000066400000000000000000000102071410652014100161560ustar00rootroot00000000000000Sphinx AutoAPI ============== .. image:: https://readthedocs.org/projects/sphinx-autoapi/badge/?version=latest :target: https://sphinx-autoapi.readthedocs.org :alt: Documentation .. image:: https://github.com/readthedocs/sphinx-autoapi/actions/workflows/main.yml/badge.svg?branch=master :target: https://github.com/readthedocs/sphinx-autoapi/actions/workflows/main.yml?query=branch%3Amaster :alt: Github Build Status .. image:: https://img.shields.io/pypi/v/sphinx-autoapi.svg :target: https://pypi.org/project/sphinx-autoapi/ :alt: PyPI Version .. image:: https://img.shields.io/pypi/pyversions/sphinx-autoapi.svg :target: https://pypi.org/project/sphinx-autoapi/ :alt: Supported Python Versions .. image:: https://img.shields.io/badge/code%20style-black-000000.svg :target: https://github.com/python/black :alt: Formatted with Black Sphinx AutoAPI provides "autodoc" style documentation for multiple programming languages without needing to load, run, or import the project being documented. In contrast to the traditional `Sphinx autodoc `_, which is Python-only and uses code imports, AutoAPI finds and generates documentation by parsing source code. Language Support ---------------- ========== ====== ========================================================== Language Status Parser ========== ====== ========================================================== Python Stable Custom using `astroid `_ Go Alpha `godocjson `_ Javascript Alpha `jsdoc `_ .NET Alpha `docfx `_ ========== ====== ========================================================== Getting Started --------------- The following steps will walk through how to add AutoAPI to an existing Sphinx project. For instructions on how to set up a Sphinx project, see Sphinx's documentation on `Getting Started `_. Installation ~~~~~~~~~~~~ AutoAPI can be installed through pip: .. code-block:: bash pip install sphinx-autoapi Next, add and configure AutoAPI in your Sphinx project's `conf.py`. Other languages may require `further configuration `_: .. code-block:: python extensions.append('autoapi.extension') autoapi_type = 'python' autoapi_dirs = ['path/to/source/files', 'src'] Where `autoapi_type` can be one of any of the supported languages: ========== ================ Language ``autoapi_type`` ========== ================ Python ``'python'`` Go ``'go'`` Javascript ``'javascript'`` .NET ``'dotnet'`` ========== ================ When the documentation is built, AutoAPI will now generate API documentation into an `autoapi/` directory and add an entry to the documentation in your top level table of contents! To configure AutoAPI behaviour further, see the `Configuration documentation `_. Contributing ------------ Running the tests ~~~~~~~~~~~~~~~~~ Tests are executed through `tox `_. .. code-block:: bash tox Code Style ~~~~~~~~~~ Code is formatted using `black `_. You can check your formatting using black's check mode: .. code-block:: bash tox -e formatting You can also get black to format your changes for you: .. code-block:: bash black autoapi/ tests/ You can even get black to format changes automatically when you commit using `pre-commit `_: .. code-block:: bash pip install pre-commit pre-commit install Versioning ---------- We use `SemVer `_ for versioning. For the versions available, see the `tags on this repository `_. License ------- This project is licensed under the MIT License. See the `LICENSE.rst `_ file for details. sphinx-autoapi-1.8.4/autoapi/000077500000000000000000000000001410652014100161315ustar00rootroot00000000000000sphinx-autoapi-1.8.4/autoapi/__init__.py000066400000000000000000000001501410652014100202360ustar00rootroot00000000000000"""Sphinx AutoAPI""" from .extension import setup __version__ = "1.8.4" __version_info__ = (1, 8, 4) sphinx-autoapi-1.8.4/autoapi/backends.py000066400000000000000000000017161410652014100202620ustar00rootroot00000000000000from .mappers import ( DotNetSphinxMapper, PythonSphinxMapper, GoSphinxMapper, JavaScriptSphinxMapper, ) DEFAULT_FILE_PATTERNS = { "python": ["*.py", "*.pyi"], "dotnet": ["project.json", "*.csproj", "*.vbproj"], "go": ["*.go"], "javascript": ["*.js"], } DEFAULT_IGNORE_PATTERNS = { "dotnet": ["*toc.yml", "*index.yml"], "python": ["*migrations*"], "go": ["_test.go"], } LANGUAGE_MAPPERS = { "python": PythonSphinxMapper, "dotnet": DotNetSphinxMapper, "go": GoSphinxMapper, "javascript": JavaScriptSphinxMapper, } #: describes backend requirements in form #: {'backend name': (('1st package name in pypi', '1st package import name'), ...)} LANGUAGE_REQUIREMENTS = { "python": (), "javascript": (), "go": (("sphinxcontrib-golangdomain", "sphinxcontrib.golangdomain"),), "dotnet": (("sphinxcontrib-dotnetdomain", "sphinxcontrib.dotnetdomain"),), } # type: Dict[str, Sequence[Tuple[str, str]]] sphinx-autoapi-1.8.4/autoapi/directives.py000066400000000000000000000036021410652014100206450ustar00rootroot00000000000000"""AutoAPI directives""" from docutils.parsers.rst import Directive from docutils import nodes from sphinx.ext.autosummary import Autosummary from sphinx.util.nodes import nested_parse_with_titles from .mappers.python.objects import PythonFunction class AutoapiSummary(Autosummary): # pylint: disable=too-few-public-methods """A version of autosummary that uses static analysis.""" def get_items(self, names): items = [] env = self.state.document.settings.env all_objects = env.autoapi_all_objects for name in names: obj = all_objects[name] if isinstance(obj, PythonFunction): if obj.overloads: sig = "(\u2026)" else: sig = "({})".format(obj.args) if obj.return_annotation is not None: sig += " \u2192 {}".format(obj.return_annotation) else: sig = "" item = (obj.short_name, sig, obj.summary, obj.id) items.append(item) return items class NestedParse(Directive): # pylint: disable=too-few-public-methods """Nested parsing to remove the first heading of included rST This is used to handle the case where we like to remove user supplied headings from module docstrings. This is required to reduce the number of duplicate headings on sections. """ has_content = 1 required_arguments = 0 optional_arguments = 0 final_argument_whitespace = False option_spec = {} def run(self): node = nodes.container() node.document = self.state.document nested_parse_with_titles(self.state, self.content, node) try: title_node = node[0][0] if isinstance(title_node, nodes.title): del node[0][0] except IndexError: pass return node.children sphinx-autoapi-1.8.4/autoapi/documenters.py000066400000000000000000000233321410652014100210360ustar00rootroot00000000000000import re from sphinx.ext import autodoc from .mappers.python import ( PythonFunction, PythonClass, PythonMethod, PythonData, PythonAttribute, PythonException, ) # pylint: disable=attribute-defined-outside-init,no-self-use,unused-argument class AutoapiDocumenter(autodoc.Documenter): def get_attr(self, obj, name, *defargs): attrgetters = self.env.app.registry.autodoc_attrgettrs for type_, func in attrgetters.items(): if isinstance(obj, type_): return func(obj, name, *defargs) if name == "__doc__": return obj.docstring for child in obj.children: if child.name == name: return child if defargs: return defargs[0] raise AttributeError(name) def import_object(self): max_splits = self.fullname.count(".") for num_splits in range(max_splits, -1, -1): path_stack = list(reversed(self.fullname.rsplit(".", num_splits))) objects = self.env.autoapi_objects parent = None current = objects.get(path_stack.pop()) while current and path_stack: parent = current current = self.get_attr(current, path_stack.pop(), None) if current: self.object = current self.object_name = current.name self._method_parent = parent return True return False def get_real_modname(self): # Return a fake modname so that nothing can be imported return None def get_doc(self, encoding=None, ignore=1): return [self.object.docstring.splitlines()] def process_doc(self, docstrings): for docstring in docstrings: for line in docstring: yield line yield "" def get_object_members(self, want_all): children = ((child.name, child) for child in self.object.children) if not want_all: if not self.options.members: return False, [] children = (child for child in children if child[0] in self.options.members) elif not self.options.inherited_members: children = (child for child in children if not child[1].inherited) return False, sorted(children) class _AutoapiDocstringSignatureMixin: # pylint: disable=too-few-public-methods def format_signature(self, **kwargs): # Set "manual" attributes at the last possible moment. # This is to let a manual entry or docstring searching happen first, # and falling back to the discovered signature only when necessary. if self.args is None: self.args = self.object.args if self.retann is None: self.retann = self.object.return_annotation return super(_AutoapiDocstringSignatureMixin, self).format_signature(**kwargs) class AutoapiFunctionDocumenter( AutoapiDocumenter, autodoc.FunctionDocumenter, _AutoapiDocstringSignatureMixin ): objtype = "apifunction" directivetype = "function" # Always prefer AutoapiDocumenters priority = autodoc.FunctionDocumenter.priority * 100 + 100 @classmethod def can_document_member(cls, member, membername, isattr, parent): return isinstance(member, PythonFunction) def format_args(self, **kwargs): return "(" + self.object.args + ")" def add_directive_header(self, sig): autodoc.Documenter.add_directive_header(self, sig) if "async" in self.object.properties: sourcename = self.get_sourcename() self.add_line(" :async:", sourcename) class AutoapiDecoratorDocumenter( AutoapiFunctionDocumenter, AutoapiDocumenter, autodoc.DecoratorDocumenter ): objtype = "apidecorator" directivetype = "decorator" priority = autodoc.DecoratorDocumenter.priority * 100 + 100 def format_signature(self, **kwargs): if self.args is None: self.args = self.format_args(**kwargs) return super(AutoapiDecoratorDocumenter, self).format_signature(**kwargs) def format_args(self, **kwargs): to_format = self.object.args if re.match(r"func\W", to_format) or to_format == "func": if "," not in to_format: return None # We need to do better stripping here. # An annotation with a comma will mess this up. to_format = self.object.args.split(",", 1)[1] return "(" + to_format + ")" class AutoapiClassDocumenter( AutoapiDocumenter, autodoc.ClassDocumenter, _AutoapiDocstringSignatureMixin ): objtype = "apiclass" directivetype = "class" doc_as_attr = False priority = autodoc.ClassDocumenter.priority * 100 + 100 @classmethod def can_document_member(cls, member, membername, isattr, parent): return isinstance(member, PythonClass) def format_args(self, **kwargs): return "(" + self.object.args + ")" def add_directive_header(self, sig): autodoc.Documenter.add_directive_header(self, sig) if self.options.show_inheritance: sourcename = self.get_sourcename() self.add_line(u"", sourcename) # TODO: Change sphinx to allow overriding of getting base names if self.object.bases: bases = [":class:`{}`".format(base) for base in self.object.bases] self.add_line(" " + "Bases: {}".format(", ".join(bases)), sourcename) class AutoapiMethodDocumenter( AutoapiDocumenter, autodoc.MethodDocumenter, _AutoapiDocstringSignatureMixin ): objtype = "apimethod" directivetype = "method" priority = autodoc.MethodDocumenter.priority * 100 + 100 @classmethod def can_document_member(cls, member, membername, isattr, parent): return isinstance(member, PythonMethod) def format_args(self, **kwargs): return "(" + self.object.args + ")" def import_object(self): result = super(AutoapiMethodDocumenter, self).import_object() if result: self.parent = self._method_parent if self.object.method_type != "method": # document class and static members before ordinary ones self.member_order = self.member_order - 1 return result def add_directive_header(self, sig): autodoc.Documenter.add_directive_header(self, sig) sourcename = self.get_sourcename() for property_type in ( "abstractmethod", "async", "classmethod", "staticmethod", ): if property_type in self.object.properties: self.add_line(" :{}:".format(property_type), sourcename) class AutoapiPropertyDocumenter( AutoapiMethodDocumenter, AutoapiDocumenter, autodoc.PropertyDocumenter ): objtype = "apiproperty" directivetype = "method" # Always prefer AutoapiDocumenters priority = autodoc.MethodDocumenter.priority * 100 + 100 + 1 @classmethod def can_document_member(cls, member, membername, isattr, parent): return isinstance(member, PythonMethod) and "property" in member.properties def add_directive_header(self, sig): super(AutoapiPropertyDocumenter, self).add_directive_header(sig) sourcename = self.get_sourcename() self.add_line(" :property:", sourcename) class AutoapiDataDocumenter(AutoapiDocumenter, autodoc.DataDocumenter): objtype = "apidata" directivetype = "data" priority = autodoc.DataDocumenter.priority * 100 + 100 @classmethod def can_document_member(cls, member, membername, isattr, parent): return isinstance(member, PythonData) def add_directive_header(self, sig): autodoc.ModuleLevelDocumenter.add_directive_header(self, sig) sourcename = self.get_sourcename() if not self.options.annotation: # TODO: Change sphinx to allow overriding of object description if self.object.value is not None: self.add_line( " :annotation: = {}".format(self.object.value), sourcename ) elif self.options.annotation is autodoc.SUPPRESS: pass else: self.add_line(" :annotation: %s" % self.options.annotation, sourcename) class AutoapiAttributeDocumenter(AutoapiDocumenter, autodoc.AttributeDocumenter): objtype = "apiattribute" directivetype = "attribute" _datadescriptor = True priority = autodoc.AttributeDocumenter.priority * 100 + 100 @classmethod def can_document_member(cls, member, membername, isattr, parent): return isinstance(member, PythonAttribute) def add_directive_header(self, sig): autodoc.ClassLevelDocumenter.add_directive_header(self, sig) sourcename = self.get_sourcename() if not self.options.annotation: # TODO: Change sphinx to allow overriding of object description if self.object.value is not None: self.add_line( " :annotation: = {}".format(self.object.value), sourcename ) elif self.options.annotation is autodoc.SUPPRESS: pass else: self.add_line(" :annotation: %s" % self.options.annotation, sourcename) class AutoapiModuleDocumenter(AutoapiDocumenter, autodoc.ModuleDocumenter): objtype = "apimodule" directivetype = "module" priority = autodoc.ModuleDocumenter.priority * 100 + 100 class AutoapiExceptionDocumenter( AutoapiClassDocumenter, AutoapiDocumenter, autodoc.ExceptionDocumenter ): objtype = "apiexception" directivetype = "exception" priority = autodoc.ExceptionDocumenter.priority * 100 + 100 @classmethod def can_document_member(cls, member, membername, isattr, parent): return isinstance(member, PythonException) sphinx-autoapi-1.8.4/autoapi/extension.py000066400000000000000000000272371410652014100205320ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Sphinx Auto-API Top-level Extension. This extension allows you to automagically generate API documentation from your project. """ import io import os import shutil import sys import warnings import sphinx from sphinx.util.console import darkgreen, bold from sphinx.addnodes import toctree from sphinx.errors import ExtensionError import sphinx.util.logging from docutils.parsers.rst import directives from . import documenters from .backends import ( DEFAULT_FILE_PATTERNS, DEFAULT_IGNORE_PATTERNS, LANGUAGE_MAPPERS, LANGUAGE_REQUIREMENTS, ) from .directives import AutoapiSummary, NestedParse from .inheritance_diagrams import AutoapiInheritanceDiagram from .settings import API_ROOT from .toctree import add_domain_to_toctree LOGGER = sphinx.util.logging.getLogger(__name__) _DEFAULT_OPTIONS = [ "members", "undoc-members", "private-members", "show-inheritance", "show-module-summary", "special-members", "imported-members", ] _VIEWCODE_CACHE = {} """Caches a module's parse results for use in viewcode. :type: dict(str, tuple) """ class RemovedInAutoAPI2Warning(DeprecationWarning): """Indicates something that will be removed in sphinx-autoapi v2.""" if "PYTHONWARNINGS" not in os.environ: warnings.filterwarnings("default", category=RemovedInAutoAPI2Warning) def _normalise_autoapi_dirs(autoapi_dirs, srcdir): normalised_dirs = [] if isinstance(autoapi_dirs, str): autoapi_dirs = [autoapi_dirs] for path in autoapi_dirs: if os.path.isabs(path): normalised_dirs.append(path) else: normalised_dirs.append(os.path.normpath(os.path.join(srcdir, path))) return normalised_dirs def run_autoapi(app): # pylint: disable=too-many-branches """ Load AutoAPI data from the filesystem. """ if app.config.autoapi_type not in LANGUAGE_MAPPERS: raise ExtensionError( "Invalid autoapi_type setting, " "following values is allowed: {}".format( ", ".join( '"{}"'.format(api_type) for api_type in sorted(LANGUAGE_MAPPERS) ) ) ) if not app.config.autoapi_dirs: raise ExtensionError("You must configure an autoapi_dirs setting") if app.config.autoapi_include_summaries is not None: warnings.warn( "autoapi_include_summaries has been replaced by " "the show-module-summary AutoAPI option\n", RemovedInAutoAPI2Warning, ) if app.config.autoapi_include_summaries: app.config.autoapi_options.append("show-module-summary") # Make sure the paths are full normalised_dirs = _normalise_autoapi_dirs(app.config.autoapi_dirs, app.srcdir) for _dir in normalised_dirs: if not os.path.exists(_dir): raise ExtensionError( "AutoAPI Directory `{dir}` not found. " "Please check your `autoapi_dirs` setting.".format(dir=_dir) ) normalized_root = os.path.normpath( os.path.join(app.srcdir, app.config.autoapi_root) ) url_root = os.path.join("/", app.config.autoapi_root) if not all( import_name in sys.modules for _, import_name in LANGUAGE_REQUIREMENTS[app.config.autoapi_type] ): raise ExtensionError( "AutoAPI of type `{type}` requires following " "packages to be installed and included in extensions list: " "{packages}".format( type=app.config.autoapi_type, packages=", ".join( '{import_name} (available as "{pkg_name}" on PyPI)'.format( pkg_name=pkg_name, import_name=import_name ) for pkg_name, import_name in LANGUAGE_REQUIREMENTS[ app.config.autoapi_type ] ), ) ) sphinx_mapper = LANGUAGE_MAPPERS[app.config.autoapi_type] template_dir = app.config.autoapi_template_dir if template_dir and not os.path.isabs(template_dir): if not os.path.isdir(template_dir): template_dir = os.path.join(app.srcdir, app.config.autoapi_template_dir) elif app.srcdir != os.getcwd(): warnings.warn( "autoapi_template_dir will be expected to be " "relative to the Sphinx source directory instead of " "relative to where sphinx-build is run\n", RemovedInAutoAPI2Warning, ) sphinx_mapper_obj = sphinx_mapper(app, template_dir=template_dir, url_root=url_root) if app.config.autoapi_file_patterns: file_patterns = app.config.autoapi_file_patterns else: file_patterns = DEFAULT_FILE_PATTERNS.get(app.config.autoapi_type, []) if app.config.autoapi_ignore: ignore_patterns = app.config.autoapi_ignore else: ignore_patterns = DEFAULT_IGNORE_PATTERNS.get(app.config.autoapi_type, []) if ".rst" in app.config.source_suffix: out_suffix = ".rst" elif ".txt" in app.config.source_suffix: out_suffix = ".txt" else: # Fallback to first suffix listed out_suffix = app.config.source_suffix[0] if sphinx_mapper_obj.load( patterns=file_patterns, dirs=normalised_dirs, ignore=ignore_patterns ): sphinx_mapper_obj.map(options=app.config.autoapi_options) if app.config.autoapi_generate_api_docs: sphinx_mapper_obj.output_rst(root=normalized_root, source_suffix=out_suffix) def build_finished(app, exception): if not app.config.autoapi_keep_files and app.config.autoapi_generate_api_docs: normalized_root = os.path.normpath( os.path.join(app.srcdir, app.config.autoapi_root) ) if app.verbosity > 1: LOGGER.info(bold("[AutoAPI] ") + darkgreen("Cleaning generated .rst files")) shutil.rmtree(normalized_root) sphinx_mapper = LANGUAGE_MAPPERS[app.config.autoapi_type] if hasattr(sphinx_mapper, "build_finished"): 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. """ add_domain_to_toctree(app, doctree, app.env.docname) if app.env.docname == "index": all_docs = set() insert = True nodes = list(doctree.traverse(toctree)) toc_entry = "%s/index" % app.config.autoapi_root add_entry = ( nodes and app.config.autoapi_generate_api_docs and app.config.autoapi_add_toctree_entry ) if not add_entry: return # Capture all existing toctree entries for node in nodes: for entry in node["entries"]: all_docs.add(entry[1]) # Don't insert autoapi it's already present for doc in all_docs: if doc.find(app.config.autoapi_root) != -1: insert = False if insert and app.config.autoapi_add_toctree_entry: # Insert AutoAPI index nodes[-1]["entries"].append((None, u"%s/index" % app.config.autoapi_root)) nodes[-1]["includefiles"].append(u"%s/index" % app.config.autoapi_root) message_prefix = bold("[AutoAPI] ") message = darkgreen( "Adding AutoAPI TOCTree [{0}] to index.rst".format(toc_entry) ) LOGGER.info(message_prefix + message) def viewcode_find(app, modname): objects = app.env.autoapi_objects if modname not in objects: return None if modname in _VIEWCODE_CACHE: return _VIEWCODE_CACHE[modname] locations = {} module = objects[modname] for child in module.children: stack = [("", child)] while stack: prefix, obj = stack.pop() type_ = "other" if obj.type == "class": type_ = "class" elif obj.type in ("function", "method"): type_ = "def" full_name = prefix + obj.name if "from_line_no" in obj.obj: locations[full_name] = ( type_, obj.obj["from_line_no"], obj.obj["to_line_no"], ) children = getattr(obj, "children", ()) stack.extend((full_name + ".", gchild) for gchild in children) if module.obj["encoding"]: source = io.open( module.obj["file_path"], encoding=module.obj["encoding"] ).read() else: source = open(module.obj["file_path"]).read() result = (source, locations) _VIEWCODE_CACHE[modname] = result return result def viewcode_follow_imported(app, modname, attribute): fullname = "{}.{}".format(modname, attribute) all_objects = app.env.autoapi_all_objects if fullname not in all_objects: return None orig_path = all_objects[fullname].obj.get("original_path", "") if orig_path.endswith(attribute): return orig_path[: -len(attribute) - 1] return modname 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: app.connect("viewcode-find-source", viewcode_find) if "viewcode-follow-imported" in app.events.events: app.connect("viewcode-follow-imported", viewcode_follow_imported) app.add_config_value("autoapi_type", "python", "html") app.add_config_value("autoapi_root", API_ROOT, "html") app.add_config_value("autoapi_ignore", [], "html") app.add_config_value("autoapi_options", _DEFAULT_OPTIONS, "html") app.add_config_value("autoapi_member_order", "bysource", "html") app.add_config_value("autoapi_file_patterns", None, "html") app.add_config_value("autoapi_dirs", [], "html") app.add_config_value("autoapi_keep_files", False, "html") app.add_config_value("autoapi_add_toctree_entry", True, "html") app.add_config_value("autoapi_template_dir", None, "html") app.add_config_value("autoapi_include_summaries", None, "html") app.add_config_value("autoapi_python_use_implicit_namespaces", False, "html") app.add_config_value("autoapi_python_class_content", "class", "html") app.add_config_value("autoapi_generate_api_docs", True, "html") app.add_config_value("autoapi_prepare_jinja_env", None, "html") app.add_autodocumenter(documenters.AutoapiFunctionDocumenter) app.add_autodocumenter(documenters.AutoapiPropertyDocumenter) app.add_autodocumenter(documenters.AutoapiDecoratorDocumenter) app.add_autodocumenter(documenters.AutoapiClassDocumenter) app.add_autodocumenter(documenters.AutoapiMethodDocumenter) app.add_autodocumenter(documenters.AutoapiDataDocumenter) app.add_autodocumenter(documenters.AutoapiAttributeDocumenter) app.add_autodocumenter(documenters.AutoapiModuleDocumenter) app.add_autodocumenter(documenters.AutoapiExceptionDocumenter) directives.register_directive("autoapi-nested-parse", NestedParse) directives.register_directive("autoapisummary", AutoapiSummary) app.setup_extension("sphinx.ext.autosummary") app.add_event("autoapi-skip-member") app.setup_extension("sphinx.ext.inheritance_diagram") app.add_directive("autoapi-inheritance-diagram", AutoapiInheritanceDiagram) return { "parallel_read_safe": False, "parallel_write_safe": True, } sphinx-autoapi-1.8.4/autoapi/inheritance_diagrams.py000066400000000000000000000104501410652014100226430ustar00rootroot00000000000000import astroid import sphinx.ext.inheritance_diagram def _do_import_class(name, currmodule=None): path_stack = list(reversed(name.split("."))) if not currmodule: currmodule = path_stack.pop() try: target = astroid.MANAGER.ast_from_module_name(currmodule) while target and path_stack: path_part = path_stack.pop() target = (target.getattr(path_part) or (None,))[0] while isinstance(target, (astroid.ImportFrom, astroid.Import)): try: target = target.do_import_module(path_part) except astroid.AstroidImportError: target = target.do_import_module() target = (target.getattr(path_part) or (None,))[0] break except astroid.AstroidError: target = None return target def _import_class(name, currmodule): target = None if currmodule: target = _do_import_class(name, currmodule) if target is None: target = _do_import_class(name) if not target: raise sphinx.ext.inheritance_diagram.InheritanceException( "Could not import class or module {} specified for inheritance diagram".format( name ) ) if isinstance(target, astroid.ClassDef): return [target] if isinstance(target, astroid.Module): classes = [] for child in target.get_children(): if isinstance(child, astroid.ClassDef): classes.append(child) return classes raise sphinx.ext.inheritance_diagram.InheritanceException( "{} specified for inheritance diagram is not a class or module".format(name) ) class _AutoapiInheritanceGraph(sphinx.ext.inheritance_diagram.InheritanceGraph): @staticmethod def _import_classes(class_names, currmodule): classes = [] for name in class_names: classes.extend(_import_class(name, currmodule)) return classes def _class_info( self, classes, show_builtins, private_bases, parts, aliases, top_classes ): # pylint: disable=too-many-arguments all_classes = {} def recurse(cls): if cls in all_classes: return if not show_builtins and cls.root().name == "builtins": return if not private_bases and cls.name.startswith("_"): return nodename = self.class_name(cls, parts, aliases) fullname = self.class_name(cls, 0, aliases) tooltip = None if cls.doc: doc = cls.doc.strip().split("\n")[0] if doc: tooltip = '"%s"' % doc.replace('"', '\\"') baselist = [] all_classes[cls] = (nodename, fullname, baselist, tooltip) if fullname in top_classes: return for base in cls.ancestors(recurs=False): if not show_builtins and base.root().name == "builtins": continue if not private_bases and base.name.startswith("_"): continue baselist.append(self.class_name(base, parts, aliases)) if base not in all_classes: recurse(base) for cls in classes: recurse(cls) return list(all_classes.values()) @staticmethod def class_name(node, parts=0, aliases=None): fullname = node.qname() if fullname.startswith(("__builtin__.", "builtins")): fullname = fullname.split(".", 1)[-1] if parts == 0: result = fullname else: name_parts = fullname.split(".") result = ".".join(name_parts[-parts:]) if aliases is not None and result in aliases: return aliases[result] return result class AutoapiInheritanceDiagram(sphinx.ext.inheritance_diagram.InheritanceDiagram): def run(self): # Yucky! Monkeypatch InheritanceGraph to use our own old_graph = sphinx.ext.inheritance_diagram.InheritanceGraph sphinx.ext.inheritance_diagram.InheritanceGraph = _AutoapiInheritanceGraph try: return super(AutoapiInheritanceDiagram, self).run() finally: sphinx.ext.inheritance_diagram.InheritanceGraph = old_graph sphinx-autoapi-1.8.4/autoapi/mappers/000077500000000000000000000000001410652014100176005ustar00rootroot00000000000000sphinx-autoapi-1.8.4/autoapi/mappers/__init__.py000066400000000000000000000002341410652014100217100ustar00rootroot00000000000000from .dotnet import DotNetSphinxMapper from .python import PythonSphinxMapper from .go import GoSphinxMapper from .javascript import JavaScriptSphinxMapper sphinx-autoapi-1.8.4/autoapi/mappers/base.py000066400000000000000000000251301410652014100210650ustar00rootroot00000000000000import os import fnmatch from collections import OrderedDict, namedtuple import re from jinja2 import Environment, FileSystemLoader, TemplateNotFound import sphinx import sphinx.util from sphinx.util.console import darkgreen, bold from sphinx.util.osutil import ensuredir import sphinx.util.logging import unidecode from ..settings import API_ROOT, TEMPLATE_DIR LOGGER = sphinx.util.logging.getLogger(__name__) Path = namedtuple("Path", ["absolute", "relative"]) class PythonMapperBase: """ Base object for JSON -> Python object mapping. Subclasses of this object will handle their language specific JSON input, and map that onto this standard Python object. Subclasses may also include language-specific attributes on this object. Arguments: :param obj: JSON object representing this object :param jinja_env: A template environment for rendering this object Required attributes: :var str id: A globally unique indentifier for this object. Generally a fully qualified name, including namespace. :var str name: A short "display friendly" name for this object. Optional attributes: :var str docstring: The documentation for this object :var list imports: Imports in this object :var list children: Children of this object :var list parameters: Parameters to this object :var list methods: Methods on this object """ language = "base" type = "base" # Create a page in the output for this object. top_level_object = False _RENDER_LOG_LEVEL = "VERBOSE" def __init__(self, obj, jinja_env, app, options=None): self.app = app self.obj = obj self.options = options self.jinja_env = jinja_env self.url_root = os.path.join("/", API_ROOT) self.name = None self.id = None def __getstate__(self): """Obtains serialisable data for pickling.""" __dict__ = self.__dict__.copy() __dict__.update(app=None, jinja_env=None) # clear unpickable attributes return __dict__ def render(self, **kwargs): LOGGER.log(self._RENDER_LOG_LEVEL, "Rendering %s", self.id) ctx = {} try: template = self.jinja_env.get_template( "{language}/{type}.rst".format(language=self.language, type=self.type) ) except TemplateNotFound: # Use a try/except here so we fallback to language specific defaults, over base defaults template = self.jinja_env.get_template( "base/{type}.rst".format(type=self.type) ) ctx.update(**self.get_context_data()) ctx.update(**kwargs) return template.render(**ctx) @property def rendered(self): """Shortcut to render an object in templates.""" return self.render() def get_context_data(self): return { "autoapi_options": self.app.config.autoapi_options, "include_summaries": self.app.config.autoapi_include_summaries, "obj": self, "sphinx_version": sphinx.version_info, } def __lt__(self, other): """Object sorting comparison""" if isinstance(other, PythonMapperBase): return self.id < other.id return super(PythonMapperBase, self).__lt__(other) def __str__(self): return "<{cls} {id}>".format(cls=self.__class__.__name__, id=self.id) @property def short_name(self): """Shorten name property""" return self.name.split(".")[-1] @property def pathname(self): """Sluggified path for filenames Slugs to a filename using the follow steps * Decode unicode to approximate ascii * Remove existing hypens * Substitute hyphens for non-word characters * Break up the string as paths """ slug = self.name slug = unidecode.unidecode(slug) slug = slug.replace("-", "") slug = re.sub(r"[^\w\.]+", "-", slug).strip("-") return os.path.join(*slug.split(".")) def include_dir(self, root): """Return directory of file""" parts = [root] parts.extend(self.pathname.split(os.path.sep)) return "/".join(parts) @property def include_path(self): """Return 'absolute' path without regarding OS path separator This is used in ``toctree`` directives, as Sphinx always expects Unix path separators """ parts = [self.include_dir(root=self.url_root)] parts.append("index") return "/".join(parts) @property def display(self): """Whether to display this object or not. :type: bool """ return True @property def ref_type(self): return self.type @property def ref_directive(self): return self.type class SphinxMapperBase: """Base class for mapping `PythonMapperBase` objects to Sphinx. :param app: Sphinx application instance """ def __init__(self, app, template_dir=None, url_root=None): self.app = app template_paths = [TEMPLATE_DIR] if template_dir: # Put at the front so it's loaded first template_paths.insert(0, template_dir) self.jinja_env = Environment( loader=FileSystemLoader(template_paths), trim_blocks=True, lstrip_blocks=True, ) def _wrapped_prepare(value): return value self.jinja_env.filters["prepare_docstring"] = _wrapped_prepare if self.app.config.autoapi_prepare_jinja_env: self.app.config.autoapi_prepare_jinja_env(self.jinja_env) self.url_root = url_root # Mapping of {filepath -> raw data} self.paths = OrderedDict() # Mapping of {object id -> Python Object} self.objects = OrderedDict() # Mapping of {object id -> Python Object} self.all_objects = OrderedDict() # Mapping of {namespace id -> Python Object} self.namespaces = OrderedDict() # Mapping of {namespace id -> Python Object} self.top_level_objects = OrderedDict() def load(self, patterns, dirs, ignore=None): """ Load objects from the filesystem into the ``paths`` dictionary. """ paths = list(self.find_files(patterns=patterns, dirs=dirs, ignore=ignore)) for path in sphinx.util.status_iterator( paths, bold("[AutoAPI] Reading files... "), "darkgreen", len(paths) ): data = self.read_file(path=path) if data: self.paths[path] = data return True @staticmethod def find_files(patterns, dirs, ignore): # pylint: disable=too-many-nested-blocks if not ignore: ignore = [] pattern_regexes = [] for pattern in patterns: regex = re.compile(fnmatch.translate(pattern).replace(".*", "(.*)")) pattern_regexes.append((pattern, regex)) for _dir in dirs: for root, _, filenames in os.walk(_dir): seen = set() for pattern, pattern_re in pattern_regexes: for filename in fnmatch.filter(filenames, pattern): skip = False match = re.match(pattern_re, filename) norm_name = match.groups() if norm_name in seen: continue # Skip ignored files for ignore_pattern in ignore: if fnmatch.fnmatch( os.path.join(root, filename), ignore_pattern ): LOGGER.info( bold("[AutoAPI] ") + darkgreen("Ignoring %s/%s" % (root, filename)) ) skip = True if skip: continue # Make sure the path is full if not os.path.isabs(filename): filename = os.path.join(root, filename) yield filename seen.add(norm_name) def read_file(self, path, **kwargs): """Read file input into memory :param path: Path of file to read """ # TODO support JSON here # TODO sphinx way of reporting errors in logs? raise NotImplementedError def add_object(self, obj): """ Add object to local and app environment storage :param obj: Instance of a AutoAPI object """ self.objects[obj.id] = obj self.all_objects[obj.id] = obj child_stack = list(obj.children) while child_stack: child = child_stack.pop() self.all_objects[child.id] = child child_stack.extend(getattr(child, "children", ())) def map(self, options=None): """Trigger find of serialized sources and build objects""" for _, data in sphinx.util.status_iterator( self.paths.items(), bold("[AutoAPI] ") + "Mapping Data... ", length=len(self.paths), stringify_func=(lambda x: x[0]), ): for obj in self.create_class(data, options=options): self.add_object(obj) def create_class(self, data, options=None, **kwargs): """ Create class object. :param data: Instance of a AutoAPI object """ raise NotImplementedError def output_rst(self, root, source_suffix): for _, obj in sphinx.util.status_iterator( self.objects.items(), bold("[AutoAPI] ") + "Rendering Data... ", length=len(self.objects), verbosity="INFO", stringify_func=(lambda x: x[0]), ): rst = obj.render() if not rst: continue detail_dir = obj.include_dir(root=root) ensuredir(detail_dir) path = os.path.join(detail_dir, "%s%s" % ("index", source_suffix)) with open(path, "wb+") as detail_file: detail_file.write(rst.encode("utf-8")) if self.app.config.autoapi_add_toctree_entry: self._output_top_rst(root) def _output_top_rst(self, root): # Render Top Index top_level_index = os.path.join(root, "index.rst") pages = self.objects.values() with open(top_level_index, "wb") as top_level_file: content = self.jinja_env.get_template("index.rst") top_level_file.write(content.render(pages=pages).encode("utf-8")) sphinx-autoapi-1.8.4/autoapi/mappers/dotnet.py000066400000000000000000000467261410652014100214660ustar00rootroot00000000000000import re import os import subprocess import traceback import shutil from collections import defaultdict import unidecode import yaml from sphinx.util.osutil import ensuredir from sphinx.util.console import darkgreen, bold import sphinx.util.logging from sphinx.errors import ExtensionError from .base import PythonMapperBase, SphinxMapperBase LOGGER = sphinx.util.logging.getLogger(__name__) # Doc comment patterns DOC_COMMENT_PATTERN = r""" \<%(tag)s \s+%(attr)s="(?P[^"]*?)" \s*? (?: \/\>| \>(?P[^\<]*?)\<\/%(tag)s\> ) """ DOC_COMMENT_SEE_PATTERN = re.compile( DOC_COMMENT_PATTERN % {"tag": "(?:see|seealso)", "attr": "cref"}, re.X ) DOC_COMMENT_PARAM_PATTERN = re.compile( DOC_COMMENT_PATTERN % {"tag": "(?:paramref|typeparamref)", "attr": "name"}, re.X ) # Comment member identities # From: https://msdn.microsoft.com/en-us/library/vstudio/fsbx0t7x(v=VS.100).aspx DOC_COMMENT_IDENTITIES = { "N": "dn:ns", "T": "any", # can be any type (class, delegate, enum, etc), so use any "F": "dn:field", "P": "dn:prop", "M": "dn:meth", "E": "dn:event", } class DotNetSphinxMapper(SphinxMapperBase): """Auto API domain handler for .NET Searches for YAML files, and soon to be JSON files as well, for auto API sources. If no pattern configuration was explicitly specified, then default to looking up a ``docfx.json`` file. :param app: Sphinx application passed in as part of the extension """ top_namespaces = {} DOCFX_OUTPUT_PATH = "_api" # pylint: disable=arguments-differ def load(self, patterns, dirs, ignore=None): """Load objects from the filesystem into the ``paths`` dictionary. If the setting ``autoapi_patterns`` was not specified, look for a ``docfx.json`` file by default. A ``docfx.json`` should be treated as the canonical source before the default patterns. Fallback to default pattern matches if no ``docfx.json`` files are found. """ LOGGER.info(bold("[AutoAPI] ") + darkgreen("Loading Data")) all_files = set() if not self.app.config.autoapi_file_patterns: all_files = set( self.find_files(patterns=["docfx.json"], dirs=dirs, ignore=ignore) ) if not all_files: all_files = set( self.find_files(patterns=patterns, dirs=dirs, ignore=ignore) ) if all_files: command = ["docfx", "metadata", "--raw", "--force"] command.extend(all_files) proc = subprocess.Popen( " ".join(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, env=dict( (key, os.environ[key]) for key in [ "PATH", "HOME", "SYSTEMROOT", "USERPROFILE", "WINDIR", ] if key in os.environ ), ) _, error_output = proc.communicate() if error_output: LOGGER.warning(error_output, type="autoapi", subtype="not_readable") # We now have yaml files for xdoc_path in self.find_files( patterns=["*.yml"], dirs=[self.DOCFX_OUTPUT_PATH], ignore=ignore ): data = self.read_file(path=xdoc_path) if data: self.paths[xdoc_path] = data return True def read_file(self, path, **kwargs): """Read file input into memory, returning deserialized objects :param path: Path of file to read """ try: with open(path, "r") as handle: parsed_data = yaml.safe_load(handle) return parsed_data except IOError: LOGGER.warning( "Error reading file: {0}".format(path), type="autoapi", subtype="not_readable", ) except TypeError: LOGGER.warning( "Error reading file: {0}".format(path), type="autoapi", subtype="not_readable", ) return None # Subclassed to iterate over items def map(self, options=None): """Trigger find of serialized sources and build objects""" for _, data in sphinx.util.status_iterator( self.paths.items(), bold("[AutoAPI] ") + "Mapping Data... ", length=len(self.paths), stringify_func=(lambda x: x[0]), ): references = data.get("references", []) for item in data["items"]: for obj in self.create_class(item, options, references=references): self.add_object(obj) self.organize_objects() def create_class(self, data, options=None, **kwargs): """ Return instance of class based on Roslyn type property Data keys handled here: type Set the object class items Recurse into :py:meth:`create_class` to create child object instances :param data: dictionary data from Roslyn output artifact """ kwargs.pop("path", None) obj_map = {cls.type: cls for cls in ALL_CLASSES} try: cls = obj_map[data["type"].lower()] except KeyError: # this warning intentionally has no (sub-)type LOGGER.warning("Unknown type: %s" % data) else: obj = cls( data, jinja_env=self.jinja_env, app=self.app, options=options, **kwargs ) obj.url_root = self.url_root # Append child objects # TODO this should recurse in the case we're getting back more # complex argument listings yield obj def add_object(self, obj): """Add object to local and app environment storage :param obj: Instance of a .NET object """ if obj.top_level_object: if isinstance(obj, DotNetNamespace): self.namespaces[obj.name] = obj self.objects[obj.id] = obj def organize_objects(self): """Organize objects and namespaces""" def _render_children(obj): for child in obj.children_strings: child_object = self.objects.get(child) if child_object: obj.item_map[child_object.plural].append(child_object) obj.children.append(child_object) for key in obj.item_map: obj.item_map[key].sort() def _recurse_ns(obj): if not obj: return namespace = obj.top_namespace if namespace is not None: ns_obj = self.top_namespaces.get(namespace) if ns_obj is None or not isinstance(ns_obj, DotNetNamespace): for ns_obj in self.create_class( {"uid": namespace, "type": "namespace"} ): self.top_namespaces[ns_obj.id] = ns_obj if obj not in ns_obj.children and namespace != obj.id: ns_obj.children.append(obj) for obj in self.objects.values(): _render_children(obj) _recurse_ns(obj) # Clean out dead namespaces for key, namespace in self.top_namespaces.copy().items(): if not namespace.children: del self.top_namespaces[key] for key, namespace in self.namespaces.copy().items(): if not namespace.children: del self.namespaces[key] def output_rst(self, root, source_suffix): if not self.objects: raise ExtensionError("No API objects exist. Can't continue") for _, obj in sphinx.util.status_iterator( self.objects.items(), bold("[AutoAPI] ") + "Rendering Data... ", length=len(self.objects), stringify_func=(lambda x: x[0]), ): if not obj or not obj.top_level_object: continue rst = obj.render() if not rst: continue detail_dir = os.path.join(root, obj.pathname) ensuredir(detail_dir) path = os.path.join(detail_dir, "%s%s" % ("index", source_suffix)) with open(path, "wb") as detail_file: detail_file.write(rst.encode("utf-8")) # Render Top Index top_level_index = os.path.join(root, "index.rst") with open(top_level_index, "wb") as top_level_file: content = self.jinja_env.get_template("index.rst") top_level_file.write( content.render(pages=self.namespaces.values()).encode("utf-8") ) @staticmethod def build_finished(app, _): if app.verbosity > 1: LOGGER.info(bold("[AutoAPI] ") + darkgreen("Cleaning generated .yml files")) if os.path.exists(DotNetSphinxMapper.DOCFX_OUTPUT_PATH): shutil.rmtree(DotNetSphinxMapper.DOCFX_OUTPUT_PATH) class DotNetPythonMapper(PythonMapperBase): """Base .NET object representation :param references: object reference list from docfx :type references: list of dict objects """ language = "dotnet" def __init__(self, obj, **kwargs): self.references = dict( (obj.get("uid"), obj) for obj in kwargs.pop("references", []) if "uid" in obj ) super(DotNetPythonMapper, self).__init__(obj, **kwargs) # Always exist self.id = obj.get("uid", obj.get("id")) self.definition = obj.get("definition", self.id) self.name = obj.get("fullName", self.definition) # Optional self.fullname = obj.get("fullName") self.summary = self.transform_doc_comments(obj.get("summary", "")) self.parameters = [] self.items = obj.get("items", []) self.children_strings = obj.get("children", []) self.children = [] self.item_map = defaultdict(list) self.inheritance = [] self.assemblies = obj.get("assemblies", []) # Syntax example and parameter list syntax = obj.get("syntax", None) self.example = "" if syntax is not None: # Code example try: self.example = syntax["content"] except (KeyError, TypeError): traceback.print_exc() self.parameters = [] for param in syntax.get("parameters", []): if "id" in param: self.parameters.append( { "name": param.get("id"), "type": self.resolve_spec_identifier(param.get("type")), "desc": self.transform_doc_comments( param.get("description", "") ), } ) self.returns = {} self.returns["type"] = self.resolve_spec_identifier( syntax.get("return", {}).get("type") ) self.returns["description"] = self.transform_doc_comments( syntax.get("return", {}).get("description") ) # Inheritance # TODO Support more than just a class type here, should support enum/etc self.inheritance = [ DotNetClass( {"uid": name, "name": name}, jinja_env=self.jinja_env, app=self.app ) for name in obj.get("inheritance", []) ] def __str__(self): return "<{cls} {id}>".format(cls=self.__class__.__name__, id=self.id) @property def pathname(self): """Sluggified path for filenames Slugs to a filename using the follow steps * Decode unicode to approximate ascii * Remove existing hypens * Substitute hyphens for non-word characters * Break up the string as paths """ slug = self.name try: slug = self.name.split("(")[0] except IndexError: pass slug = unidecode.unidecode(slug) slug = slug.replace("-", "") slug = re.sub(r"[^\w\.]+", "-", slug).strip("-") return os.path.join(*slug.split(".")) @property def short_name(self): """Shorten name property""" return self.name.split(".")[-1] @property def edit_link(self): try: repo = self.source["remote"]["repo"].replace(".git", "") path = self.path return "{repo}/blob/master/{path}".format(repo=repo, path=path) except KeyError: return "" @property def source(self): return self.obj.get("source") @property def path(self): return self.source["path"] @property def namespace(self): pieces = self.id.split(".")[:-1] if pieces: return ".".join(pieces) return None @property def top_namespace(self): pieces = self.id.split(".")[:2] if pieces: return ".".join(pieces) return None @property def ref_type(self): return self.type @property def ref_directive(self): return self.type @property def ref_name(self): """Return object name suitable for use in references Escapes several known strings that cause problems, including the following reference syntax:: :dotnet:cls:`Foo.Bar` As the `` notation is also special syntax in references, indicating the reference to Foo.Bar should be named T. See: http://sphinx-doc.org/domains.html#role-cpp:any """ return self.name.replace("<", r"\<").replace("`", r"\`") @property def ref_short_name(self): """Same as above, return the truncated name instead""" return self.ref_name.split(".")[-1] @staticmethod def transform_doc_comments(text): """ Parse XML content for references and other syntax. This avoids an LXML dependency, we only need to parse out a small subset of elements here. Iterate over string to reduce regex pattern complexity and make substitutions easier .. seealso:: `Doc comment reference ` Reference on XML documentation comment syntax """ try: while True: found = DOC_COMMENT_SEE_PATTERN.search(text) if found is None: break ref = found.group("attr_value").replace("<", r"\<").replace("`", r"\`") reftype = "any" replacement = "" # Given the pattern of `\w:\w+`, inspect first letter of # reference for identity type if ref[1] == ":" and ref[0] in DOC_COMMENT_IDENTITIES: reftype = DOC_COMMENT_IDENTITIES[ref[:1]] ref = ref[2:] replacement = ":{reftype}:`{ref}`".format(reftype=reftype, ref=ref) elif ref[:2] == "!:": replacement = ref[2:] else: replacement = ":any:`{ref}`".format(ref=ref) # Escape following text text_end = text[found.end() :] text_start = text[: found.start()] text_end = re.sub(r"^(\S)", r"\\\1", text_end) text_start = re.sub(r"(\S)$", r"\1 ", text_start) text = "".join([text_start, replacement, text_end]) while True: found = DOC_COMMENT_PARAM_PATTERN.search(text) if found is None: break # Escape following text text_end = text[found.end() :] text_start = text[: found.start()] text_end = re.sub(r"^(\S)", r"\\\1", text_end) text_start = re.sub(r"(\S)$", r"\1 ", text_start) text = "".join( [text_start, "``", found.group("attr_value"), "``", text_end] ) except TypeError: pass return text def resolve_spec_identifier(self, obj_name): """Find reference name based on spec identifier Spec identifiers are used in parameter and return type definitions, but should be a user-friendly version instead. Use docfx ``references`` lookup mapping for resolution. If the spec identifier reference has a ``spec.csharp`` key, this implies a compound reference that should be linked in a special way. Resolve to a nested reference, with the corrected nodes. .. note:: This uses a special format that is interpreted by the domain for parameter type and return type fields. :param obj_name: spec identifier to resolve to a correct reference :returns: resolved string with one or more references :rtype: str """ ref = self.references.get(obj_name) if ref is None: return obj_name resolved = ref.get("fullName", obj_name) spec = ref.get("spec.csharp", []) parts = [] for part in spec: if part.get("name") == "<": parts.append("{") elif part.get("name") == ">": parts.append("}") elif "fullName" in part and "uid" in part: parts.append("{fullName}<{uid}>".format(**part)) elif "uid" in part: parts.append(part["uid"]) elif "fullName" in part: parts.append(part["fullName"]) if parts: resolved = "".join(parts) return resolved class DotNetNamespace(DotNetPythonMapper): type = "namespace" ref_directive = "ns" plural = "namespaces" top_level_object = True class DotNetMethod(DotNetPythonMapper): type = "method" ref_directive = "meth" plural = "methods" class DotNetOperator(DotNetPythonMapper): type = "operator" ref_directive = "op" plural = "operators" class DotNetProperty(DotNetPythonMapper): type = "property" ref_directive = "prop" plural = "properties" class DotNetEnum(DotNetPythonMapper): type = "enum" ref_type = "enumeration" ref_directive = "enum" plural = "enumerations" top_level_object = True class DotNetStruct(DotNetPythonMapper): type = "struct" ref_type = "structure" ref_directive = "struct" plural = "structures" top_level_object = True class DotNetConstructor(DotNetPythonMapper): type = "constructor" ref_directive = "ctor" plural = "constructors" class DotNetInterface(DotNetPythonMapper): type = "interface" ref_directive = "iface" plural = "interfaces" top_level_object = True class DotNetDelegate(DotNetPythonMapper): type = "delegate" ref_directive = "del" plural = "delegates" top_level_object = True class DotNetClass(DotNetPythonMapper): type = "class" ref_directive = "cls" plural = "classes" top_level_object = True class DotNetField(DotNetPythonMapper): type = "field" plural = "fields" class DotNetEvent(DotNetPythonMapper): type = "event" plural = "events" ALL_CLASSES = [ DotNetNamespace, DotNetClass, DotNetEnum, DotNetStruct, DotNetInterface, DotNetDelegate, DotNetOperator, DotNetProperty, DotNetMethod, DotNetConstructor, DotNetField, DotNetEvent, ] sphinx-autoapi-1.8.4/autoapi/mappers/go.py000066400000000000000000000141561410652014100205660ustar00rootroot00000000000000import json import subprocess from sphinx.util.console import bold import sphinx.util.logging from .base import PythonMapperBase, SphinxMapperBase LOGGER = sphinx.util.logging.getLogger(__name__) class GoSphinxMapper(SphinxMapperBase): """Auto API domain handler for Go Parses directly from Go files. :param app: Sphinx application passed in as part of the extension """ def load(self, patterns, dirs, ignore=None): """ Load objects from the filesystem into the ``paths`` dictionary. """ for _dir in sphinx.util.status_iterator( dirs, bold("[AutoAPI] Loading Data "), "darkgreen", len(dirs) ): data = self.read_file(_dir, ignore=ignore) if data: self.paths[_dir] = data return True def read_file(self, path, **kwargs): """Read file input into memory, returning deserialized objects :param path: Path of file to read :param **kwargs: * ignore (``list``): List of file patterns to ignore """ # TODO support JSON here # TODO sphinx way of reporting errors in logs? parser_command = ["godocjson"] _ignore = kwargs.get("ignore") if _ignore: parser_command.extend(["-e", "{0}".format("|".join(_ignore))]) parser_command.append(path) try: parsed_data = json.loads(subprocess.check_output(parser_command)) return parsed_data except IOError: LOGGER.warning( "Error reading file: {0}".format(path), type="autoapi", subtype="not_readable", ) except TypeError: LOGGER.warning( "Error reading file: {0}".format(path), type="autoapi", subtype="not_readable", ) return None def create_class(self, data, options=None, **kwargs): """Return instance of class based on Go data Data keys handled here: _type Set the object class consts, types, vars, funcs, methods Recurse into :py:meth:`create_class` to create child object instances :param data: dictionary data from godocjson output """ _type = kwargs.get("_type") obj_map = dict((cls.type, cls) for cls in ALL_CLASSES) try: # Contextual type data from children recursion if _type: LOGGER.debug("Forcing Go Type %s" % _type) cls = obj_map[_type] else: cls = obj_map[data["type"]] except KeyError: # this warning intentionally has no (sub-)type LOGGER.warning("Unknown type: %s" % data) else: if cls.inverted_names and "names" in data: # Handle types that have reversed names parameter for name in data["names"]: data_inv = {} data_inv.update(data) data_inv["name"] = name if "names" in data_inv: del data_inv["names"] for obj in self.create_class(data_inv): yield obj else: # Recurse for children obj = cls(data, jinja_env=self.jinja_env, app=self.app) for child_type in ["consts", "types", "vars", "funcs", "methods"]: for child_data in data.get(child_type, []): obj.children += list( self.create_class( child_data, _type=child_type.replace("consts", "const") .replace("types", "type") .replace("vars", "variable") .replace("funcs", "func") .replace("methods", "method"), ) ) yield obj class GoPythonMapper(PythonMapperBase): language = "go" inverted_names = False def __init__(self, obj, **kwargs): super(GoPythonMapper, self).__init__(obj, **kwargs) self.name = obj.get("name") or obj.get("packageName") self.id = self.name # Second level self.imports = obj.get("imports", []) self.children = [] temp_parameters = map( lambda n: {"name": n["name"], "type": n["type"].lstrip("*")}, obj.get("parameters", []), ) self.parameters = list(temp_parameters) self.results = obj.get("results", []) self.docstring = obj.get("doc", "") # Go Specific self.notes = obj.get("notes", {}) self.filenames = obj.get("filenames", []) self.bugs = obj.get("bugs", []) def __str__(self): return "<{cls} {id}>".format(cls=self.__class__.__name__, id=self.id) @property def short_name(self): """Shorten name property""" return self.name.split(".")[-1] @property def namespace(self): pieces = self.id.split(".")[:-1] if pieces: return ".".join(pieces) return None @property def ref_type(self): return self.type @property def ref_directive(self): return self.type @property def methods(self): return self.obj.get("methods", []) class GoVariable(GoPythonMapper): type = "var" inverted_names = True class GoMethod(GoPythonMapper): type = "method" ref_directive = "meth" def __init__(self, obj, **kwargs): super(GoMethod, self).__init__(obj, **kwargs) self.receiver = obj.get("recv") class GoConstant(GoPythonMapper): type = "const" inverted_names = True class GoFunction(GoPythonMapper): type = "func" ref_type = "function" class GoPackage(GoPythonMapper): type = "package" ref_directive = "pkg" top_level_object = True _RENDER_LOG_LEVEL = "VERBOSE" class GoType(GoPythonMapper): type = "type" ALL_CLASSES = [GoConstant, GoFunction, GoPackage, GoVariable, GoType, GoMethod] sphinx-autoapi-1.8.4/autoapi/mappers/javascript.py000066400000000000000000000104331410652014100223210ustar00rootroot00000000000000import json import subprocess import os from sphinx.util.console import bold import sphinx.util.logging from .base import PythonMapperBase, SphinxMapperBase LOGGER = sphinx.util.logging.getLogger(__name__) class JavaScriptSphinxMapper(SphinxMapperBase): """Auto API domain handler for Javascript Parses directly from Javascript files. :param app: Sphinx application passed in as part of the extension """ def read_file(self, path, **kwargs): """Read file input into memory, returning deserialized objects :param path: Path of file to read """ # TODO support JSON here # TODO sphinx way of reporting errors in logs? subcmd = "jsdoc" if os.name == "nt": subcmd = ".".join([subcmd, "cmd"]) try: parsed_data = json.loads(subprocess.check_output([subcmd, "-X", path])) return parsed_data except IOError: LOGGER.warning( "Error reading file: {0}".format(path), type="autoapi", subtype="not_readable", ) except TypeError: LOGGER.warning( "Error reading file: {0}".format(path), type="autoapi", subtype="not_readable", ) return None # Subclassed to iterate over items def map(self, options=None): """Trigger find of serialized sources and build objects""" for _, data in sphinx.util.status_iterator( self.paths.items(), bold("[AutoAPI] ") + "Mapping Data... ", length=len(self.paths), stringify_func=(lambda x: x[0]), ): for item in data: for obj in self.create_class(item, options): obj.jinja_env = self.jinja_env self.add_object(obj) def create_class(self, data, options=None, **kwargs): """Return instance of class based on Javascript data Data keys handled here: type Set the object class consts, types, vars, funcs Recurse into :py:meth:`create_class` to create child object instances :param data: dictionary data from godocjson output """ obj_map = dict((cls.type, cls) for cls in ALL_CLASSES) try: cls = obj_map[data["kind"]] except (KeyError, TypeError): # this warning intentionally has no (sub-)type LOGGER.warning("Unknown type: %s" % data) else: # Recurse for children obj = cls(data, jinja_env=self.jinja_env, app=self.app) if "children" in data: for child_data in data["children"]: for child_obj in self.create_class(child_data, options=options): obj.children.append(child_obj) yield obj class JavaScriptPythonMapper(PythonMapperBase): language = "javascript" def __init__(self, obj, **kwargs): """ Map JSON data into Python object. This is the standard object that will be rendered into the templates, so we try and keep standard naming to keep templates more re-usable. """ super(JavaScriptPythonMapper, self).__init__(obj, **kwargs) self.name = obj.get("name") self.id = self.name # Second level self.docstring = obj.get("description", "") # self.docstring = obj.get('comment', '') self.imports = obj.get("imports", []) self.children = [] self.parameters = map( lambda n: {"name": n["name"], "type": n["type"][0]}, obj.get("param", []) ) class JavaScriptClass(JavaScriptPythonMapper): type = "class" ref_directive = "class" top_level_object = True class JavaScriptFunction(JavaScriptPythonMapper): type = "function" ref_type = "func" class JavaScriptData(JavaScriptPythonMapper): type = "data" ref_directive = "data" class JavaScriptMember(JavaScriptPythonMapper): type = "member" ref_directive = "member" class JavaScriptAttribute(JavaScriptPythonMapper): type = "attribute" ref_directive = "attr" ALL_CLASSES = [ JavaScriptFunction, JavaScriptClass, JavaScriptData, JavaScriptAttribute, JavaScriptMember, ] sphinx-autoapi-1.8.4/autoapi/mappers/python/000077500000000000000000000000001410652014100211215ustar00rootroot00000000000000sphinx-autoapi-1.8.4/autoapi/mappers/python/__init__.py000066400000000000000000000003261410652014100232330ustar00rootroot00000000000000from .mapper import PythonSphinxMapper from .objects import ( PythonClass, PythonFunction, PythonModule, PythonMethod, PythonPackage, PythonAttribute, PythonData, PythonException, ) sphinx-autoapi-1.8.4/autoapi/mappers/python/astroid_utils.py000066400000000000000000000453331410652014100243700ustar00rootroot00000000000000import builtins import itertools import re import sys import astroid import astroid.nodes # Disable until pylint uses astroid 2.7 import astroid.nodes.node_classes # pylint: disable=no-name-in-module import sphinx.util.logging _LOGGER = sphinx.util.logging.getLogger(__name__) def resolve_import_alias(name, import_names): """Resolve a name from an aliased import to its original name. :param name: The potentially aliased name to resolve. :type name: str :param import_names: The pairs of original names and aliases from the import. :type import_names: iterable(tuple(str, str or None)) :returns: The original name. :rtype: str """ resolved_name = name for import_name, imported_as in import_names: if import_name == name: break if imported_as == name: resolved_name = import_name break return resolved_name def get_full_import_name(import_from, name): """Get the full path of a name from a ``from x import y`` statement. :param import_from: The astroid node to resolve the name of. :type import_from: astroid.nodes.ImportFrom :param name: :type name: str :returns: The full import path of the name. :rtype: str """ partial_basename = resolve_import_alias(name, import_from.names) module_name = import_from.modname if import_from.level: module = import_from.root() assert isinstance(module, astroid.nodes.Module) module_name = module.relative_to_absolute_name( import_from.modname, level=import_from.level ) return "{}.{}".format(module_name, partial_basename) def resolve_qualname(node, basename): """Resolve where a node is defined to get its fully qualified name. :param node: The node representing the base name. :type node: astroid.NodeNG :param basename: The partial base name to resolve. :type basename: str :returns: The fully resolved base name. :rtype: str """ full_basename = basename top_level_name = re.sub(r"\(.*\)", "", basename).split(".", 1)[0] # Disable until pylint uses astroid 2.7 if isinstance( node, astroid.nodes.node_classes.LookupMixIn # pylint: disable=no-member ): lookup_node = node else: lookup_node = node.scope() assigns = lookup_node.lookup(top_level_name)[1] for assignment in assigns: if isinstance(assignment, astroid.nodes.ImportFrom): import_name = get_full_import_name(assignment, top_level_name) full_basename = basename.replace(top_level_name, import_name, 1) break if isinstance(assignment, astroid.nodes.Import): import_name = resolve_import_alias(top_level_name, assignment.names) full_basename = basename.replace(top_level_name, import_name, 1) break if isinstance(assignment, astroid.nodes.ClassDef): full_basename = assignment.qname() break if isinstance(assignment, astroid.nodes.AssignName): full_basename = "{}.{}".format(assignment.scope().qname(), assignment.name) if isinstance(node, astroid.nodes.Call): full_basename = re.sub(r"\(.*\)", "()", full_basename) if full_basename.startswith("builtins."): return full_basename[len("builtins.") :] if full_basename.startswith("__builtin__."): return full_basename[len("__builtin__.") :] return full_basename def get_full_basenames(node): """Resolve the partial names of a class' bases to fully qualified names. :param node: The class definition node to resolve the bases of. :type: astroid.ClassDef :returns: The full names. :rtype: iterable(str) """ for base in node.bases: yield _resolve_annotation(base) def _get_const_values(node): value = None if isinstance(node, (astroid.nodes.List, astroid.nodes.Tuple)): new_value = [] for element in node.elts: if isinstance(element, astroid.nodes.Const): new_value.append(element.value) elif isinstance(element, (astroid.nodes.List, astroid.nodes.Tuple)): new_value.append(_get_const_values(element)) else: break else: value = new_value elif isinstance(node, astroid.nodes.Const): value = node.value return value def get_assign_value(node): """Get the name and value of the assignment of the given node. Assignments to multiple names are ignored, as per PEP 257. :param node: The node to get the assignment value from. :type node: astroid.nodes.Assign or astroid.nodes.AnnAssign :returns: The name that is assigned to, and the value assigned to the name (if it can be converted). :rtype: tuple(str, object or None) or None """ try: targets = node.targets except AttributeError: targets = [node.target] if len(targets) == 1: target = targets[0] if isinstance(target, astroid.nodes.AssignName): name = target.name elif isinstance(target, astroid.nodes.AssignAttr): name = target.attrname else: return None return (name, _get_const_values(node.value)) return None def get_assign_annotation(node): """Get the type annotation of the assignment of the given node. :param node: The node to get the annotation for. :type node: astroid.nodes.Assign or astroid.nodes.AnnAssign :returns: The type annotation as a string, or None if one does not exist. :rtype: str or None """ annotation_node = None try: annotation_node = node.annotation except AttributeError: annotation_node = node.type_annotation return format_annotation(annotation_node) def is_decorated_with_property(node): """Check if the function is decorated as a property. :param node: The node to check. :type node: astroid.nodes.FunctionDef :returns: True if the function is a property, False otherwise. :rtype: bool """ if not node.decorators: return False for decorator in node.decorators.nodes: if not isinstance(decorator, astroid.Name): continue try: if _is_property_decorator(decorator): return True except astroid.InferenceError: pass return False def _is_property_decorator(decorator): def _is_property_class(class_node): return ( class_node.name == "property" and class_node.root().name == builtins.__name__ ) for inferred in decorator.infer(): if not isinstance(inferred, astroid.nodes.ClassDef): continue if _is_property_class(inferred): return True if any(_is_property_class(ancestor) for ancestor in inferred.ancestors()): return True return False def is_decorated_with_property_setter(node): """Check if the function is decorated as a property setter. :param node: The node to check. :type node: astroid.nodes.FunctionDef :returns: True if the function is a property setter, False otherwise. :rtype: bool """ if not node.decorators: return False for decorator in node.decorators.nodes: if ( isinstance(decorator, astroid.nodes.Attribute) and decorator.attrname == "setter" ): return True return False def is_decorated_with_overload(node): """Check if the function is decorated as an overload definition. :param node: The node to check. :type node: astroid.nodes.FunctionDef :returns: True if the function is an overload definition, False otherwise. :rtype: bool """ if not node.decorators: return False for decorator in node.decorators.nodes: if not isinstance(decorator, (astroid.Name, astroid.Attribute)): continue try: if _is_overload_decorator(decorator): return True except astroid.InferenceError: pass return False def _is_overload_decorator(decorator): for inferred in decorator.infer(): if not isinstance(inferred, astroid.nodes.FunctionDef): continue if inferred.name == "overload" and inferred.root().name == "typing": return True return False def is_constructor(node): """Check if the function is a constructor. :param node: The node to check. :type node: astroid.nodes.FunctionDef :returns: True if the function is a constructor, False otherwise. :rtype: bool """ return ( node.parent and isinstance(node.parent.scope(), astroid.nodes.ClassDef) and node.name == "__init__" ) def is_exception(node): """Check if a class is an exception. :param node: The node to check. :type node: astroid.nodes.ClassDef :returns: True if the class is an exception, False otherwise. :rtype: bool """ if node.name in ("Exception", "BaseException") and node.root().name == "builtins": return True if not hasattr(node, "ancestors"): return False return any(is_exception(parent) for parent in node.ancestors(recurs=True)) def is_local_import_from(node, package_name): """Check if a node is an import from the local package. :param node: The node to check. :type node: astroid.node.NodeNG :param package_name: The name of the local package. :type package_name: str :returns: True if the node is an import from the local package, False otherwise. :rtype: bool """ if not isinstance(node, astroid.ImportFrom): return False return ( node.level or node.modname == package_name or node.modname.startswith(package_name + ".") ) def get_module_all(node): """Get the contents of the ``__all__`` variable from a module. :param node: The module to get ``__all__`` from. :type node: astroid.nodes.Module :returns: The contents of ``__all__`` if defined. Otherwise None. :rtype: list(str) or None """ all_ = None if "__all__" in node.locals: assigned = next(node.igetattr("__all__")) if assigned is not astroid.Uninferable: all_ = [] for elt in getattr(assigned, "elts", ()): try: elt_name = next(elt.infer()) except astroid.InferenceError: continue if elt_name is astroid.Uninferable: continue if isinstance(elt_name, astroid.Const) and isinstance( elt_name.value, str ): all_.append(elt_name.value) return all_ def _is_ellipsis(node): if sys.version_info < (3, 8): return isinstance(node, astroid.Ellipsis) return isinstance(node, astroid.Const) and node.value == Ellipsis def merge_annotations(annotations, comment_annotations): for ann, comment_ann in itertools.zip_longest(annotations, comment_annotations): if ann and not _is_ellipsis(ann): yield ann elif comment_ann and not _is_ellipsis(comment_ann): yield comment_ann else: yield None def _resolve_annotation(annotation): resolved = None if isinstance(annotation, astroid.Const): resolved = resolve_qualname(annotation, str(annotation.value)) elif isinstance(annotation, astroid.Name): resolved = resolve_qualname(annotation, annotation.name) elif isinstance(annotation, astroid.Attribute): resolved = resolve_qualname(annotation, annotation.as_string()) elif isinstance(annotation, astroid.Subscript): value = _resolve_annotation(annotation.value) slice_node = annotation.slice if isinstance(slice_node, astroid.Index): slice_node = slice_node.value if isinstance(slice_node, astroid.Tuple): slice_ = ", ".join(_resolve_annotation(elt) for elt in slice_node.elts) else: slice_ = _resolve_annotation(slice_node) resolved = f"{value}[{slice_}]" elif isinstance(annotation, astroid.Tuple): resolved = ( "(" + ", ".join(_resolve_annotation(elt) for elt in annotation.elts) + ")" ) elif isinstance(annotation, astroid.List): resolved = ( "[" + ", ".join(_resolve_annotation(elt) for elt in annotation.elts) + "]" ) else: resolved = annotation.as_string() if resolved.startswith("typing."): return resolved[len("typing.") :] # Sphinx is capable of linking anything in the same module # without needing a fully qualified path. module_prefix = annotation.root().name + "." if resolved.startswith(module_prefix): return resolved[len(module_prefix) :] return resolved def format_annotation(annotation): if annotation: return _resolve_annotation(annotation) return annotation def _iter_args(args, annotations, defaults): default_offset = len(args) - len(defaults) packed = itertools.zip_longest(args, annotations) for i, (arg, annotation) in enumerate(packed): default = None if defaults is not None and i >= default_offset: if defaults[i - default_offset] is not None: default = defaults[i - default_offset].as_string() name = arg.name if isinstance(arg, astroid.Tuple): name = "({})".format(", ".join(x.name for x in arg.elts)) yield (name, format_annotation(annotation), default) def get_args_info(args_node): # pylint: disable=too-many-branches,too-many-statements result = [] positional_only_defaults = [] positional_or_keyword_defaults = args_node.defaults if args_node.defaults: args = args_node.args or [] positional_or_keyword_defaults = args_node.defaults[-len(args) :] positional_only_defaults = args_node.defaults[ : len(args_node.defaults) - len(args) ] plain_annotations = args_node.annotations or () func_comment_annotations = args_node.parent.type_comment_args or () comment_annotations = args_node.type_comment_posonlyargs comment_annotations += args_node.type_comment_args or [] comment_annotations += args_node.type_comment_kwonlyargs annotations = list( merge_annotations( plain_annotations, merge_annotations(func_comment_annotations, comment_annotations), ) ) annotation_offset = 0 if args_node.posonlyargs: posonlyargs_annotations = args_node.posonlyargs_annotations if not any(args_node.posonlyargs_annotations): num_args = len(args_node.posonlyargs) posonlyargs_annotations = annotations[ annotation_offset : annotation_offset + num_args ] for arg, annotation, default in _iter_args( args_node.posonlyargs, posonlyargs_annotations, positional_only_defaults ): result.append((None, arg, annotation, default)) result.append(("/", None, None, None)) if not any(args_node.posonlyargs_annotations): annotation_offset += num_args if args_node.args: num_args = len(args_node.args) for arg, annotation, default in _iter_args( args_node.args, annotations[annotation_offset : annotation_offset + num_args], positional_or_keyword_defaults, ): result.append((None, arg, annotation, default)) annotation_offset += num_args if args_node.vararg: annotation = None if args_node.varargannotation: annotation = format_annotation(args_node.varargannotation) elif len(annotations) > annotation_offset and annotations[annotation_offset]: annotation = format_annotation(annotations[annotation_offset]) annotation_offset += 1 result.append(("*", args_node.vararg, annotation, None)) if args_node.kwonlyargs: if not args_node.vararg: result.append(("*", None, None, None)) kwonlyargs_annotations = args_node.kwonlyargs_annotations if not any(args_node.kwonlyargs_annotations): num_args = len(args_node.kwonlyargs) kwonlyargs_annotations = annotations[ annotation_offset : annotation_offset + num_args ] for arg, annotation, default in _iter_args( args_node.kwonlyargs, kwonlyargs_annotations, args_node.kw_defaults, ): result.append((None, arg, annotation, default)) if not any(args_node.kwonlyargs_annotations): annotation_offset += num_args if args_node.kwarg: annotation = None if args_node.kwargannotation: annotation = format_annotation(args_node.kwargannotation) elif len(annotations) > annotation_offset and annotations[annotation_offset]: annotation = format_annotation(annotations[annotation_offset]) annotation_offset += 1 result.append(("**", args_node.kwarg, annotation, None)) return result def get_return_annotation(node): """Get the return annotation of a node. :type node: astroid.nodes.FunctionDef """ return_annotation = None if node.returns: return_annotation = format_annotation(node.returns) elif node.type_comment_returns: return_annotation = format_annotation(node.type_comment_returns) return return_annotation def get_func_docstring(node): """Get the docstring of a node, using a parent docstring if needed. :param node: The node to get a docstring for. :type node: astroid.nodes.FunctionDef """ doc = node.doc if doc is None and isinstance(node.parent, astroid.nodes.ClassDef): for base in node.parent.ancestors(): if node.name in ("__init__", "__new__") and base.qname() in ( "__builtins__.object", "builtins.object", "builtins.type", ): continue for child in base.get_children(): if ( isinstance(child, node.__class__) and child.name == node.name and child.doc is not None ): return child.doc return doc or "" def get_class_docstring(node): """Get the docstring of a node, using a parent docstring if needed. :param node: The node to get a docstring for. :type node: astroid.nodes.ClassDef """ doc = node.doc if doc is None: for base in node.ancestors(): if base.qname() in ( "__builtins__.object", "builtins.object", "builtins.type", ): continue if base.doc is not None: return base.doc return doc or "" sphinx-autoapi-1.8.4/autoapi/mappers/python/mapper.py000066400000000000000000000363171410652014100227710ustar00rootroot00000000000000import collections import copy import operator import os import re import sphinx.environment import sphinx.util from sphinx.util.console import bold import sphinx.util.docstrings import sphinx.util.logging from ..base import SphinxMapperBase from .parser import Parser from .objects import ( PythonClass, PythonFunction, PythonModule, PythonMethod, PythonPackage, PythonAttribute, PythonData, PythonException, ) LOGGER = sphinx.util.logging.getLogger(__name__) def _expand_wildcard_placeholder(original_module, originals_map, placeholder): """Expand a wildcard placeholder to a sequence of named placeholders. :param original_module: The data dictionary of the module that the placeholder is imported from. :type original_module: dict :param originals_map: A map of the names of children under the module to their data dictionaries. :type originals_map: dict(str, dict) :param placeholder: The wildcard placeholder to expand. :type placeholder: dict :returns: The placeholders that the wildcard placeholder represents. :rtype: list(dict) """ originals = originals_map.values() if original_module["all"] is not None: originals = [] for name in original_module["all"]: if name == "__all__": continue if name not in originals_map: msg = "Invalid __all__ entry {0} in {1}".format( name, original_module["name"] ) LOGGER.warning(msg, type="autoapi", subtype="python_import_resolution") continue originals.append(originals_map[name]) placeholders = [] for original in originals: new_full_name = placeholder["full_name"].replace("*", original["name"]) new_original_path = placeholder["original_path"].replace("*", original["name"]) if "original_path" in original: new_original_path = original["original_path"] new_placeholder = dict( placeholder, name=original["name"], full_name=new_full_name, original_path=new_original_path, ) placeholders.append(new_placeholder) return placeholders def _resolve_module_placeholders(modules, module_name, visit_path, resolved): """Resolve all placeholder children under a module. :param modules: A mapping of module names to their data dictionary. Placeholders are resolved in place. :type modules: dict(str, dict) :param module_name: The name of the module to resolve. :type module_name: str :param visit_path: An ordered set of visited module names. :type visited: collections.OrderedDict :param resolved: A set of already resolved module names. :type resolved: set(str) """ if module_name in resolved: return visit_path[module_name] = True module, children = modules[module_name] for child in list(children.values()): if child["type"] != "placeholder": continue if child["original_path"] in modules: module["children"].remove(child) children.pop(child["name"]) continue imported_from, original_name = child["original_path"].rsplit(".", 1) if imported_from in visit_path: msg = "Cannot resolve cyclic import: {0}, {1}".format( ", ".join(visit_path), imported_from ) LOGGER.warning(msg, type="autoapi", subtype="python_import_resolution") module["children"].remove(child) children.pop(child["name"]) continue if imported_from not in modules: msg = "Cannot resolve import of unknown module {0} in {1}".format( imported_from, module_name ) LOGGER.warning(msg, type="autoapi", subtype="python_import_resolution") module["children"].remove(child) children.pop(child["name"]) continue _resolve_module_placeholders(modules, imported_from, visit_path, resolved) if original_name == "*": original_module, originals_map = modules[imported_from] # Replace the wildcard placeholder # with a list of named placeholders. new_placeholders = _expand_wildcard_placeholder( original_module, originals_map, child ) child_index = module["children"].index(child) module["children"][child_index : child_index + 1] = new_placeholders children.pop(child["name"]) for new_placeholder in new_placeholders: if new_placeholder["name"] not in children: children[new_placeholder["name"]] = new_placeholder original = originals_map[new_placeholder["name"]] _resolve_placeholder(new_placeholder, original) elif original_name not in modules[imported_from][1]: msg = "Cannot resolve import of {0} in {1}".format( child["original_path"], module_name ) LOGGER.warning(msg, type="autoapi", subtype="python_import_resolution") module["children"].remove(child) children.pop(child["name"]) continue else: original = modules[imported_from][1][original_name] _resolve_placeholder(child, original) del visit_path[module_name] resolved.add(module_name) def _resolve_placeholder(placeholder, original): """Resolve a placeholder to the given original object. :param placeholder: The placeholder to resolve, in place. :type placeholder: dict :param original: The object that the placeholder represents. :type original: dict """ new = copy.deepcopy(original) # We are supposed to be resolving the placeholder, # not replacing it with another. assert original["type"] != "placeholder" # The name remains the same. new["name"] = placeholder["name"] new["full_name"] = placeholder["full_name"] # Record where the placeholder originally came from. new["original_path"] = original["full_name"] # The source lines for this placeholder do not exist in this file. # The keys might not exist if original is a resolved placeholder. new.pop("from_line_no", None) new.pop("to_line_no", None) # Resolve the children stack = list(new.get("children", ())) while stack: child = stack.pop() # Relocate the child to the new location assert child["full_name"].startswith(original["full_name"]) suffix = child["full_name"][len(original["full_name"]) :] child["full_name"] = new["full_name"] + suffix # The source lines for this placeholder do not exist in this file. # The keys might not exist if original is a resolved placeholder. child.pop("from_line_no", None) child.pop("to_line_no", None) # Resolve the remaining children stack.extend(child.get("children", ())) placeholder.clear() placeholder.update(new) def _link_objs(value): result = "" delims = r"(\s*[\[\]\(\),]\s*)" delims_re = re.compile(delims) sub_targets = re.split(delims, value.strip()) for sub_target in sub_targets: sub_target = sub_target.strip() if delims_re.match(sub_target): result += f"{sub_target}" if sub_target.endswith(","): result += " " else: result += "\\ " elif sub_target: result += f":py:obj:`{sub_target}`\\ " # Strip off the extra "\ " return result[:-2] class PythonSphinxMapper(SphinxMapperBase): """Auto API domain handler for Python Parses directly from Python files. :param app: Sphinx application passed in as part of the extension """ _OBJ_MAP = { cls.type: cls for cls in ( PythonClass, PythonFunction, PythonModule, PythonMethod, PythonPackage, PythonAttribute, PythonData, PythonException, ) } _OBJ_MAP["property"] = PythonMethod def __init__(self, app, template_dir=None, url_root=None): super(PythonSphinxMapper, self).__init__(app, template_dir, url_root) self.jinja_env.filters["link_objs"] = _link_objs self._use_implicit_namespace = ( self.app.config.autoapi_python_use_implicit_namespaces ) def _need_to_load(self, files): last_files = getattr(self.app.env, "autoapi_source_files", []) self.app.env.autoapi_source_files = files last_mtime = getattr(self.app.env, "autoapi_max_mtime", 0) this_mtime = max(os.path.getmtime(file) for _, file in files) self.app.env.autoapi_max_mtime = this_mtime if not self.app.config.autoapi_keep_files: return True if self.app.env.config_status != sphinx.environment.CONFIG_OK: return True return last_files != files or not last_mtime or last_mtime < this_mtime def _find_files(self, patterns, dirs, ignore): for dir_ in dirs: dir_root = dir_ if ( os.path.exists(os.path.join(dir_, "__init__.py")) or self._use_implicit_namespace ): dir_root = os.path.abspath(os.path.join(dir_, os.pardir)) for path in self.find_files(patterns=patterns, dirs=[dir_], ignore=ignore): yield dir_root, path def load(self, patterns, dirs, ignore=None): """Load objects from the filesystem into the ``paths`` dictionary Also include an attribute on the object, ``relative_path`` which is the shortened, relative path the package/module """ dir_root_files = list(self._find_files(patterns, dirs, ignore)) if not self._need_to_load(dir_root_files): LOGGER.debug( "[AutoAPI] Skipping read stage because source files have not changed." ) return False for dir_root, path in sphinx.util.status_iterator( dir_root_files, bold("[AutoAPI] Reading files... "), length=len(dir_root_files), stringify_func=(lambda x: x[1]), ): data = self.read_file(path=path, dir_root=dir_root) if data: data["relative_path"] = os.path.relpath(path, dir_root) self.paths[path] = data return True def read_file(self, path, **kwargs): """Read file input into memory, returning deserialized objects :param path: Path of file to read """ dir_root = kwargs.get("dir_root") try: if self._use_implicit_namespace: parsed_data = Parser().parse_file_in_namespace(path, dir_root) else: parsed_data = Parser().parse_file(path) return parsed_data except (IOError, TypeError, ImportError): LOGGER.debug("Reason:", exc_info=True) LOGGER.warning( "Unable to read file: {0}".format(path), type="autoapi", subtype="not_readable", ) return None def _resolve_placeholders(self): """Resolve objects that have been imported from elsewhere.""" modules = {} for module in self.paths.values(): children = {child["name"]: child for child in module["children"]} modules[module["name"]] = (module, children) resolved = set() for module_name in modules: visit_path = collections.OrderedDict() _resolve_module_placeholders(modules, module_name, visit_path, resolved) def map(self, options=None): self._resolve_placeholders() self.app.env.autoapi_annotations = {} super(PythonSphinxMapper, self).map(options) parents = {obj.name: obj for obj in self.objects.values()} for obj in self.objects.values(): parent_name = obj.name.rsplit(".", 1)[0] if parent_name in parents and parent_name != obj.name: parent = parents[parent_name] attr = "sub{}s".format(obj.type) getattr(parent, attr).append(obj) for obj in self.objects.values(): 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 :param data: dictionary data of parser output """ try: cls = self._OBJ_MAP[data["type"]] except KeyError: # this warning intentionally has no (sub-)type LOGGER.warning("Unknown type: %s" % data["type"]) else: obj = cls( data, class_content=self.app.config.autoapi_python_class_content, options=self.app.config.autoapi_options, jinja_env=self.jinja_env, app=self.app, **kwargs, ) obj.url_root = self.url_root for child_data in data.get("children", []): for child_obj in self.create_class( child_data, options=options, **kwargs ): obj.children.append(child_obj) # Some objects require children to establish their docstring # or type annotations (eg classes with inheritance), # so do this after all children have been created. lines = obj.docstring.splitlines() lines.append("") # Add back the trailing newline that .splitlines removes if lines and "autodoc-process-docstring" in self.app.events.events: self.app.emit( "autodoc-process-docstring", cls.type, obj.name, None, None, lines ) obj.docstring = "\n".join(lines) self._record_typehints(obj) # Parser gives children in source order already if self.app.config.autoapi_member_order == "alphabetical": obj.children.sort(key=operator.attrgetter("name")) elif self.app.config.autoapi_member_order == "groupwise": obj.children.sort(key=lambda x: (x.member_order, x.name)) yield obj def _record_typehints(self, obj): if ( isinstance(obj, (PythonClass, PythonFunction, PythonMethod)) and not obj.overloads ): obj_annotations = {} include_return_annotation = True obj_data = obj.obj if isinstance(obj, PythonClass): constructor = obj.constructor if constructor: include_return_annotation = False obj_data = constructor.obj else: return for _, name, annotation, _ in obj_data["args"]: if name and annotation: obj_annotations[name] = annotation return_annotation = obj_data["return_annotation"] if include_return_annotation and return_annotation: obj_annotations["return"] = return_annotation self.app.env.autoapi_annotations[obj.id] = obj_annotations sphinx-autoapi-1.8.4/autoapi/mappers/python/objects.py000066400000000000000000000303261410652014100231300ustar00rootroot00000000000000import functools from typing import Optional import sphinx.util.logging from ..base import PythonMapperBase LOGGER = sphinx.util.logging.getLogger(__name__) def _format_args(args_info, include_annotations=True, ignore_self=None): result = [] for i, (prefix, name, annotation, default) in enumerate(args_info): if i == 0 and name == ignore_self: continue formatted = "{}{}{}{}".format( prefix or "", name or "", ": {}".format(annotation) if annotation and include_annotations else "", (" = {}" if annotation else "={}").format(default) if default else "", ) result.append(formatted) return ", ".join(result) class PythonPythonMapper(PythonMapperBase): """A base class for all types of representations of Python objects. :var name: The name given to this object. :vartype name: str :var id: A unique identifier for this object. :vartype id: str :var children: The members of this object. :vartype children: list(PythonPythonMapper) """ language = "python" is_callable = False member_order = 0 def __init__(self, obj, class_content="class", **kwargs): super(PythonPythonMapper, self).__init__(obj, **kwargs) self.name = obj["name"] self.id = obj.get("full_name", self.name) # Optional self.children = [] self._docstring = obj["doc"] self._docstring_resolved = False self.imported = "original_path" in obj self.inherited = obj.get("inherited", False) """Whether this was inherited from an ancestor of the parent class. :type: bool """ # For later self._class_content = class_content self._display_cache = None # type: Optional[bool] @property def docstring(self): """The docstring for this object. If a docstring did not exist on the object, this will be the empty string. For classes this will also depend on the :confval:`autoapi_python_class_content` option. :type: str """ return self._docstring @docstring.setter def docstring(self, value): self._docstring = value self._docstring_resolved = True @property def is_undoc_member(self): """Whether this object has a docstring (False) or not (True). :type: bool """ return not bool(self.docstring) @property def is_private_member(self): """Whether this object is private (True) or not (False). :type: bool """ return self.short_name.startswith("_") and not self.short_name.endswith("__") @property def is_special_member(self): """Whether this object is a special member (True) or not (False). :type: bool """ return self.short_name.startswith("__") and self.short_name.endswith("__") @property def display(self): """Whether this object should be displayed in documentation. This attribute depends on the configuration options given in :confval:`autoapi_options` and the result of :event:`autoapi-skip-member`. :type: bool """ if self._display_cache is None: self._display_cache = not self._ask_ignore(self._should_skip()) return self._display_cache @property def summary(self): """The summary line of the docstring. The summary line is the first non-empty line, as-per :pep:`257`. This will be the empty string if the object does not have a docstring. :type: str """ for line in self.docstring.splitlines(): line = line.strip() if line: return line return "" def _should_skip(self): # type: () -> bool skip_undoc_member = self.is_undoc_member and "undoc-members" not in self.options skip_private_member = ( self.is_private_member and "private-members" not in self.options ) skip_special_member = ( self.is_special_member and "special-members" not in self.options ) skip_imported_member = self.imported and "imported-members" not in self.options return ( skip_undoc_member or skip_private_member or skip_special_member or skip_imported_member ) def _ask_ignore(self, skip): # type: (bool) -> bool ask_result = self.app.emit_firstresult( "autoapi-skip-member", self.type, self.id, self, skip, self.options ) return ask_result if ask_result is not None else skip def _children_of_type(self, type_): return list(child for child in self.children if child.type == type_) class PythonFunction(PythonPythonMapper): """The representation of a function.""" type = "function" is_callable = True member_order = 40 def __init__(self, obj, **kwargs): super(PythonFunction, self).__init__(obj, **kwargs) autodoc_typehints = getattr(self.app.config, "autodoc_typehints", "signature") show_annotations = autodoc_typehints != "none" and not ( autodoc_typehints == "description" and not obj["overloads"] ) self.args = _format_args(obj["args"], show_annotations) """The arguments to this object, formatted as a string. :type: str """ self.return_annotation = obj["return_annotation"] if show_annotations else None """The type annotation for the return type of this function. This will be ``None`` if an annotation or annotation comment was not given. :type: str or None """ self.properties = obj["properties"] """The properties that describe what type of function this is. Can be only be: async :type: list(str) """ self.overloads = [ (_format_args(args), return_annotation) for args, return_annotation in obj["overloads"] ] """The list of overloaded signatures ``[(args, return_annotation), ...]`` of this function. :type: list(tuple(str, str)) """ class PythonMethod(PythonFunction): """The representation of a method.""" type = "method" is_callable = True member_order = 50 def __init__(self, obj, **kwargs): super(PythonMethod, self).__init__(obj, **kwargs) self.method_type = obj.get("method_type") """The type of method that this object represents. This can be one of: method, staticmethod, or classmethod. :type: str """ self.properties = obj["properties"] """The properties that describe what type of method this is. Can be any of: abstractmethod, async, classmethod, property, staticmethod :type: list(str) """ def _should_skip(self): # type: () -> bool skip = super(PythonMethod, self)._should_skip() or self.name in ( "__new__", "__init__", ) return self._ask_ignore(skip) class PythonData(PythonPythonMapper): """Global, module level data.""" type = "data" member_order = 10 def __init__(self, obj, **kwargs): super(PythonData, self).__init__(obj, **kwargs) self.value = obj.get("value") """The value of this attribute. This will be ``None`` if the value is not constant. :type: str or None """ self.annotation = obj.get("annotation") """The type annotation of this attribute. This will be ``None`` if an annotation or annotation comment was not given. :type: str or None """ class PythonAttribute(PythonData): """An object/class level attribute.""" type = "attribute" member_order = 10 class TopLevelPythonPythonMapper(PythonPythonMapper): """A common base class for modules and packages.""" _RENDER_LOG_LEVEL = "VERBOSE" def __init__(self, obj, **kwargs): super(TopLevelPythonPythonMapper, self).__init__(obj, **kwargs) self.top_level_object = "." not in self.name """Whether this object is at the very top level (True) or not (False). This will be False for subpackages and submodules. :type: bool """ self.subpackages = [] self.submodules = [] self.all = obj["all"] """The contents of ``__all__`` if assigned to. Only constants are included. This will be ``None`` if no ``__all__`` was set. :type: list(str) or None """ @property def functions(self): """All of the member functions. :type: list(PythonFunction) """ return self._children_of_type("function") @property def classes(self): """All of the member classes. :type: list(PythonClass) """ return self._children_of_type("class") class PythonModule(TopLevelPythonPythonMapper): """The representation of a module.""" type = "module" class PythonPackage(TopLevelPythonPythonMapper): """The representation of a package.""" type = "package" class PythonClass(PythonPythonMapper): """The representation of a class.""" type = "class" member_order = 30 def __init__(self, obj, **kwargs): super(PythonClass, self).__init__(obj, **kwargs) self.bases = obj["bases"] """The fully qualified names of all base classes. :type: list(str) """ @property def args(self): """The arguments to this object, formatted as a string. :type: str """ args = "" if self.constructor: autodoc_typehints = getattr( self.app.config, "autodoc_typehints", "signature" ) show_annotations = autodoc_typehints != "none" and not ( autodoc_typehints == "description" and not self.constructor.overloads ) args_data = self.constructor.obj["args"] args = _format_args(args_data, show_annotations, ignore_self="self") return args @property def overloads(self): overloads = [] if self.constructor: overload_data = self.constructor.obj["overloads"] autodoc_typehints = getattr( self.app.config, "autodoc_typehints", "signature" ) show_annotations = autodoc_typehints not in ("none", "description") overloads = [ ( _format_args(args, show_annotations, ignore_self="self"), return_annotation, ) for args, return_annotation in overload_data ] return overloads @property def docstring(self): docstring = super().docstring if not self._docstring_resolved and self._class_content in ("both", "init"): constructor_docstring = self.constructor_docstring if constructor_docstring: if self._class_content == "both": docstring = "{0}\n{1}".format(docstring, constructor_docstring) else: docstring = constructor_docstring return docstring @docstring.setter def docstring(self, value): super(PythonClass, self.__class__).docstring.fset(self, value) @property def methods(self): return self._children_of_type("method") @property def attributes(self): return self._children_of_type("attribute") @property def classes(self): return self._children_of_type("class") @property @functools.lru_cache() def constructor(self): for child in self.children: if child.short_name == "__init__": return child return None @property def constructor_docstring(self): docstring = "" constructor = self.constructor if constructor and constructor.docstring: docstring = constructor.docstring else: for child in self.children: if child.short_name == "__new__": docstring = child.docstring break return docstring class PythonException(PythonClass): """The representation of an exception class.""" type = "exception" member_order = 20 sphinx-autoapi-1.8.4/autoapi/mappers/python/parser.py000066400000000000000000000216741410652014100230010ustar00rootroot00000000000000import collections import itertools import os import astroid import astroid.builder import sphinx.util.docstrings from . import astroid_utils def _prepare_docstring(doc): return "\n".join(sphinx.util.docstrings.prepare_docstring(doc)) class Parser: def __init__(self): self._name_stack = [] self._encoding = None def _get_full_name(self, name): return ".".join(self._name_stack + [name]) def _parse_file(self, file_path, condition): directory, filename = os.path.split(file_path) module_parts = [] if filename != "__init__.py": module_part = os.path.splitext(filename)[0] module_parts = [module_part] module_parts = collections.deque(module_parts) while directory and condition(directory): directory, module_part = os.path.split(directory) if module_part: module_parts.appendleft(module_part) module_name = ".".join(module_parts) node = astroid.builder.AstroidBuilder().file_build(file_path, module_name) return self.parse(node) def parse_file(self, file_path): return self._parse_file( file_path, lambda directory: os.path.isfile(os.path.join(directory, "__init__.py")), ) def parse_file_in_namespace(self, file_path, dir_root): return self._parse_file( file_path, lambda directory: os.path.abspath(directory) != dir_root ) def parse_annassign(self, node): return self.parse_assign(node) def parse_assign(self, node): doc = "" doc_node = node.next_sibling() if isinstance(doc_node, astroid.nodes.Expr) and isinstance( doc_node.value, astroid.nodes.Const ): doc = doc_node.value.value type_ = "data" if isinstance( node.scope(), astroid.nodes.ClassDef ) or astroid_utils.is_constructor(node.scope()): type_ = "attribute" assign_value = astroid_utils.get_assign_value(node) if not assign_value: return [] target = assign_value[0] value = assign_value[1] annotation = astroid_utils.get_assign_annotation(node) data = { "type": type_, "name": target, "full_name": self._get_full_name(target), "doc": _prepare_docstring(doc), "value": value, "from_line_no": node.fromlineno, "to_line_no": node.tolineno, "annotation": annotation, } return [data] def parse_classdef(self, node, data=None): type_ = "class" if astroid_utils.is_exception(node): type_ = "exception" basenames = list(astroid_utils.get_full_basenames(node)) data = { "type": type_, "name": node.name, "full_name": self._get_full_name(node.name), "bases": basenames, "doc": _prepare_docstring(astroid_utils.get_class_docstring(node)), "from_line_no": node.fromlineno, "to_line_no": node.tolineno, "children": [], } self._name_stack.append(node.name) overridden = set() overloads = {} for base in itertools.chain(iter((node,)), node.ancestors()): seen = set() if base.qname() in ( "__builtins__.object", "builtins.object", "builtins.type", ): continue for child in base.get_children(): name = getattr(child, "name", None) if isinstance(child, (astroid.Assign, astroid.AnnAssign)): assign_value = astroid_utils.get_assign_value(child) if not assign_value: continue name = assign_value[0] if not name or name in overridden: continue seen.add(name) child_data = self.parse(child) data["children"].extend( _parse_child(node, child_data, overloads, base, name) ) overridden.update(seen) self._name_stack.pop() return [data] def parse_asyncfunctiondef(self, node): return self.parse_functiondef(node) def parse_functiondef(self, node): # pylint: disable=too-many-branches if astroid_utils.is_decorated_with_property_setter(node): return [] type_ = "method" properties = [] if node.type == "function": type_ = "function" elif astroid_utils.is_decorated_with_property(node): type_ = "property" properties.append("property") else: # "__new__" method is implicit classmethod if node.type in ("staticmethod", "classmethod") and node.name != "__new__": properties.append(node.type) if node.is_abstract(pass_is_abstract=False): properties.append("abstractmethod") if isinstance(node, astroid.AsyncFunctionDef): properties.append("async") data = { "type": type_, "name": node.name, "full_name": self._get_full_name(node.name), "args": astroid_utils.get_args_info(node.args), "doc": _prepare_docstring(astroid_utils.get_func_docstring(node)), "from_line_no": node.fromlineno, "to_line_no": node.tolineno, "return_annotation": astroid_utils.get_return_annotation(node), "properties": properties, "is_overload": astroid_utils.is_decorated_with_overload(node), "overloads": [], } if type_ in ("method", "property"): data["method_type"] = node.type result = [data] if node.name == "__init__": for child in node.get_children(): if isinstance(child, (astroid.nodes.Assign, astroid.nodes.AnnAssign)): child_data = self.parse_assign(child) result.extend(data for data in child_data if data["doc"]) return result def _parse_local_import_from(self, node): result = [] for name, alias in node.names: is_wildcard = (alias or name) == "*" full_name = self._get_full_name(alias or name) original_path = astroid_utils.get_full_import_name(node, alias or name) data = { "type": "placeholder", "name": original_path if is_wildcard else (alias or name), "full_name": full_name, "original_path": original_path, } result.append(data) return result def parse_module(self, node): path = node.path if isinstance(node.path, list): path = node.path[0] if node.path else None type_ = "module" if node.package: type_ = "package" self._name_stack = [node.name] self._encoding = node.file_encoding data = { "type": type_, "name": node.name, "full_name": node.name, "doc": _prepare_docstring(node.doc or ""), "children": [], "file_path": path, "encoding": node.file_encoding, "all": astroid_utils.get_module_all(node), } overloads = {} top_name = node.name.split(".", 1)[0] for child in node.get_children(): if astroid_utils.is_local_import_from(child, top_name): child_data = self._parse_local_import_from(child) else: child_data = self.parse(child) data["children"].extend(_parse_child(node, child_data, overloads)) return data def parse(self, node): data = {} node_type = node.__class__.__name__.lower() parse_func = getattr(self, "parse_" + node_type, None) if parse_func: data = parse_func(node) else: for child in node.get_children(): data = self.parse(child) if data: break return data def _parse_child(node, child_data, overloads, base=None, name=None): result = [] for single_data in child_data: if single_data["type"] in ("function", "method", "property"): if name is None: name = single_data["name"] if name in overloads: grouped = overloads[name] grouped["doc"] = single_data["doc"] if single_data["is_overload"]: grouped["overloads"].append( (single_data["args"], single_data["return_annotation"]) ) continue if single_data["is_overload"] and name not in overloads: overloads[name] = single_data if base: single_data["inherited"] = base is not node result.append(single_data) return result sphinx-autoapi-1.8.4/autoapi/settings.py000066400000000000000000000003371410652014100203460ustar00rootroot00000000000000""" Basic settings for AutoAPI projects. You shouldn't need to touch this. """ import os SITE_ROOT = os.path.dirname(os.path.realpath(__file__)) TEMPLATE_DIR = os.path.join(SITE_ROOT, "templates") API_ROOT = "autoapi" sphinx-autoapi-1.8.4/autoapi/templates/000077500000000000000000000000001410652014100201275ustar00rootroot00000000000000sphinx-autoapi-1.8.4/autoapi/templates/base/000077500000000000000000000000001410652014100210415ustar00rootroot00000000000000sphinx-autoapi-1.8.4/autoapi/templates/base/base.rst000066400000000000000000000001301410652014100224770ustar00rootroot00000000000000.. {{ obj.type }}:: {{ obj.name }} {% if summary %} {{ obj.summary }} {% endif %} sphinx-autoapi-1.8.4/autoapi/templates/dotnet/000077500000000000000000000000001410652014100214245ustar00rootroot00000000000000sphinx-autoapi-1.8.4/autoapi/templates/dotnet/base_detail.rst000066400000000000000000000025341410652014100244160ustar00rootroot00000000000000{% block title %} {{ obj.short_name }} {{ obj.type.title()}} {{ "=" * (obj.short_name|length + obj.type|length + 1) }} {% endblock %} {% block summary %} {% if obj.summary %} {{ obj.summary }} {% endif %} {% endblock %} {% if obj.namespace %} Namespace :dn:ns:`{{ obj.namespace }}` {% endif %} {% if obj.assemblies %} Assemblies {% for assembly in obj.assemblies %} * {{ assembly }} {% endfor %} {% endif %} ---- .. contents:: :local: {% block inheritance %} {% if obj.inheritance %} Inheritance Hierarchy --------------------- {% for item in obj.inheritance %} * :dn:{{ item.ref_directive }}:`{{ item.ref_name }}` {% endfor %} * :dn:{{ obj.ref_directive }}:`{{ obj.ref_name }}` {% endif %} {% endblock %} {% block syntax %} {% if obj.example %} Syntax ------ .. code-block:: csharp {{ obj.example|indent(4) }} {% endif %} {% endblock %} {% block content %} .. dn:{{ obj.ref_type }}:: {{ obj.definition }} :hidden: .. dn:{{ obj.ref_type }}:: {{ obj.name }} {% for item_type in obj.item_map.keys() %} {% if item_type in obj.item_map %} {{ item_type.title() }} {{ "-" * item_type|length }} .. dn:{{ obj.ref_type }}:: {{ obj.name }} :noindex: :hidden: {% for obj_item in obj.item_map.get(item_type, []) %} {{ obj_item.render()|indent(4) }} {% endfor %} {% endif %} {% endfor %} {% endblock %} sphinx-autoapi-1.8.4/autoapi/templates/dotnet/base_embed.rst000066400000000000000000000012351410652014100242250ustar00rootroot00000000000000.. dn:{{ obj.ref_type }}:: {{ obj.name }} {% if obj.summary %} {{ obj.summary|indent(4) }} {% endif %} {% for param in obj.parameters %} {% if param.desc %} :param {{ param.name }}: {{ param.desc|indent(8) }} {% endif %} {% if param.type %} :type {{ param.name }}: {{ param.type|indent(8) }} {% endif %} {% endfor %} {% if obj.returns.type %} :rtype: {{ obj.returns.type|indent(8) }} {% endif %} {% if obj.returns.description %} :return: {{ obj.returns.description|indent(8) }} {% endif %} {% if obj.example %} .. code-block:: csharp {{ obj.example|indent(8) }} {% endif %} sphinx-autoapi-1.8.4/autoapi/templates/dotnet/base_list.rst000066400000000000000000000022261410652014100241250ustar00rootroot00000000000000{% block title %} {{ obj.name }} {{ obj.type.title() }} {{ "=" * (obj.name|length + obj.type|length + 1) }} {% endblock %} {% block toc %} {% if obj.children %} .. toctree:: :hidden: :maxdepth: 2 {% for item in obj.children|sort %} {% if item.type != 'namespace' %} {{ item.include_path }} {% endif %} {% endfor %} {% endif %} {% if obj.references %} .. toctree:: :hidden: :maxdepth: 2 {% for item in obj.references|sort %} {% if item.type != 'namespace' %} {{ item.include_path }} {% endif %} {% endfor %} {% endif %} {% endblock %} {% block content %} {% macro display_type(item_type) %} .. rubric:: {{ item_type.title() }} {% for obj_item in obj.item_map.get(item_type, []) %} {% macro render() %}{{ obj_item.summary }}{% endmacro %} {{ obj_item.type }} :dn:{{ obj_item.ref_directive }}:`{{ obj_item.ref_short_name }}` .. object: type={{ obj_item.type }} name={{ obj_item.ref_name }} {{ render()|indent(8) }} {% endfor %} {% endmacro %} .. dn:{{ obj.ref_type }}:: {{ obj.name }} {% for item_type in obj.item_map.keys() %} {{ display_type(item_type) }} {% endfor %} {% endblock %} sphinx-autoapi-1.8.4/autoapi/templates/dotnet/class.rst000066400000000000000000000000461410652014100232630ustar00rootroot00000000000000{% extends "dotnet/base_detail.rst" %}sphinx-autoapi-1.8.4/autoapi/templates/dotnet/constructor.rst000066400000000000000000000000451410652014100245420ustar00rootroot00000000000000{% extends "dotnet/base_embed.rst" %}sphinx-autoapi-1.8.4/autoapi/templates/dotnet/delegate.rst000066400000000000000000000000461410652014100237300ustar00rootroot00000000000000{% extends "dotnet/base_detail.rst" %}sphinx-autoapi-1.8.4/autoapi/templates/dotnet/enum.rst000066400000000000000000000000461410652014100231220ustar00rootroot00000000000000{% extends "dotnet/base_detail.rst" %}sphinx-autoapi-1.8.4/autoapi/templates/dotnet/event.rst000066400000000000000000000000451410652014100232760ustar00rootroot00000000000000{% extends "dotnet/base_embed.rst" %}sphinx-autoapi-1.8.4/autoapi/templates/dotnet/field.rst000066400000000000000000000000451410652014100232400ustar00rootroot00000000000000{% extends "dotnet/base_embed.rst" %}sphinx-autoapi-1.8.4/autoapi/templates/dotnet/interface.rst000066400000000000000000000000461410652014100241160ustar00rootroot00000000000000{% extends "dotnet/base_detail.rst" %}sphinx-autoapi-1.8.4/autoapi/templates/dotnet/method.rst000066400000000000000000000000451410652014100234350ustar00rootroot00000000000000{% extends "dotnet/base_embed.rst" %}sphinx-autoapi-1.8.4/autoapi/templates/dotnet/namespace.rst000066400000000000000000000000441410652014100241100ustar00rootroot00000000000000{% extends "dotnet/base_list.rst" %}sphinx-autoapi-1.8.4/autoapi/templates/dotnet/operator.rst000066400000000000000000000000451410652014100240100ustar00rootroot00000000000000{% extends "dotnet/base_embed.rst" %}sphinx-autoapi-1.8.4/autoapi/templates/dotnet/property.rst000066400000000000000000000000451410652014100240410ustar00rootroot00000000000000{% extends "dotnet/base_embed.rst" %}sphinx-autoapi-1.8.4/autoapi/templates/dotnet/struct.rst000066400000000000000000000000461410652014100235020ustar00rootroot00000000000000{% extends "dotnet/base_detail.rst" %}sphinx-autoapi-1.8.4/autoapi/templates/go/000077500000000000000000000000001410652014100205345ustar00rootroot00000000000000sphinx-autoapi-1.8.4/autoapi/templates/go/base_member.rst000066400000000000000000000016621410652014100235340ustar00rootroot00000000000000{% if obj.type == 'func' %} {# Creating the parameters line #} {% set ns = namespace(tmpstring='') %} {% set argjoin = joiner(', ') %} {% for param in obj.parameters %} {% set ns.tmpstring = ns.tmpstring ~ argjoin() ~ param.name ~ ' ' ~ param.type %} {% endfor %} .. go:{{ obj.ref_type }}:: {{ obj.name }}({{ ns.tmpstring }}) {% else %} .. go:{{ obj.ref_type }}:: {{ obj.name }} {% endif %} {% macro render() %}{{ obj.docstring }}{% endmacro %} {{ render()|indent(4) }} {# Don't define parameter description here, that can be done in the block above #} {% for param in obj.parameters %} :param {{ param.name }}: :type {{ param.name }}: {{ param.type }} {% endfor %} {% if obj.returns %} :rtype: {{ obj.returns.type }} {% endif %} {% if obj.children %} {% for child in obj.children|sort %} {% macro render_child() %}{{ child.render() }}{% endmacro %} {{ render_child()|indent(4) }} {% endfor %} {% endif %} sphinx-autoapi-1.8.4/autoapi/templates/go/const.rst000066400000000000000000000000431410652014100224110ustar00rootroot00000000000000{% extends "go/base_member.rst" %} sphinx-autoapi-1.8.4/autoapi/templates/go/func.rst000066400000000000000000000000431410652014100222160ustar00rootroot00000000000000{% extends "go/base_member.rst" %} sphinx-autoapi-1.8.4/autoapi/templates/go/method.rst000066400000000000000000000000431410652014100225430ustar00rootroot00000000000000{% extends "go/base_member.rst" %} sphinx-autoapi-1.8.4/autoapi/templates/go/package.rst000066400000000000000000000010411410652014100226550ustar00rootroot00000000000000.. go:package:: {{ obj.name }} {{ obj.name }} {{ "=" * obj.name|length }} {% block toc %} {% if obj.children %} {# TODO Make this work .. toctree:: :maxdepth: 4 {% for item in obj.children|sort %} /autoapi/{{ item.id.split('.')|join('/') }}/index {% endfor %} #} {% endif %} {% endblock %} {% if obj.docstring %} {{ obj.docstring }} {% endif %} {% block content %} {% for obj_item in obj.children|sort %} {% macro render() %}{{ obj_item.render() }}{% endmacro %} {{ render()|indent(0) }} {% endfor %} {% endblock %} sphinx-autoapi-1.8.4/autoapi/templates/go/type.rst000066400000000000000000000000431410652014100222440ustar00rootroot00000000000000{% extends "go/base_member.rst" %} sphinx-autoapi-1.8.4/autoapi/templates/go/var.rst000066400000000000000000000000431410652014100220530ustar00rootroot00000000000000{% extends "go/base_member.rst" %} sphinx-autoapi-1.8.4/autoapi/templates/index.rst000066400000000000000000000005431410652014100217720ustar00rootroot00000000000000API Reference ============= This page contains auto-generated API reference documentation [#f1]_. .. toctree:: :titlesonly: {% for page in pages %} {% if page.top_level_object and page.display %} {{ page.include_path }} {% endif %} {% endfor %} .. [#f1] Created with `sphinx-autoapi `_ sphinx-autoapi-1.8.4/autoapi/templates/javascript/000077500000000000000000000000001410652014100222755ustar00rootroot00000000000000sphinx-autoapi-1.8.4/autoapi/templates/javascript/class.rst000066400000000000000000000005651410652014100241420ustar00rootroot00000000000000.. js:class:: {{ obj.name }}{% if obj.args %}({{ obj.args|join(',') }}){% endif %} {% if obj.docstring %} .. rubric:: Summary {{ obj.docstring|indent(3) }} {% endif %} {% if obj.methods %} {% for method in obj.methods %} {% macro render() %}{{ method.render() }}{% endmacro %} {{ render()|indent(3) }} {%- endfor %} {% endif %} sphinx-autoapi-1.8.4/autoapi/templates/javascript/function.rst000066400000000000000000000005051410652014100246540ustar00rootroot00000000000000{# Identention in this file is important #} {% if is_method %} {# Slice self off #} .. js:method:: {{ obj.name.split('.')[-1] }}({{ args[1:]|join(',') }}) {% else %} .. js:function:: {{ obj.name.split('.')[-1] }}({{ args|join(',') }}) {% endif %} {% if obj.docstring %} {{ obj.docstring|indent(3) }} {% endif %} sphinx-autoapi-1.8.4/autoapi/templates/javascript/member.rst000066400000000000000000000001671410652014100243020ustar00rootroot00000000000000{# Identention in this file is important #} .. js:{{ obj.type }}:: {{ obj.name }} {{ obj.docstring|indent(3) }} sphinx-autoapi-1.8.4/autoapi/templates/javascript/module.rst000066400000000000000000000014261410652014100243170ustar00rootroot00000000000000{{ obj.name }} {{ "-" * obj.name|length }} {% block toc %} {% if obj.children %} .. toctree:: :maxdepth: 4 {% for item in obj.children|sort %} /autoapi/{{ item.pathname }}/index {%- endfor %} {% endif %} {% endblock %} {% if obj.docstring %} .. rubric:: Summary {{ obj.docstring }} {% endif %} .. js:module:: {{ obj.name }} {% block content %} {%- macro display_type(item_type) %} {{ item_type.title() }} {{ "*" * item_type|length }} {%- for obj_item in obj.item_map.get(item_type, []) %} {% macro render() %}{{ obj_item.render() }}{% endmacro %} {{ render()|indent(4) }} {%- endfor %} {%- endmacro %} {%- for item_type in obj.item_map.keys() %} {% if item_type.lower() != 'module' %} {{ display_type(item_type) }} {% endif %} {%- endfor %} {% endblock %} sphinx-autoapi-1.8.4/autoapi/templates/python/000077500000000000000000000000001410652014100214505ustar00rootroot00000000000000sphinx-autoapi-1.8.4/autoapi/templates/python/attribute.rst000066400000000000000000000000401410652014100241770ustar00rootroot00000000000000{% extends "python/data.rst" %} sphinx-autoapi-1.8.4/autoapi/templates/python/class.rst000066400000000000000000000035041410652014100233110ustar00rootroot00000000000000{% if obj.display %} .. py:{{ obj.type }}:: {{ obj.short_name }}{% if obj.args %}({{ obj.args }}){% endif %} {% for (args, return_annotation) in obj.overloads %} {{ " " * (obj.type | length) }} {{ obj.short_name }}{% if args %}({{ args }}){% endif %} {% endfor %} {% if obj.bases %} {% if "show-inheritance" in autoapi_options %} Bases: {% for base in obj.bases %}{{ base|link_objs }}{% if not loop.last %}, {% endif %}{% endfor %} {% endif %} {% if "show-inheritance-diagram" in autoapi_options and obj.bases != ["object"] %} .. autoapi-inheritance-diagram:: {{ obj.obj["full_name"] }} :parts: 1 {% if "private-members" in autoapi_options %} :private-bases: {% endif %} {% endif %} {% endif %} {% if obj.docstring %} {{ obj.docstring|indent(3) }} {% endif %} {% if "inherited-members" in autoapi_options %} {% set visible_classes = obj.classes|selectattr("display")|list %} {% else %} {% set visible_classes = obj.classes|rejectattr("inherited")|selectattr("display")|list %} {% endif %} {% for klass in visible_classes %} {{ klass.render()|indent(3) }} {% endfor %} {% if "inherited-members" in autoapi_options %} {% set visible_attributes = obj.attributes|selectattr("display")|list %} {% else %} {% set visible_attributes = obj.attributes|rejectattr("inherited")|selectattr("display")|list %} {% endif %} {% for attribute in visible_attributes %} {{ attribute.render()|indent(3) }} {% endfor %} {% if "inherited-members" in autoapi_options %} {% set visible_methods = obj.methods|selectattr("display")|list %} {% else %} {% set visible_methods = obj.methods|rejectattr("inherited")|selectattr("display")|list %} {% endif %} {% for method in visible_methods %} {{ method.render()|indent(3) }} {% endfor %} {% endif %} sphinx-autoapi-1.8.4/autoapi/templates/python/data.rst000066400000000000000000000013561410652014100231200ustar00rootroot00000000000000{% if obj.display %} .. py:{{ obj.type }}:: {{ obj.name }} {%+ if obj.value is not none or obj.annotation is not none -%} :annotation: {%- if obj.annotation %} :{{ obj.annotation }} {%- endif %} {%- if obj.value is not none %} = {% if obj.value is string and obj.value.splitlines()|count > 1 -%} Multiline-String .. raw:: html
Show Value .. code-block:: text :linenos: {{ obj.value|indent(width=8) }} .. raw:: html
{%- else -%} {{ obj.value|string|truncate(100) }} {%- endif %} {%- endif %} {% endif %} {{ obj.docstring|indent(3) }} {% endif %} sphinx-autoapi-1.8.4/autoapi/templates/python/exception.rst000066400000000000000000000000411410652014100241730ustar00rootroot00000000000000{% extends "python/class.rst" %} sphinx-autoapi-1.8.4/autoapi/templates/python/function.rst000066400000000000000000000011031410652014100240220ustar00rootroot00000000000000{% if obj.display %} .. py:function:: {{ obj.short_name }}({{ obj.args }}){% if obj.return_annotation is not none %} -> {{ obj.return_annotation }}{% endif %} {% for (args, return_annotation) in obj.overloads %} {{ obj.short_name }}({{ args }}){% if return_annotation is not none %} -> {{ return_annotation }}{% endif %} {% endfor %} {% if sphinx_version >= (2, 1) %} {% for property in obj.properties %} :{{ property }}: {% endfor %} {% endif %} {% if obj.docstring %} {{ obj.docstring|indent(3) }} {% else %} {% endif %} {% endif %} sphinx-autoapi-1.8.4/autoapi/templates/python/method.rst000066400000000000000000000015031410652014100234610ustar00rootroot00000000000000{%- if obj.display %} {% if sphinx_version >= (2, 1) %} .. py:method:: {{ obj.short_name }}({{ obj.args }}){% if obj.return_annotation is not none %} -> {{ obj.return_annotation }}{% endif %} {% for (args, return_annotation) in obj.overloads %} {{ obj.short_name }}({{ args }}){% if return_annotation is not none %} -> {{ return_annotation }}{% endif %} {% endfor %} {% if obj.properties %} {% for property in obj.properties %} :{{ property }}: {% endfor %} {% else %} {% endif %} {% else %} .. py:{{ obj.method_type }}:: {{ obj.short_name }}({{ obj.args }}) {% for (args, return_annotation) in obj.overloads %} {{ " " * (obj.method_type | length) }} {{ obj.short_name }}({{ args }}) {% endfor %} {% endif %} {% if obj.docstring %} {{ obj.docstring|indent(3) }} {% endif %} {% endif %} sphinx-autoapi-1.8.4/autoapi/templates/python/module.rst000066400000000000000000000045701410652014100234750ustar00rootroot00000000000000{% if not obj.display %} :orphan: {% endif %} :py:mod:`{{ obj.name }}` =========={{ "=" * obj.name|length }} .. py:module:: {{ obj.name }} {% if obj.docstring %} .. autoapi-nested-parse:: {{ obj.docstring|indent(3) }} {% endif %} {% block subpackages %} {% set visible_subpackages = obj.subpackages|selectattr("display")|list %} {% if visible_subpackages %} Subpackages ----------- .. toctree:: :titlesonly: :maxdepth: 3 {% for subpackage in visible_subpackages %} {{ subpackage.short_name }}/index.rst {% endfor %} {% endif %} {% endblock %} {% block submodules %} {% set visible_submodules = obj.submodules|selectattr("display")|list %} {% if visible_submodules %} Submodules ---------- .. toctree:: :titlesonly: :maxdepth: 1 {% for submodule in visible_submodules %} {{ submodule.short_name }}/index.rst {% endfor %} {% endif %} {% endblock %} {% block content %} {% if obj.all is not none %} {% set visible_children = obj.children|selectattr("short_name", "in", obj.all)|list %} {% elif obj.type is equalto("package") %} {% set visible_children = obj.children|selectattr("display")|list %} {% else %} {% set visible_children = obj.children|selectattr("display")|rejectattr("imported")|list %} {% endif %} {% if visible_children %} {{ obj.type|title }} Contents {{ "-" * obj.type|length }}--------- {% set visible_classes = visible_children|selectattr("type", "equalto", "class")|list %} {% set visible_functions = visible_children|selectattr("type", "equalto", "function")|list %} {% set visible_attributes = visible_children|selectattr("type", "equalto", "data")|list %} {% if "show-module-summary" in autoapi_options and (visible_classes or visible_functions) %} {% block classes scoped %} {% if visible_classes %} Classes ~~~~~~~ .. autoapisummary:: {% for klass in visible_classes %} {{ klass.id }} {% endfor %} {% endif %} {% endblock %} {% block functions scoped %} {% if visible_functions %} Functions ~~~~~~~~~ .. autoapisummary:: {% for function in visible_functions %} {{ function.id }} {% endfor %} {% endif %} {% endblock %} {% block attributes scoped %} {% if visible_attributes %} Attributes ~~~~~~~~~~ .. autoapisummary:: {% for attribute in visible_attributes %} {{ attribute.id }} {% endfor %} {% endif %} {% endblock %} {% endif %} {% for obj_item in visible_children %} {{ obj_item.render()|indent(0) }} {% endfor %} {% endif %} {% endblock %} sphinx-autoapi-1.8.4/autoapi/templates/python/package.rst000066400000000000000000000000421410652014100235710ustar00rootroot00000000000000{% extends "python/module.rst" %} sphinx-autoapi-1.8.4/autoapi/toctree.py000066400000000000000000000136261410652014100201600ustar00rootroot00000000000000""" A small Sphinx extension that adds Domain objects (eg. Python Classes & Methods) to the TOC Tree. It dynamically adds them to the already rendered ``app.env.tocs`` dict on the Sphinx environment. Traditionally this only contains Section's, we then nest our Domain references inside the already existing Sections. """ from docutils import nodes from sphinx import addnodes import sphinx.util.logging LOGGER = sphinx.util.logging.getLogger(__name__) def _build_toc_node(docname, anchor="anchor", text="test text", bullet=False): """ Create the node structure that Sphinx expects for TOC Tree entries. The ``bullet`` argument wraps it in a ``nodes.bullet_list``, which is how you nest TOC Tree entries. """ reference = nodes.reference( "", "", internal=True, refuri=docname, anchorname="#" + anchor, *[nodes.Text(text, text)] ) para = addnodes.compact_paragraph("", "", reference) ret_list = nodes.list_item("", para) return nodes.bullet_list("", ret_list) if bullet else ret_list def _traverse_parent(node, objtypes): """ Traverse up the node's parents until you hit the ``objtypes`` referenced. Can either be a single type, or a tuple of types. """ curr_node = node.parent while curr_node is not None: if isinstance(curr_node, objtypes): return curr_node curr_node = curr_node.parent return None def _find_toc_node(toc, ref_id, objtype): """ Find the actual TOC node for a ref_id. Depends on the object type: * Section - First section (refuri) or 2nd+ level section (anchorname) * Desc - Just use the anchor name """ for check_node in toc.traverse(nodes.reference): if objtype == nodes.section and ( check_node.attributes["refuri"] == ref_id or check_node.attributes["anchorname"] == "#" + ref_id ): return check_node if ( objtype == addnodes.desc and check_node.attributes["anchorname"] == "#" + ref_id ): return check_node return None def _get_toc_reference(node, toc, docname): """ Logic that understands maps a specific node to it's part of the toctree. It takes a specific incoming ``node``, and returns the actual TOC Tree node that is said reference. """ if isinstance(node, nodes.section) and isinstance(node.parent, nodes.document): # Top Level Section header ref_id = docname toc_reference = _find_toc_node(toc, ref_id, nodes.section) elif isinstance(node, nodes.section): # Nested Section header ref_id = node.attributes["ids"][0] toc_reference = _find_toc_node(toc, ref_id, nodes.section) else: # Desc node try: ref_id = node.children[0].attributes["ids"][0] toc_reference = _find_toc_node(toc, ref_id, addnodes.desc) except (KeyError, IndexError): LOGGER.warning( "Invalid desc node", exc_info=True, type="autoapi", subtype="toc_reference", ) toc_reference = None return toc_reference def add_domain_to_toctree(app, doctree, docname): """ Add domain objects to the toctree dynamically. This should be attached to the ``doctree-resolved`` event. This works by: * Finding each domain node (addnodes.desc) * Figuring out it's parent that will be in the toctree (nodes.section, or a previously added addnodes.desc) * Finding that parent in the TOC Tree based on it's ID * Taking that element in the TOC Tree, and finding it's parent that is a TOC Listing (nodes.bullet_list) * Adding the new TOC element for our specific node as a child of that nodes.bullet_list * This checks that bullet_list's last child, and checks that it is also a nodes.bullet_list, effectively nesting it under that element """ toc = app.env.tocs[docname] for desc_node in doctree.traverse(addnodes.desc): try: ref_id = desc_node.children[0].attributes["ids"][0] except (KeyError, IndexError): # autodoc-style directives already add nodes to the toc. continue try: # Python domain object ref_text = desc_node[0].attributes["fullname"].split(".")[-1].split("(")[0] except (KeyError, IndexError): # TODO[eric]: Support other Domains and ways of accessing this data # Use `astext` for other types of domain objects ref_text = desc_node[0].astext().split(".")[-1].split("(")[0] # This is the actual object that will exist in the TOC Tree # Sections by default, and other Desc nodes that we've previously placed. parent_node = _traverse_parent( node=desc_node, objtypes=(addnodes.desc, nodes.section) ) if parent_node: toc_reference = _get_toc_reference(parent_node, toc, docname) if toc_reference: # Get the last child of our parent's bullet list, this is where "we" live. toc_insertion_point = _traverse_parent( toc_reference, nodes.bullet_list )[-1] # Ensure we're added another bullet list so that we nest inside the parent, # not next to it if len(toc_insertion_point) > 1 and isinstance( toc_insertion_point[1], nodes.bullet_list ): to_add = _build_toc_node(docname, anchor=ref_id, text=ref_text) toc_insertion_point = toc_insertion_point[1] else: to_add = _build_toc_node( docname, anchor=ref_id, text=ref_text, bullet=True, ) toc_insertion_point.append(to_add) sphinx-autoapi-1.8.4/docs/000077500000000000000000000000001410652014100154175ustar00rootroot00000000000000sphinx-autoapi-1.8.4/docs/conf.py000066400000000000000000000240741410652014100167250ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Sphinx AutoAPI documentation build configuration file, created by # sphinx-quickstart on Wed Apr 22 15:38:18 2015. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = ['autoapi.extension', 'sphinx.ext.intersphinx'] autoapi_type = 'python' autoapi_dirs = ['../autoapi'] autoapi_generate_api_docs = False intersphinx_mapping = { 'jinja': ('https://jinja.palletsprojects.com/en/3.0.x/', None), 'sphinx': ('https://www.sphinx-doc.org/en/master/', None), 'python': ('https://docs.python.org/3/', None), } # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'Sphinx AutoAPI' copyright = u'2015, Read the Docs, Inc' author = u'Read the Docs, Inc' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # import autoapi # The short X.Y version. version = ".".join(str(x) for x in autoapi.__version_info__[:2]) # The full version, including alpha/beta/rc tags. release = autoapi.__version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all # documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. #keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'sphinx_rtd_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. #html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' #html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # Now only 'ja' uses this config value #html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. #html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. htmlhelp_basename = 'SphinxAutoAPIdoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', # Latex figure (float) alignment #'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'SphinxAutoAPI.tex', u'Sphinx AutoAPI Documentation', u'Read the Docs, Inc', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'sphinxautoapi', u'Sphinx AutoAPI Documentation', [author], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'SphinxAutoAPI', u'Sphinx AutoAPI Documentation', author, 'SphinxAutoAPI', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. #texinfo_no_detailmenu = False import re from sphinx import addnodes event_sig_re = re.compile(r'([a-zA-Z-]+)\s*\((.*)\)') def parse_event(env, sig, signode): m = event_sig_re.match(sig) if not m: signode += addnodes.desc_name(sig, sig) return sig name, args = m.groups() signode += addnodes.desc_name(name, name) plist = addnodes.desc_parameterlist() for arg in args.split(','): arg = arg.strip() plist += addnodes.desc_parameter(arg, arg) signode += plist return name def setup(app): from sphinx.util.docfields import TypedField app.add_object_type('confval', 'confval', objname='configuration value', indextemplate='pair: %s; configuration value') fdesc = TypedField('parameter', label='Parameters', names=['param'], typenames=['type'], can_collapse=True) app.add_object_type('event', 'event', 'pair: %s; event', parse_event, doc_field_types=[fdesc]) sphinx-autoapi-1.8.4/docs/how_to.rst000066400000000000000000000111311410652014100174450ustar00rootroot00000000000000How-to Guides ============= .. _customise-templates: How to Customise Layout Through Templates ----------------------------------------- You can customise the look of the documentation that AutoAPI generates by changing the Jinja2 templates that it uses. The default templates live in the ``autoapi/templates`` directory of the AutoAPI package. Simply copy whichever templates you want to customise to a local directory and edit them. To get AutoAPI to use these templates, point the :confval:`autoapi_template_dir` configuration option to your directory. It can be absolute, or relative to the root of the documentation source directory (ie the directory passed to ``sphinx-build``). .. code-block:: python autoapi_template_dir = '_autoapi_templates' Your template directory must to follow the same layout as the default templates. For example, to override the Python class and module templates: .. code-block:: none _autoapi_templates └── python ├── class.rst └── module.rst How to Customise the Index Page ------------------------------- The index page that AutoAPI creates is generated using a template. So customising the index page follows the same steps as customising a template. Simply edit the ``autoapi/templates/index.rst`` template with the same steps as :ref:`customising a template `. How to Remove the Index Page ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To remove the index page altogether, turn off the :confval:`autoapi_add_toctree_entry` configuration option:: autoapi_add_toctree_entry = False You will then need to include the generated documentation in the toctree yourself. For example if you were generating documentation for a package called "example", you would add the following toctree entry:: .. toctree:: autoapi/example/index Note that ``autoapi/`` is the default location of documentation, as configured by :confval:`autoapi_root`. If you change :confval:`autoapi_root`, then the entry that you need to add would change also. How to Configure Where Documentation Appears in the TOC Tree ------------------------------------------------------------ The :confval:`autoapi_root` configuration option defines where generated documentation is output. To change where documentation is output, simply change this option to another directory relative to the documentation source directory: .. code-block:: python autoapi_root = 'technical/api' How to Transition to Autodoc-Style Documentation ---------------------------------------------------- Once you have written some documentation with the :ref:`autodoc-directives`, turning the automatic documentation generation off is as easy as disabling the :confval:`autoapi_generate_api_docs` configuration option:: autoapi_generate_api_docs = False How to Transition to Manual Documentation ----------------------------------------- To start writing API documentation yourself, you can get AutoAPI to keep its generated files around as a base to start from using the :confval:`autoapi_keep_files` option:: autoapi_keep_files = True Once you have built your documentation with this option turned on, you can disable AutoAPI altogether from your project. How to Include Type Annotations as Types in Rendered Docstrings --------------------------------------------------------------- .. warning:: This feature is experimental and may change or be removed in future versions. Since v3.0, :mod:`sphinx` has included an :mod:`sphinx.ext.autodoc.typehints` extension that is capable of rendering type annotations as parameter types and return types. For example the following function: .. code-block:: def _func(a: int, b: Optional[str]) -> bool """My function. :param a: The first arg. :param b: The second arg. :returns: Something. """ would be rendered as: .. py:function:: _func(a, b) :noindex: :param int a: The first arg. :param b: The second arg. :type b: Optional[str] :returns: Something. :rtype: bool AutoAPI is capable of the same thing. To enable this behaviour, load the :mod:`sphinx.ext.autodoc.typehints` (or :mod:`sphinx.ext.autodoc`) extension in Sphinx's ``conf.py`` file and set :confval:`autodoc_typehints` to ``description`` as normal:: extensions = ['sphinx.ext.autodoc', 'autoapi.extension'] autodoc_typehints = 'description' .. note:: Unless :confval:`autodoc_typehints` is set to ``none``, the type annotations of overloads will always be output in the signature and never merged into the description because it is impossible to represent all overloads as a list of parameters. sphinx-autoapi-1.8.4/docs/index.rst000066400000000000000000000001761410652014100172640ustar00rootroot00000000000000Sphinx AutoAPI ============== .. toctree:: :maxdepth: 2 :glob: tutorials how_to reference/* maintenance/* sphinx-autoapi-1.8.4/docs/maintenance/000077500000000000000000000000001410652014100177015ustar00rootroot00000000000000sphinx-autoapi-1.8.4/docs/maintenance/design.rst000066400000000000000000000144411410652014100217100ustar00rootroot00000000000000Design Reference ================ Python ------ When choosing what to document, AutoAPI aims to document anything that is publicly accessible through the actual package when loaded in Python. For example if a function is imported from a submodule into a package, that function is documented in both the submodule and the package. There are some exceptions to this rule: * Anything that is imported into a module is not documented. Usually a module is where implementations exist. Therefore an import of something is usually for the usage of the implementation, and not as something to be accessed publicly. * When the module or package defines an ``__all__``, only the members named in ``__all__`` are documented. * When a configuration option indicates that private or special members should also be documented. Furthermore, AutoAPI follows the same docstring inheritance rules as :func:`inspect.getdoc`, with some exceptions: * The docstrings of the following methods are not inherited because they are usually redundant: * :meth:`object.__init__` * :meth:`object.__new__` * :meth:`type.__init__` * :meth:`type.__new__` .NET ---- This document talks about the design of a .NET Sphinx integration. This will include a mechanism for generating Javadoc style API references automatically. We will describe decisions that lead to specific implementation details. Goals ----- The main goal of this project is to be able to generate a MSDN or Javadoc style API reference from a .Net project in Sphinx. Primary Goals ~~~~~~~~~~~~~ * Build MSDN/Javadoc style HTML output for arbitrary .Net code. * Have specific pages for each Package, Class, and all class-level structures. - `/api/System/` - `/api/System/String/` - `/api/System/String/Constructors/` Secondary Goals ~~~~~~~~~~~~~~~ * Allow for definition of .Net classes inside of normal Sphinx prose docs (classic Sphinx style definition). * Allow generation of Javadoc style docs from other languages. Requirements ~~~~~~~~~~~~ Introduction ------------ We are working with Sphinx, which has an existing way of doing this. Generally, you define a `Domain` which describes the various language structure, a *Class* or *Method*, for example. Then the user will write RST that uses these definitions, and Sphinx will create output from that markup. .. code-block:: rst .. py:function:: spam(eggs) Spam the foo. The author of the doucmentation will have now told Sphinx that the *spam* function exists in the Python project that is being documented. Autogenerated Output ~~~~~~~~~~~~~~~~~~~~ Sphinx then built a series of tools to make the generation of this markup easier and more automatic: * `Autodoc `_ * `Autosummary `_ Autodoc is a Python-only solution that imports the author's code into memory, and then allows the author to more automatically document full objects. For example, you can document a whole class on a page. .. code-block:: py .. autoclass:: Noodle This will generate output that looks like: .. class:: Noodle Noodle's docstring. There are also options for it to include a full listing of the classes attributes, methods, and other things, automatically. .. warning:: Remember, this depends on ``Noodle`` being importable by the Python interpreter running Sphinx. Proposed Architecture --------------------- The proposed architecture for this project is as follows: * A program that will generate a YAML (or JSON) file from a .Net project, representing it's full API information. * Read the YAML and generate an appropriate tree structure that will the outputted HTML will look like (YAMLTree) - If time allows, we will allow a merging of these objects with multiple YAML files to allow for prose content to be injected into the output * Take the YAML structure and generate in-memory rst that corresponds to the Sphinx dotnet Domain objects * dotnet Domain will output HTML based on the doctree generated from the in-memory RST In diagram form:: Code -> YAML -> YAMLTree -> RST (Dotnet Domain) -> Sphinx -> HTML YAMLTree ~~~~~~~~ One of the main problems is how to actually structure the outputted HTML pages. The YAML file will likely be ordered, but we need to have a place to define the page structure in the HTML. This can be done before or after the loading of the content into RST. We decided to do it before loading into RST because that matches standard Sphinx convention. Generally the markup being fed in as RST is considered to be in a file that maps to it's output loation. If we tried to maniuplate this structure after loading into the Domain, that could lead to unexpected consequences like wrong indexes and missing references. File Structure vs. Hierarchy ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Specific ID's should have one specific detail representation. This means that every YAML docid object should only have one place that it is rendered with a ``.. dn:`` canonical identifier. All other places it is referenced should be in either: * A reference * A toctree (listing) Sphinx Implementation ~~~~~~~~~~~~~~~~~~~~~ The user will run a normal `make html` as part of the experience. The generation and loading will be done as an extension that can be configured. There will be Sphinx configuration for how things get built: .. code-block:: rst autoapi_root = 'api' # Where HTML is generated autoapi_dirs = ['yaml'] # Directory of YAML sources We will then loop over all YAML files in the ``autoapi_dir`` and parse them. They will then be output into ``autoapi_root`` inside the documentation. Examples -------- A nice example of Sphinx Python output similar to what we want: * http://dta.googlecode.com/git/doc/_build/html/index.html * Src: https://raw.githubusercontent.com/sfcta/dta/master/doc/index.rst An example domain for Spec: * https://subversion.xray.aps.anl.gov/bcdaext/specdomain/trunk/src/specdomain/sphinxcontrib/specdomain.py Other Ideas ----------- .. warning:: Things in this section might not get implemented. The .Net domain will not be able to depend on importing code from the users code base. We might be able to implement similar authoring tools with the YAML file. We might be able to output the YAML subtree of an object with autodoc style tools: .. code-block:: rst .. autodnclass:: System.String :members: sphinx-autoapi-1.8.4/docs/maintenance/release-process.rst000066400000000000000000000014101410652014100235230ustar00rootroot00000000000000Release Process =============== This page documents the steps to be taken to release a new version of Sphinx AutoAPI. Pre-Checks ---------- 1. Check that the dependencies of the package are correct. 2. Clean the ``.tox`` directory and run the tests. 3. Commit and push any changes needed to make the tests pass. 4. Check that the tests passed on github. Preparation ----------- 1. Update the version numbers in ``autoapi/__init__.py``. 2. Add any missing changelog entries. 3. Put the version number and release date into the changelog. 4. Commit and push the changes. 5. Check that the tests passed on github. Release ------- .. code-block:: bash git clean -fdx python setup.py sdist bdist_wheel twine upload dist/* git tag vX.X.X git push --tags sphinx-autoapi-1.8.4/docs/reference/000077500000000000000000000000001410652014100173555ustar00rootroot00000000000000sphinx-autoapi-1.8.4/docs/reference/config.rst000066400000000000000000000235431410652014100213630ustar00rootroot00000000000000Configuration Options ===================== .. confval:: autoapi_dirs **Required** Paths (relative or absolute) to the source code that you wish to generate your API documentation from. The paths are searched recursively for files matching :confval:`autoapi_file_patterns`. Relative paths should be relative to the source directory of your documentation. For Python, if a package directory is specified, the package directory itself will be included in the relative path of the children. If an ordinary directory is specified, that directory will not be included in the relative path. .. confval:: autoapi_type Default: ``python`` Set the type of files you are documenting. This depends on the programming language that you are using: ========== ================ Language ``autoapi_type`` ========== ================ Python ``'python'`` Go ``'go'`` Javascript ``'javascript'`` .NET ``'dotnet'`` ========== ================ .. confval:: autoapi_template_dir Default: ``''`` A directory that has user-defined templates to override our default templates. The path can either be absolute, or relative to the source directory of your documentation files. An path relative to where `sphinx-build` is run is allowed for backwards compatibility only and will be removed in a future version. You can view the default templates in the `autoapi/templates `_ directory of the package. .. confval:: autoapi_file_patterns Default: Varies by Language A list containing the file patterns to look for when generating documentation. Patterns should be listed in order of preference. For example, if ``autoapi_file_patterns`` is set to the default value and a `.py` file and a `.pyi` file are found, then the `.py` will be read. The defaults by language are: ========== ============================================ Language ``autoapi_file_patterns`` ========== ============================================ Python ``['*.py', '*.pyi']`` Go ``['*.go']`` Javascript ``['*.js']`` .NET ``['project.json', '*.csproj', '*.vbproj']`` ========== ============================================ .. confval:: autoapi_generate_api_docs Default: ``True`` Whether to generate API documentation. If this is ``False``, documentation should be generated though the :doc:`directives`. Customisation Options --------------------- .. confval:: autoapi_options Default: [ ``'members'``, ``'undoc-members'``, ``'private-members'``, ``'show-inheritance'``, ``'show-module-summary'``, ``'special-members'``, ``'imported-members'``, ] Options for display of the generated documentation. * ``members``: Display children of an object * ``inherited-members``: Display children of an object that have been inherited from a base class. * ``undoc-members``: Display objects that have no docstring * ``private-members``: Display private objects (eg. ``_foo`` in Python) * ``special-members``: Display special objects (eg. ``__foo__`` in Python) * ``show-inheritance``: Display a list of base classes below the class signature. * ``show-inheritance-diagram``: Display an inheritance diagram in generated class documentation. It makes use of the :mod:`sphinx.ext.inheritance_diagram` extension, and requires `Graphviz `_ to be installed. * ``show-module-summary``: Whether to include autosummary directives in generated module documentation. * ``imported-members``: Display objects imported from the same top level package or module. The default module template does not include imported objects, even with this option enabled. The default package template does. .. confval:: autoapi_ignore Default: Varies By Language A list of patterns to ignore when finding files. The defaults by language are: ========== ============================================ Language ``autoapi_file_patterns`` ========== ============================================ Python ``['*migrations*']`` Go ``[]`` Javascript ``[]`` .NET ``['*toc.yml', '*index.yml']`` ========== ============================================ .. confval:: autoapi_root Default: ``autoapi`` Path to output the generated AutoAPI files into, including the generated index page. This path must be relative to the source directory of your documentation files. This can be used to place the generated documentation anywhere in your documentation hierarchy. .. confval:: autoapi_add_toctree_entry Default: ``True`` Whether to insert the generated documentation into the TOC tree. If this is ``False``, the default AutoAPI index page is not generated and you will need to include the generated documentation in a TOC tree entry yourself. .. confval:: autoapi_python_class_content Default: ``class`` Which docstring to insert into the content of a class. * ``class``: Use only the class docstring. * ``both``: Use the concatentation of the class docstring and the ``__init__`` docstring. * ``init``: Use only the ``__init__`` docstring. If the class does not have an ``__init__`` or the ``__init__`` docstring is empty and the class defines a ``__new__`` with a docstring, the ``__new__`` docstring is used instead of the ``__init__`` docstring. .. confval:: autoapi_member_order Default: ``bysource`` The order to document members. This option can have the following values: * ``alphabetical``: Order members by their name, case sensitively. * ``bysource``: Order members by the order that they were defined in the source code. * ``groupwise``: Order members by their type then alphabetically, ordering the types as follows: * Submodules and subpackages * Attributes * Exceptions * Classes * Functions * Methods .. confval:: autoapi_python_use_implicit_namespaces Default: ``False`` This changes the package detection behaviour to be compatible with :pep:`420`, but directories in :confval:`autoapi_dirs` are no longer searched recursively for packages. Instead, when this is ``True``, :confval:`autoapi_dirs` should point directly to the directories of implicit namespaces and the directories of packages. If searching is still required, this should be done manually in the ``conf.py``. .. confval:: autoapi_prepare_jinja_env Default: ``None`` A callback that is called shortly after the Jinja environment is created. It passed the Jinja environment for editing before template rendering begins. The callback should have the following signature: .. py:function:: prepare_jinja_env(jinja_env: jinja2.Environment) -> None :noindex: Events ~~~~~~ The following events allow you to control the behaviour of AutoAPI. .. event:: autoapi-skip-member (app, what, name, obj, skip, options) (Python only) Emitted when a template has to decide whether a member should be included in the documentation. Usually the member is skipped if a handler returns ``True``, and included otherwise. Handlers should return ``None`` to fall back to the default skipping behaviour of AutoAPI or another attached handler. .. code-block:: python :caption: Example conf.py def skip_util_classes(app, what, name, obj, skip, options): if what == "class" and "util" in name: skip = True return skip def setup(sphinx): sphinx.connect("autoapi-skip-member", skip_util_classes) :param app: The Sphinx application object. :param what: The type of the object which the docstring belongs to. This can be one of: ``"attribute"``, ``"class"``, ``"data"``, ``"exception"``, ``"function"``, ``"method"``, ``"module"``, ``"package"``. :type what: str :param name: The fully qualified name of the object. :type name: str :param obj: The object itself. :type obj: PythonPythonMapper :param skip: Whether AutoAPI will skip this member if the handler does not override the decision. :type skip: bool :param options: The options given to the directive. Advanced Options ----------------- .. confval:: autoapi_keep_files Default: ``False`` Keep the AutoAPI generated files on the filesystem after the run. Useful for debugging or transitioning to manual documentation. Keeping files will also allow AutoAPI to use incremental builds. Providing none of the source files have changed, AutoAPI will skip parsing the source code and regenerating the API documentation. Suppressing Warnings --------------------- .. confval:: suppress_warnings This is a sphinx builtin option that enables the granular filtering of AutoAPI generated warnings. Items in the ``suppress_warnings`` list are of the format ``"type.subtype"`` where ``".subtype"`` can be left out to cover all subtypes. To suppress all AutoAPI warnings add the type ``"autoapi"`` to the list: .. code-block:: python suppress_warnings = ["autoapi"] If narrower suppression is wanted, the available subtypes for AutoAPI are: * python_import_resolution Used if resolving references to objects in an imported module failed. Potential reasons include cyclical imports and missing (parent) modules. * not_readable Emitted if processing (opening, parsing, ...) an input file failed. * toc_reference Used if a reference to an entry in a table of content cannot be resolved. So if all AutoAPI warnings concerning unreadable sources and failing Python imports should be filtered, but all other warnings should not, the option would be .. code-block:: python suppress_warnings = ["autoapi.python_import_resolution", "autoapi.not_readable"] sphinx-autoapi-1.8.4/docs/reference/directives.rst000066400000000000000000000040031410652014100222450ustar00rootroot00000000000000Directives ========== .. _autodoc-directives: Autodoc-Style Directives ------------------------ You can opt to write API documentation yourself using autodoc style directives. These directives work similarly to autodoc, but docstrings are retrieved through static analysis instead of through imports. .. seealso:: When transitioning to autodoc-style documentation, you may want to turn the :confval:`autoapi_generate_api_docs` option off so that automatic API documentation is no longer generated. To use these directives you will need to enable the autodoc extension in your Sphinx project's ``conf.py``: .. code:: python extensions = ['sphinx.ext.autodoc', 'autoapi.extension'] For Python, all directives have an autodoc equivalent and accept the same options. The following directives are available: .. rst:directive:: autoapimodule autoapiclass autoapiexception Equivalent to :rst:dir:`automodule`, :rst:dir:`autoclass`, and :rst:dir:`autoexception` respectively. :confval:`autodoc_inherit_docstrings` does not currently work. .. rst:directive:: autoapifunction autoapidata autoapimethod autoapiattribute Equivalent to :rst:dir:`autofunction`, :rst:dir:`autodata`, :rst:dir:`automethod`, and :rst:dir:`autoattribute` respectively. Inheritance Diagrams -------------------- .. rst:directive:: autoapi-inheritance-diagram This directive uses the :mod:`sphinx.ext.inheritance_diagram` extension to create inheritance diagrams for classes. For example: .. autoapi-inheritance-diagram:: autoapi.mappers.python.objects.PythonModule autoapi.mappers.python.objects.PythonPackage :parts: 1 :mod:`sphinx.ext.inheritance_diagram` makes use of the :mod:`sphinx.ext.graphviz` extension, and therefore it requires `Graphviz `_ to be installed. The directive can be configured using the same options as :mod:`sphinx.ext.inheritance_diagram`. sphinx-autoapi-1.8.4/docs/reference/templates.rst000066400000000000000000000056541410652014100221170ustar00rootroot00000000000000Templates ========= A lot of the power from AutoAPI comes from templates. We are basically building a mapping from code to docs, and templates let you highly customise the display of said docs. Structure --------- Every type of data structure has its own template. It uses the form :samp:`{language}/{type}.rst` to find the template to render. The full search path is: * :samp:`{language}/{type}.rst` So for a .NET Class, this would resolve to: * :samp:`dotnet/class.rst` We provide :samp:`base/base.rst` as an incredibly basic output of every object:: .. {language}:{type}:: {name} Custom Filters, Tests, and Globals ---------------------------------- The :confval:`autoapi_prepare_jinja_env` configuration option allows you to pass a callback that can edit the :class:`jinja2.Environment` object before rendering begins. This callback, among other things, can be used to add custom filters, tests, and/or globals to the Jinja environment. For example: .. code-block:: python def autoapi_prepare_jinja_env(jinja_env): jinja_env.filters["my_custom_filter"] = lambda value: value.upper() Context ------- Every template is given a set context that can be accessed in the templates. This contains: * ``autoapi_options``: The value of the :confval:`autoapi_options` configuration option. * ``include_summaries``: The value of the :confval:`autoapi_include_summaries` configuration option. * ``obj``: A Python object derived from :class:`PythonMapperBase`. * ``sphinx_version``: The contents of :attr:`sphinx.version_info`. The object in ``obj`` has a number of standard attributes that you can reliably access per language. .. warning:: These classes should not be constructed manually. They can be reliably accessed through templates only. Python ~~~~~~ .. autoapiclass:: autoapi.mappers.python.objects.PythonPythonMapper :members: .. autoapiclass:: autoapi.mappers.python.objects.PythonFunction :members: :show-inheritance: .. autoapiclass:: autoapi.mappers.python.objects.PythonMethod :members: :show-inheritance: .. autoapiclass:: autoapi.mappers.python.objects.PythonData :members: :show-inheritance: .. autoapiclass:: autoapi.mappers.python.objects.PythonAttribute :members: :show-inheritance: .. autoapiclass:: autoapi.mappers.python.objects.TopLevelPythonPythonMapper :members: :show-inheritance: .. autoapiclass:: autoapi.mappers.python.objects.PythonModule :members: :show-inheritance: .. autoapiclass:: autoapi.mappers.python.objects.PythonPackage :members: :show-inheritance: .. autoapiclass:: autoapi.mappers.python.objects.PythonClass :members: :show-inheritance: .. autoapiclass:: autoapi.mappers.python.objects.PythonException :members: :show-inheritance: Go ~~~ .. autoapiclass:: autoapi.mappers.go.GoPythonMapper :members: Javascript ~~~~~~~~~~ .. autoapiclass:: autoapi.mappers.javascript.JavaScriptPythonMapper :members: .NET ~~~~ .. autoapiclass:: autoapi.mappers.dotnet.DotNetPythonMapper :members: sphinx-autoapi-1.8.4/docs/tutorials.rst000066400000000000000000000163131410652014100202030ustar00rootroot00000000000000Tutorials ========= Setting up Automatic API Documentation Generation ------------------------------------------------- This tutorial will assume that you already have a basic Sphinx project set up. If you are not sure how to do this, you can follow the :doc:`sphinx:usage/quickstart` guide in the Sphinx documentation. The recommended way of installing AutoAPI is through a `virtualenv `_. Once you have a virtualenv set up, you can install AutoAPI with the command: ========== ====================================== Language Command ========== ====================================== Python ``pip install sphinx-autoapi`` Go ``pip install sphinx-autoapi[go]`` Javascript ``pip install sphinx-autoapi`` .NET ``pip install sphinx-autoapi[dotnet]`` ========== ====================================== Depending on which language you are trying to document, each language has a different set of steps for finishing the setup of AutoAPI: .. contents:: :local: :backlinks: none Python ^^^^^^ To enable the extension, we need to add it to the list of extensions in Sphinx's ``conf.py`` file:: extensions = ['autoapi.extension'] For Python, there is only one required configuration option that we need to set. :confval:`autoapi_dirs` tells AutoAPI which directories contain the source code to document. These can either be absolute, or relative to the source directory of your documentation files. For example, say we have a package and we have used ``sphinx-quickstart`` to create a Sphinx project in a ``docs/`` folder. The directory structure might look like this: .. code-block:: none mypackage/ ├── docs │   ├── _build │   ├── conf.py │   ├── index.rst │   ├── make.bat │   ├── Makefile │   ├── _static │   └── _templates ├── mypackage │   ├── _client.py │   ├── __init__.py │   └── _server.py └── README.md ``sphinx-quickstart`` sets up the ``sphinx-build`` to run from inside the ``docs/`` directory, and the source code is one level up. So the value of our :confval:`autoapi_dirs` option would be:: autoapi_dirs = ['../mypackage'] If you are documenting many packages, you can point AutoAPI to the directory that contains those packages. For example if our source code was inside a ``src/`` directory: .. code-block:: none mypackage/ ├── docs │   ├── _build │   ├── conf.py │   ├── index.rst │   ├── make.bat │   ├── Makefile │   ├── _static │   └── _templates ├── README.md └── src └── mypackage ├── _client.py ├── __init__.py └── _server.py We can configure :confval:`autoapi_dirs` to be:: autoapi_dirs = ['../src'] Now that everything is configured, AutoAPI will generate documentation when you run Sphinx! .. code-block:: bash cd docs/ sphinx-build -b html . _build Go ^^^ Support for Go requires you to have the go environment installed (https://golang.org/dl/), as well as our godocjson tool:: go get github.com/readthedocs/godocjson and the Go domain extension for Sphinx:: pip install sphinxcontrib-golangdomain To enable the AutoAPI extension, we need to add it to the list of extensions in Sphinx's ``conf.py`` file with the Go domain extension:: extensions = [ 'sphinxcontrib.golangdomain', 'autoapi.extension', ] For Go, there are two required configuration options that we need to set. :confval:`autoapi_type` tells AutoAPI what type of language we are documenting. For Go, this is:: autoapi_type = 'go' The second configuration option is :confval:`autoapi_dirs`, which tells AutoAPI which directories contain the source code to document. These can either be absolute, or relative to the source directory of your documentation files. So if your documentation was inside a ``docs/`` directory and your source code is in an ``example`` directory one level up, you would configure :confval:`autoapi_dirs` to be:: autoapi_dirs = ['../example'] Now that everything is configured, AutoAPI will generate documentation when you run Sphinx! .. code-block:: bash cd docs/ sphinx-build -b html . _build Javascript ^^^^^^^^^^ Support for Javascript requires you to have jsdoc (http://usejsdoc.org/) installed:: npm install jsdoc -g To enable the AutoAPI extension, we need to add it to the list of extensions in Sphinx's ``conf.py`` file:: extensions = ['autoapi.extension'] For Javascript, there are two required configuration options that we need to set. :confval:`autoapi_type` tells AutoAPI what type of language we are documenting. For Javascript, this is:: autoapi_type = 'javascript' The second configuration option is :confval:`autoapi_dirs`, which tells AutoAPI which directories contain the source code to document. These can either be absolute, or relative to the source directory of your documentation files. So if your documentation was inside a ``docs/`` directory and your source code is in an ``example`` directory one level up, you would configure :confval:`autoapi_dirs` to be:: autoapi_dirs = ['../example'] Now that everything is configured, AutoAPI will generate documentation when you run Sphinx! .. code-block:: bash cd docs/ sphinx-build -b html . _build .NET ^^^^ Support for .NET requires you to have the docfx (https://dotnet.github.io/docfx/) tool installed, as well as the .NET domain extension for Sphinx:: pip install sphinxcontrib-dotnetdomain Firstly, we need to configure docfx to output to a directory known to AutoAPI. By default, ``docfx`` will output metadata files into the ``_api`` path. You can configure which path to output files into by setting the path in your `docfx configuration file `_ in your project repository. For example, if your documentation source files are located inside a ``docs/`` directory: .. code:: json { "metadata": [{ "dest": "docs/_api" }] } To enable the AutoAPI extension, we need to add it to the list of extensions in Sphinx's ``conf.py`` file with the .NET domain extension:: extensions = [ 'sphinxcontrib.dotnetdomain', 'autoapi.extension', ] For .NET, there are two required configuration options that we need to set. :confval:`autoapi_type` tells AutoAPI what type of language we are documenting. For .NET, this is:: autoapi_type = 'dotnet' The second configuration option is :confval:`autoapi_dirs`, which tells AutoAPI which directories contain the source code to document. These can either be absolute, or relative to the source directory of your documentation files. So if your documentation was inside a ``docs/`` directory and your source code is in an ``example`` directory one level up, you would configure :confval:`autoapi_dirs` to be:: autoapi_dirs = ['../example'] Now that everything is configured, AutoAPI will generate documentation when you run Sphinx! .. code-block:: bash cd docs/ sphinx-build -b html . _build sphinx-autoapi-1.8.4/pylintrc000066400000000000000000000006251410652014100162610ustar00rootroot00000000000000[MASTER] load-plugins= [MESSAGES CONTROL] disable=bad-continuation, duplicate-code, fixme, import-error, missing-class-docstring, missing-function-docstring, missing-module-docstring, too-few-public-methods, too-many-locals, too-many-instance-attributes, useless-object-inheritance enable=c-extension-no-member [BASIC] good-names=i,j,id,_ sphinx-autoapi-1.8.4/pyproject.toml000066400000000000000000000001421410652014100174000ustar00rootroot00000000000000[build-system] requires = ["setuptools>=46.4.0", "wheel"] build-backend = "setuptools.build_meta" sphinx-autoapi-1.8.4/setup.cfg000066400000000000000000000025351410652014100163150ustar00rootroot00000000000000[metadata] name = sphinx-autoapi version = attr: autoapi.__version__ author = Eric Holscher author_email = eric@ericholscher.com maintainer = Ashley Whetter maintainer_email = ashley@awhetter.co.uk description = Sphinx API documentation generator long_description = file: README.rst long_description_content_type = text/x-rst url = http://github.com/readthedocs/sphinx-autoapi license = MIT license_files = LICENSE.rst classifiers = Development Status :: 4 - Beta Environment :: Plugins Framework :: Sphinx :: Extension Intended Audience :: Developers License :: OSI Approved :: MIT License Natural Language :: English Programming Language :: Python Programming Language :: Python :: 3 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 project_urls = Documentation = https://sphinx-autoapi.readthedocs.io/en/latest/ [options] packages = find: include_package_data = True python_requires = >=3.6 install_requires = astroid>=2.7 Jinja2 PyYAML sphinx>=3.0 unidecode [options.extras_require] docs = sphinx sphinx_rtd_theme go = sphinxcontrib-golangdomain dotnet = sphinxcontrib-dotnetdomain [options.packages.find] include = autoapi autoapi.* [bdist_wheel] universal = 1 sphinx-autoapi-1.8.4/setup.py000066400000000000000000000000451410652014100162000ustar00rootroot00000000000000from setuptools import setup setup() sphinx-autoapi-1.8.4/tests/000077500000000000000000000000001410652014100156315ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/dotnetexample/000077500000000000000000000000001410652014100205025ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/dotnetexample/Makefile000066400000000000000000000165251410652014100221530ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " applehelp to make an Apple Help Book" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " coverage to run coverage check of the documentation (if enabled)" clean: rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SphinxAutoAPI.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SphinxAutoAPI.qhc" applehelp: $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp @echo @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." @echo "N.B. You won't be able to view it unless you put it in" \ "~/Library/Documentation/Help or install it in your application" \ "bundle." devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/SphinxAutoAPI" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/SphinxAutoAPI" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." coverage: $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage @echo "Testing of coverage in the sources finished, look at the " \ "results in $(BUILDDIR)/coverage/python.txt." xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." livehtml: sphinx-autobuild -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html sphinx-autoapi-1.8.4/tests/dotnetexample/README.md000066400000000000000000000005061410652014100217620ustar00rootroot00000000000000## .NET example This assumes that you have a ``docfx`` executable on your `PATH`. It also depends on the sphinxcontrib-dotnet domain: https://github.com/readthedocs/sphinxcontrib-dotnetdomain Currently this is setup to build the Indentity repo from ASP.Net You should simply be able to run ``make html`` in this directory. sphinx-autoapi-1.8.4/tests/dotnetexample/conf.py000066400000000000000000000015241410652014100220030ustar00rootroot00000000000000# -*- coding: utf-8 -*- templates_path = ["_templates"] source_suffix = ".rst" master_doc = "index" project = u"dotnetexample" 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 = "sphinx_rtd_theme" htmlhelp_basename = "dotnetexampledoc" extensions = ["autoapi.extension", "sphinxcontrib.dotnetdomain"] autoapi_type = "dotnet" # Turn this on for debugging # autoapi_keep_files = True autoapi_dirs = ["example/Identity/src/"] import os SITE_ROOT = os.path.dirname(os.path.realpath(__file__)) DIR = os.path.join(SITE_ROOT, autoapi_dirs[0]) if not os.path.exists(DIR): os.system( "git clone https://github.com/aspnet/Identity %s" % os.path.join(SITE_ROOT, "example/Identity") ) sphinx-autoapi-1.8.4/tests/dotnetexample/example/000077500000000000000000000000001410652014100221355ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/dotnetexample/example/clone.sh000077500000000000000000000000551410652014100235740ustar00rootroot00000000000000git clone https://github.com/aspnet/Identity sphinx-autoapi-1.8.4/tests/dotnetexample/index.rst000066400000000000000000000001631410652014100223430ustar00rootroot00000000000000Welcome to .Net example's documentation! ======================================== .. toctree:: autoapi/index sphinx-autoapi-1.8.4/tests/fixtures/000077500000000000000000000000001410652014100175025ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/fixtures/dotnet.json000066400000000000000000000724121410652014100217000ustar00rootroot00000000000000{ "items": [ { "uid": "Microsoft.AspNet.Identity.IUserStore`1", "parent": "Microsoft.AspNet.Identity", "syntax": { "content": "public interface IUserStore : IDisposable where TUser : class", "typeParameters": [ { "id": "TUser", "description": "The type encapsulating a user." } ], "content.vb": "Public Interface IUserStore(Of TUser As Class) Inherits IDisposable" }, "children": [ "Microsoft.AspNet.Identity.IUserStore`1.CreateAsync(`0,CancellationToken)", "Microsoft.AspNet.Identity.IUserStore`1.DeleteAsync(`0,CancellationToken)", "Microsoft.AspNet.Identity.IUserStore`1.FindByIdAsync(System.String,CancellationToken)", "Microsoft.AspNet.Identity.IUserStore`1.FindByNameAsync(System.String,CancellationToken)", "Microsoft.AspNet.Identity.IUserStore`1.GetNormalizedUserNameAsync(`0,CancellationToken)", "Microsoft.AspNet.Identity.IUserStore`1.GetUserIdAsync(`0,CancellationToken)", "Microsoft.AspNet.Identity.IUserStore`1.GetUserNameAsync(`0,CancellationToken)", "Microsoft.AspNet.Identity.IUserStore`1.SetNormalizedUserNameAsync(`0,System.String,CancellationToken)", "Microsoft.AspNet.Identity.IUserStore`1.SetUserNameAsync(`0,System.String,CancellationToken)", "Microsoft.AspNet.Identity.IUserStore`1.UpdateAsync(`0,CancellationToken)" ], "fullName.vb": "Microsoft.AspNet.Identity.IUserStore(Of TUser)", "name.vb": "IUserStore(Of TUser)", "langs": [ "csharp", "vb" ], "fullName": "Microsoft.AspNet.Identity.IUserStore", "id": "IUserStore`1", "name": "IUserStore", "assemblies": [ "Microsoft.AspNet.Identity" ], "namespace": "Microsoft.AspNet.Identity", "summary": "Provides an abstraction for a store which manages user accounts.", "source": { "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "startLine": 13, "remote": { "repo": "https://github.com/aspnet/apidocs", "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "branch": "master" } }, "href": "Microsoft.AspNet.Identity.IUserStore`1.yml", "type": "Interface", "example": [] }, { "name": "GetUserIdAsync(TUser, CancellationToken)", "parent": "Microsoft.AspNet.Identity.IUserStore`1", "href": "Microsoft.AspNet.Identity.IUserStore`1.yml", "assemblies": [ "Microsoft.AspNet.Identity" ], "namespace": "Microsoft.AspNet.Identity", "summary": "Gets the user identifier for the specified .", "source": { "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "startLine": 21, "remote": { "repo": "https://github.com/aspnet/apidocs", "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "branch": "master" } }, "fullName.vb": "Microsoft.AspNet.Identity.IUserStore(Of TUser).GetUserIdAsync(TUser, CancellationToken)", "id": "GetUserIdAsync(`0,CancellationToken)", "langs": [ "csharp", "vb" ], "fullName": "Microsoft.AspNet.Identity.IUserStore.GetUserIdAsync(TUser, CancellationToken)", "syntax": { "content": "Task GetUserIdAsync(TUser user, CancellationToken cancellationToken)", "return": { "type": "Task{System.String}", "description": "The that represents the asynchronous operation, containing the identifier for the specified ." }, "content.vb": "Function GetUserIdAsync(user As TUser, cancellationToken As CancellationToken) As Task(Of String)", "parameters": [ { "type": "{TUser}", "id": "user", "description": "The user whose identifier should be retrieved." }, { "type": "CancellationToken", "id": "cancellationToken", "description": "The used to propagate notifications that the operation should be canceled." } ] }, "type": "Method", "example": [], "uid": "Microsoft.AspNet.Identity.IUserStore`1.GetUserIdAsync(`0,CancellationToken)" }, { "name": "GetUserNameAsync(TUser, CancellationToken)", "parent": "Microsoft.AspNet.Identity.IUserStore`1", "href": "Microsoft.AspNet.Identity.IUserStore`1.yml", "assemblies": [ "Microsoft.AspNet.Identity" ], "namespace": "Microsoft.AspNet.Identity", "summary": "Gets the user name for the specified .", "source": { "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "startLine": 29, "remote": { "repo": "https://github.com/aspnet/apidocs", "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "branch": "master" } }, "fullName.vb": "Microsoft.AspNet.Identity.IUserStore(Of TUser).GetUserNameAsync(TUser, CancellationToken)", "id": "GetUserNameAsync(`0,CancellationToken)", "langs": [ "csharp", "vb" ], "fullName": "Microsoft.AspNet.Identity.IUserStore.GetUserNameAsync(TUser, CancellationToken)", "syntax": { "content": "Task GetUserNameAsync(TUser user, CancellationToken cancellationToken)", "return": { "type": "Task{System.String}", "description": "The that represents the asynchronous operation, containing the name for the specified ." }, "content.vb": "Function GetUserNameAsync(user As TUser, cancellationToken As CancellationToken) As Task(Of String)", "parameters": [ { "type": "{TUser}", "id": "user", "description": "The user whose name should be retrieved." }, { "type": "CancellationToken", "id": "cancellationToken", "description": "The used to propagate notifications that the operation should be canceled." } ] }, "type": "Method", "example": [], "uid": "Microsoft.AspNet.Identity.IUserStore`1.GetUserNameAsync(`0,CancellationToken)" }, { "name": "SetUserNameAsync(TUser, String, CancellationToken)", "parent": "Microsoft.AspNet.Identity.IUserStore`1", "href": "Microsoft.AspNet.Identity.IUserStore`1.yml", "assemblies": [ "Microsoft.AspNet.Identity" ], "namespace": "Microsoft.AspNet.Identity", "summary": "Sets the given for the specified .", "source": { "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "startLine": 38, "remote": { "repo": "https://github.com/aspnet/apidocs", "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "branch": "master" } }, "fullName.vb": "Microsoft.AspNet.Identity.IUserStore(Of TUser).SetUserNameAsync(TUser, System.String, CancellationToken)", "id": "SetUserNameAsync(`0,System.String,CancellationToken)", "langs": [ "csharp", "vb" ], "fullName": "Microsoft.AspNet.Identity.IUserStore.SetUserNameAsync(TUser, System.String, CancellationToken)", "syntax": { "content": "Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken)", "return": { "type": "Task", "description": "The that represents the asynchronous operation." }, "content.vb": "Function SetUserNameAsync(user As TUser, userName As String, cancellationToken As CancellationToken) As Task", "parameters": [ { "type": "{TUser}", "id": "user", "description": "The user whose name should be set." }, { "type": "System.String", "id": "userName", "description": "The user name to set." }, { "type": "CancellationToken", "id": "cancellationToken", "description": "The used to propagate notifications that the operation should be canceled." } ] }, "type": "Method", "example": [], "uid": "Microsoft.AspNet.Identity.IUserStore`1.SetUserNameAsync(`0,System.String,CancellationToken)" }, { "name": "GetNormalizedUserNameAsync(TUser, CancellationToken)", "parent": "Microsoft.AspNet.Identity.IUserStore`1", "href": "Microsoft.AspNet.Identity.IUserStore`1.yml", "assemblies": [ "Microsoft.AspNet.Identity" ], "namespace": "Microsoft.AspNet.Identity", "summary": "Gets the normalized user name for the specified .", "source": { "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "startLine": 46, "remote": { "repo": "https://github.com/aspnet/apidocs", "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "branch": "master" } }, "fullName.vb": "Microsoft.AspNet.Identity.IUserStore(Of TUser).GetNormalizedUserNameAsync(TUser, CancellationToken)", "id": "GetNormalizedUserNameAsync(`0,CancellationToken)", "langs": [ "csharp", "vb" ], "fullName": "Microsoft.AspNet.Identity.IUserStore.GetNormalizedUserNameAsync(TUser, CancellationToken)", "syntax": { "content": "Task GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken)", "return": { "type": "Task{System.String}", "description": "The that represents the asynchronous operation, containing the normalized user name for the specified ." }, "content.vb": "Function GetNormalizedUserNameAsync(user As TUser, cancellationToken As CancellationToken) As Task(Of String)", "parameters": [ { "type": "{TUser}", "id": "user", "description": "The user whose normalized name should be retrieved." }, { "type": "CancellationToken", "id": "cancellationToken", "description": "The used to propagate notifications that the operation should be canceled." } ] }, "type": "Method", "example": [], "uid": "Microsoft.AspNet.Identity.IUserStore`1.GetNormalizedUserNameAsync(`0,CancellationToken)" }, { "name": "SetNormalizedUserNameAsync(TUser, String, CancellationToken)", "parent": "Microsoft.AspNet.Identity.IUserStore`1", "href": "Microsoft.AspNet.Identity.IUserStore`1.yml", "assemblies": [ "Microsoft.AspNet.Identity" ], "namespace": "Microsoft.AspNet.Identity", "summary": "Sets the given normalized name for the specified .", "source": { "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "startLine": 55, "remote": { "repo": "https://github.com/aspnet/apidocs", "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "branch": "master" } }, "fullName.vb": "Microsoft.AspNet.Identity.IUserStore(Of TUser).SetNormalizedUserNameAsync(TUser, System.String, CancellationToken)", "id": "SetNormalizedUserNameAsync(`0,System.String,CancellationToken)", "langs": [ "csharp", "vb" ], "fullName": "Microsoft.AspNet.Identity.IUserStore.SetNormalizedUserNameAsync(TUser, System.String, CancellationToken)", "syntax": { "content": "Task SetNormalizedUserNameAsync(TUser user, string normalizedName, CancellationToken cancellationToken)", "return": { "type": "Task", "description": "The that represents the asynchronous operation." }, "content.vb": "Function SetNormalizedUserNameAsync(user As TUser, normalizedName As String, cancellationToken As CancellationToken) As Task", "parameters": [ { "type": "{TUser}", "id": "user", "description": "The user whose name should be set." }, { "type": "System.String", "id": "normalizedName", "description": "The normalized name to set." }, { "type": "CancellationToken", "id": "cancellationToken", "description": "The used to propagate notifications that the operation should be canceled." } ] }, "type": "Method", "example": [], "uid": "Microsoft.AspNet.Identity.IUserStore`1.SetNormalizedUserNameAsync(`0,System.String,CancellationToken)" }, { "name": "CreateAsync(TUser, CancellationToken)", "parent": "Microsoft.AspNet.Identity.IUserStore`1", "href": "Microsoft.AspNet.Identity.IUserStore`1.yml", "assemblies": [ "Microsoft.AspNet.Identity" ], "namespace": "Microsoft.AspNet.Identity", "summary": "Creates the specified in the user store.", "source": { "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "startLine": 63, "remote": { "repo": "https://github.com/aspnet/apidocs", "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "branch": "master" } }, "fullName.vb": "Microsoft.AspNet.Identity.IUserStore(Of TUser).CreateAsync(TUser, CancellationToken)", "id": "CreateAsync(`0,CancellationToken)", "langs": [ "csharp", "vb" ], "fullName": "Microsoft.AspNet.Identity.IUserStore.CreateAsync(TUser, CancellationToken)", "syntax": { "content": "Task CreateAsync(TUser user, CancellationToken cancellationToken)", "return": { "type": "Task{Microsoft.AspNet.Identity.IdentityResult}", "description": "The that represents the asynchronous operation, containing the of the creation operation." }, "content.vb": "Function CreateAsync(user As TUser, cancellationToken As CancellationToken) As Task(Of IdentityResult)", "parameters": [ { "type": "{TUser}", "id": "user", "description": "The user to create." }, { "type": "CancellationToken", "id": "cancellationToken", "description": "The used to propagate notifications that the operation should be canceled." } ] }, "type": "Method", "example": [], "uid": "Microsoft.AspNet.Identity.IUserStore`1.CreateAsync(`0,CancellationToken)" }, { "name": "UpdateAsync(TUser, CancellationToken)", "parent": "Microsoft.AspNet.Identity.IUserStore`1", "href": "Microsoft.AspNet.Identity.IUserStore`1.yml", "assemblies": [ "Microsoft.AspNet.Identity" ], "namespace": "Microsoft.AspNet.Identity", "summary": "Updates the specified in the user store.", "source": { "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "startLine": 71, "remote": { "repo": "https://github.com/aspnet/apidocs", "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "branch": "master" } }, "fullName.vb": "Microsoft.AspNet.Identity.IUserStore(Of TUser).UpdateAsync(TUser, CancellationToken)", "id": "UpdateAsync(`0,CancellationToken)", "langs": [ "csharp", "vb" ], "fullName": "Microsoft.AspNet.Identity.IUserStore.UpdateAsync(TUser, CancellationToken)", "syntax": { "content": "Task UpdateAsync(TUser user, CancellationToken cancellationToken)", "return": { "type": "Task{Microsoft.AspNet.Identity.IdentityResult}", "description": "The that represents the asynchronous operation, containing the of the update operation." }, "content.vb": "Function UpdateAsync(user As TUser, cancellationToken As CancellationToken) As Task(Of IdentityResult)", "parameters": [ { "type": "{TUser}", "id": "user", "description": "The user to update." }, { "type": "CancellationToken", "id": "cancellationToken", "description": "The used to propagate notifications that the operation should be canceled." } ] }, "type": "Method", "example": [], "uid": "Microsoft.AspNet.Identity.IUserStore`1.UpdateAsync(`0,CancellationToken)" }, { "name": "DeleteAsync(TUser, CancellationToken)", "parent": "Microsoft.AspNet.Identity.IUserStore`1", "href": "Microsoft.AspNet.Identity.IUserStore`1.yml", "assemblies": [ "Microsoft.AspNet.Identity" ], "namespace": "Microsoft.AspNet.Identity", "summary": "Deletes the specified from the user store.", "source": { "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "startLine": 79, "remote": { "repo": "https://github.com/aspnet/apidocs", "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "branch": "master" } }, "fullName.vb": "Microsoft.AspNet.Identity.IUserStore(Of TUser).DeleteAsync(TUser, CancellationToken)", "id": "DeleteAsync(`0,CancellationToken)", "langs": [ "csharp", "vb" ], "fullName": "Microsoft.AspNet.Identity.IUserStore.DeleteAsync(TUser, CancellationToken)", "syntax": { "content": "Task DeleteAsync(TUser user, CancellationToken cancellationToken)", "return": { "type": "Task{Microsoft.AspNet.Identity.IdentityResult}", "description": "The that represents the asynchronous operation, containing the of the update operation." }, "content.vb": "Function DeleteAsync(user As TUser, cancellationToken As CancellationToken) As Task(Of IdentityResult)", "parameters": [ { "type": "{TUser}", "id": "user", "description": "The user to delete." }, { "type": "CancellationToken", "id": "cancellationToken", "description": "The used to propagate notifications that the operation should be canceled." } ] }, "type": "Method", "example": [], "uid": "Microsoft.AspNet.Identity.IUserStore`1.DeleteAsync(`0,CancellationToken)" }, { "name": "FindByIdAsync(String, CancellationToken)", "parent": "Microsoft.AspNet.Identity.IUserStore`1", "href": "Microsoft.AspNet.Identity.IUserStore`1.yml", "assemblies": [ "Microsoft.AspNet.Identity" ], "namespace": "Microsoft.AspNet.Identity", "summary": "Finds and returns a user, if any, who has the specified .", "source": { "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "startLine": 89, "remote": { "repo": "https://github.com/aspnet/apidocs", "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "branch": "master" } }, "fullName.vb": "Microsoft.AspNet.Identity.IUserStore(Of TUser).FindByIdAsync(System.String, CancellationToken)", "id": "FindByIdAsync(System.String,CancellationToken)", "langs": [ "csharp", "vb" ], "fullName": "Microsoft.AspNet.Identity.IUserStore.FindByIdAsync(System.String, CancellationToken)", "syntax": { "content": "Task FindByIdAsync(string userId, CancellationToken cancellationToken)", "return": { "type": "Task{{TUser}}", "description": "The that represents the asynchronous operation, containing the user matching the specified if it exists." }, "content.vb": "Function FindByIdAsync(userId As String, cancellationToken As CancellationToken) As Task(Of TUser)", "parameters": [ { "type": "System.String", "id": "userId", "description": "The user ID to search for." }, { "type": "CancellationToken", "id": "cancellationToken", "description": "The used to propagate notifications that the operation should be canceled." } ] }, "type": "Method", "example": [], "uid": "Microsoft.AspNet.Identity.IUserStore`1.FindByIdAsync(System.String,CancellationToken)" }, { "name": "FindByNameAsync(String, CancellationToken)", "parent": "Microsoft.AspNet.Identity.IUserStore`1", "href": "Microsoft.AspNet.Identity.IUserStore`1.yml", "assemblies": [ "Microsoft.AspNet.Identity" ], "namespace": "Microsoft.AspNet.Identity", "summary": "Finds and returns a user, if any, who has the specified normalized user name.", "source": { "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "startLine": 99, "remote": { "repo": "https://github.com/aspnet/apidocs", "path": "aspnet/identity/src/Microsoft.AspNet.Identity/IUserStore.cs", "branch": "master" } }, "fullName.vb": "Microsoft.AspNet.Identity.IUserStore(Of TUser).FindByNameAsync(System.String, CancellationToken)", "id": "FindByNameAsync(System.String,CancellationToken)", "langs": [ "csharp", "vb" ], "fullName": "Microsoft.AspNet.Identity.IUserStore.FindByNameAsync(System.String, CancellationToken)", "syntax": { "content": "Task FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)", "return": { "type": "Task{{TUser}}", "description": "The that represents the asynchronous operation, containing the user matching the specified if it exists." }, "content.vb": "Function FindByNameAsync(normalizedUserName As String, cancellationToken As CancellationToken) As Task(Of TUser)", "parameters": [ { "type": "System.String", "id": "normalizedUserName", "description": "The normalized user name to search for." }, { "type": "CancellationToken", "id": "cancellationToken", "description": "The used to propagate notifications that the operation should be canceled." } ] }, "type": "Method", "example": [], "uid": "Microsoft.AspNet.Identity.IUserStore`1.FindByNameAsync(System.String,CancellationToken)" } ], "references": [ { "fullName": "Microsoft.AspNet.Identity", "isExternal": false, "uid": "Microsoft.AspNet.Identity", "name": "Microsoft.AspNet.Identity" }, { "fullName": "TUser", "isExternal": false, "uid": "{TUser}", "name": "TUser" }, { "fullName": "CancellationToken", "isExternal": true, "name": "CancellationToken", "parent": null, "uid": "CancellationToken" }, { "definition": "Task`1", "uid": "Task{System.String}", "parent": null, "spec.vb": [ { "fullName": "Task", "uid": "Task`1", "name": "Task", "isExternal": true }, { "fullName": "(Of ", "name": "(Of " }, { "fullName": "System.String", "uid": "System.String", "name": "String", "isExternal": true }, { "fullName": ")", "name": ")" } ], "fullName.vb": "Task(Of System.String)", "name.vb": "Task(Of String)", "fullName": "Task", "spec.csharp": [ { "fullName": "Task", "uid": "Task`1", "name": "Task", "isExternal": true }, { "fullName": "<", "name": "<" }, { "fullName": "System.String", "uid": "System.String", "name": "String", "isExternal": true }, { "fullName": ">", "name": ">" } ], "name": "Task" }, { "fullName": null, "isExternal": false, "uid": null, "name": null }, { "name": "Task<>", "parent": null, "spec.vb": [ { "fullName": "Task", "uid": "Task`1", "name": "Task", "isExternal": true }, { "fullName": "(Of ", "name": "(Of " }, { "fullName": null, "name": null }, { "fullName": ")", "name": ")" } ], "fullName.vb": "Task(Of )", "name.vb": "Task(Of )", "uid": "Task`1", "fullName": "Task<>", "spec.csharp": [ { "fullName": "Task", "uid": "Task`1", "name": "Task", "isExternal": true }, { "fullName": "<", "name": "<" }, { "fullName": null, "name": null }, { "fullName": ">", "name": ">" } ], "isExternal": true }, { "fullName": "System.String", "isExternal": true, "name": "String", "parent": "System", "uid": "System.String" }, { "fullName": "Task", "isExternal": true, "name": "Task", "parent": null, "uid": "Task" }, { "fullName": "System", "isExternal": false, "uid": "System", "name": "System" }, { "definition": "Task`1", "uid": "Task{Microsoft.AspNet.Identity.IdentityResult}", "parent": null, "href": "Microsoft.AspNet.Identity.IdentityResult.yml", "spec.vb": [ { "fullName": "Task", "uid": "Task`1", "name": "Task", "isExternal": true }, { "fullName": "(Of ", "name": "(Of " }, { "fullName": "Microsoft.AspNet.Identity.IdentityResult", "href": "Microsoft.AspNet.Identity.IdentityResult.yml", "uid": "Microsoft.AspNet.Identity.IdentityResult", "name": "IdentityResult" }, { "fullName": ")", "name": ")" } ], "fullName.vb": "Task(Of Microsoft.AspNet.Identity.IdentityResult)", "name.vb": "Task(Of IdentityResult)", "fullName": "Task", "spec.csharp": [ { "fullName": "Task", "uid": "Task`1", "name": "Task", "isExternal": true }, { "fullName": "<", "name": "<" }, { "fullName": "Microsoft.AspNet.Identity.IdentityResult", "href": "Microsoft.AspNet.Identity.IdentityResult.yml", "uid": "Microsoft.AspNet.Identity.IdentityResult", "name": "IdentityResult" }, { "fullName": ">", "name": ">" } ], "name": "Task" }, { "definition": "Task`1", "uid": "Task{{TUser}}", "parent": null, "spec.vb": [ { "fullName": "Task", "uid": "Task`1", "name": "Task", "isExternal": true }, { "fullName": "(Of ", "name": "(Of " }, { "fullName": "TUser", "name": "TUser" }, { "fullName": ")", "name": ")" } ], "fullName.vb": "Task(Of TUser)", "name.vb": "Task(Of TUser)", "fullName": "Task", "spec.csharp": [ { "fullName": "Task", "uid": "Task`1", "name": "Task", "isExternal": true }, { "fullName": "<", "name": "<" }, { "fullName": "TUser", "name": "TUser" }, { "fullName": ">", "name": ">" } ], "name": "Task" } ] }sphinx-autoapi-1.8.4/tests/fixtures/go.json000066400000000000000000000054001410652014100210010ustar00rootroot00000000000000{ "funcs": [ { "name": "CopyFuncs", "doc": "CopyFuncs produces a json-annotated array of Func objects from an array of GoDoc Func objects.\n", "packageName": "main", "packageImportPath": "example", "recv": "", "orig": "" }, { "name": "CopyValues", "doc": "CopyValues produces a json-annotated array of Value objects from an array of GoDoc Value objects.\n", "packageName": "main", "packageImportPath": "example", "recv": "", "orig": "" } ], "name": "main", "vars": [], "doc": "", "notes": {}, "bugs": null, "filenames": [ "example/godocjson.go" ], "importPath": "example", "consts": [], "imports": [ "encoding/json", "fmt", "go/doc", "go/parser", "go/token", "os" ], "type": "package", "types": [ { "funcs": [], "name": "Func", "vars": [], "doc": "Func represents a function declaration.\n", "packageName": "main", "packageImportPath": "example", "consts": [], "methods": [] }, { "funcs": [], "name": "Note", "vars": [], "doc": "Note represents a note comment.\n", "packageName": "main", "packageImportPath": "example", "consts": [], "methods": [] }, { "funcs": [ { "name": "CopyPackage", "doc": "CopyPackage produces a json-annotated Package object from a GoDoc Package object.\n", "packageName": "main", "packageImportPath": "example", "recv": "", "orig": "" } ], "name": "Package", "vars": [], "doc": "Package represents a package declaration.\n", "packageName": "main", "packageImportPath": "example", "consts": [], "methods": [] }, { "funcs": [], "name": "Type", "vars": [], "doc": "Type represents a type declaration.\n", "packageName": "main", "packageImportPath": "example", "consts": [], "methods": [] }, { "funcs": [], "name": "Value", "vars": [], "doc": "Value represents a value declaration.\n", "packageName": "main", "packageImportPath": "example", "consts": [], "methods": [] } ] }sphinx-autoapi-1.8.4/tests/fixtures/javascript.json000066400000000000000000000224541410652014100225520ustar00rootroot00000000000000[ { "comment": "/**\n * Creates an instance of Circle.\n *\n * @constructor\n * @this {Circle}\n * @param {number} r The desired radius of the circle.\n */", "kind": "class", "description": "Creates an instance of Circle.", "this": "{Circle}", "see": [], "meta": { "path": "/Users/eric/projects/sphinx-autoapi/tests/jsexample/example", "range": [ 134, 251 ], "code": { "node": "", "paramnames": [ "r" ], "type": "function", "id": "astnode194706439", "name": "Circle" }, "lineno": 8, "filename": "jsdoc-example.js" }, "params": [ { "description": "The desired radius of the circle.", "nullable": "undefined", "type": { "names": [ "number" ] }, "defaultvalue": "undefined", "variable": "undefined", "optional": "undefined", "name": "r" } ], "longname": "Circle", "scope": "global", "name": "Circle" }, { "comment": "/** @private */", "kind": "member", "name": "radius", "memberof": "{Circle}", "access": "private", "meta": { "path": "/Users/eric/projects/sphinx-autoapi/tests/jsexample/example", "range": [ 175, 190 ], "code": { "node": "", "type": "NAME", "id": "astnode1413378318", "value": "r", "name": "this.radius" }, "lineno": 9, "filename": "jsdoc-example.js" }, "longname": "{Circle}#radius", "scope": "instance" }, { "comment": "/** @private */", "kind": "member", "name": "circumference", "memberof": "{Circle}", "access": "private", "meta": { "path": "/Users/eric/projects/sphinx-autoapi/tests/jsexample/example", "range": [ 212, 248 ], "code": { "node": "", "type": "MUL", "id": "astnode1157058691", "value": "MUL", "name": "this.circumference" }, "lineno": 10, "filename": "jsdoc-example.js" }, "longname": "{Circle}#circumference", "scope": "instance" }, { "comment": "/**\n * Creates a new Circle from a diameter.\n *\n * @param {number} d The desired diameter of the circle.\n * @return {Circle} The new Circle object.\n */", "kind": "function", "description": "Creates a new Circle from a diameter.", "memberof": "Circle", "returns": [ { "description": "The new Circle object.", "nullable": "undefined", "type": { "names": [ "Circle" ] }, "defaultvalue": "undefined", "variable": "undefined", "optional": "undefined" } ], "meta": { "path": "/Users/eric/projects/sphinx-autoapi/tests/jsexample/example", "range": [ 406, 474 ], "code": { "node": "", "paramnames": [ "d" ], "name": "Circle.fromDiameter", "value": "FUNCTION", "type": "FUNCTION", "id": "astnode398110318" }, "lineno": 19, "filename": "jsdoc-example.js" }, "params": [ { "description": "The desired diameter of the circle.", "nullable": "undefined", "type": { "names": [ "number" ] }, "defaultvalue": "undefined", "variable": "undefined", "optional": "undefined", "name": "d" } ], "longname": "Circle.fromDiameter", "scope": "static", "name": "fromDiameter" }, { "comment": "/**\n * Calculates the circumference of the Circle.\n *\n * @deprecated\n * @this {Circle}\n * @return {number} The circumference of the circle.\n */", "kind": "function", "description": "Calculates the circumference of the Circle.", "this": "{Circle}", "deprecated": true, "longname": "Circle#calculateCircumference", "returns": [ { "description": "The circumference of the circle.", "nullable": "undefined", "type": { "names": [ "number" ] }, "defaultvalue": "undefined", "variable": "undefined", "optional": "undefined" } ], "see": [], "meta": { "path": "/Users/eric/projects/sphinx-autoapi/tests/jsexample/example", "range": [ 622, 717 ], "code": { "node": "", "paramnames": [], "name": "Circle.prototype.calculateCircumference", "value": "FUNCTION", "type": "FUNCTION", "id": "astnode1582785598" }, "lineno": 30, "filename": "jsdoc-example.js" }, "memberof": "Circle", "scope": "instance", "name": "calculateCircumference" }, { "comment": "/**\n * Returns the pre-computed circumference of the Circle.\n *\n * @this {Circle}\n * @return {number} The circumference of the circle.\n */", "kind": "function", "description": "Returns the pre-computed circumference of the Circle.", "this": "{Circle}", "memberof": "Circle", "returns": [ { "description": "The circumference of the circle.", "nullable": "undefined", "type": { "names": [ "number" ] }, "defaultvalue": "undefined", "variable": "undefined", "optional": "undefined" } ], "see": [], "meta": { "path": "/Users/eric/projects/sphinx-autoapi/tests/jsexample/example", "range": [ 860, 942 ], "code": { "node": "", "paramnames": [], "name": "Circle.prototype.getCircumference", "value": "FUNCTION", "type": "FUNCTION", "id": "astnode2134991632" }, "lineno": 40, "filename": "jsdoc-example.js" }, "longname": "Circle#getCircumference", "scope": "instance", "name": "getCircumference" }, { "comment": "/**\n * Find a String representation of the Circle.\n *\n * @override\n * @this {Circle}\n * @return {string} Human-readable representation of this Circle.\n */", "kind": "function", "description": "Find a String representation of the Circle.", "tags": [ { "originalTitle": "override", "text": "", "title": "override" } ], "this": "{Circle}", "memberof": "Circle", "returns": [ { "description": "Human-readable representation of this Circle.", "nullable": "undefined", "type": { "names": [ "string" ] }, "defaultvalue": "undefined", "variable": "undefined", "optional": "undefined" } ], "see": [], "meta": { "path": "/Users/eric/projects/sphinx-autoapi/tests/jsexample/example", "range": [ 1101, 1210 ], "code": { "node": "", "paramnames": [], "name": "Circle.prototype.toString", "value": "FUNCTION", "type": "FUNCTION", "id": "astnode1822383117" }, "lineno": 51, "filename": "jsdoc-example.js" }, "longname": "Circle#toString", "scope": "instance", "name": "toString" }, { "files": [ "/Users/eric/projects/sphinx-autoapi/tests/jsexample/example/jsdoc-example.js" ], "kind": "package", "description": "undefined", "version": "undefined", "longname": "package:undefined", "licenses": "undefined", "name": "undefined" } ]sphinx-autoapi-1.8.4/tests/goexample/000077500000000000000000000000001410652014100176125ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/goexample/conf.py000066400000000000000000000010421410652014100211060ustar00rootroot00000000000000# -*- coding: utf-8 -*- templates_path = ["_templates"] source_suffix = ".rst" master_doc = "index" project = u"goexample" 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 = "goexampledoc" extensions = ["autoapi.extension", "sphinxcontrib.golangdomain"] autoapi_type = "go" autoapi_dirs = ["example"] autoapi_file_pattern = "*.go" sphinx-autoapi-1.8.4/tests/goexample/example/000077500000000000000000000000001410652014100212455ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/goexample/example/godocjson.go000066400000000000000000000123451410652014100235660ustar00rootroot00000000000000package main import ( "encoding/json" "fmt" "go/doc" "go/parser" "go/token" "os" ) // Func represents a function declaration. type Func struct { Doc string `json:"doc"` Name string `json:"name"` PackageName string `json:"packageName"` PackageImportPath string `json:"packageImportPath"` // Decl *ast.FuncDecl // methods // (for functions, these fields have the respective zero value) Recv string `json:"recv"` // actual receiver "T" or "*T" Orig string `json:"orig"` // original receiver "T" or "*T" // Level int // embedding level; 0 means not embedded } // Package represents a package declaration. type Package struct { Type string `json:"type"` Doc string `json:"doc"` Name string `json:"name"` ImportPath string `json:"importPath"` Imports []string `json:"imports"` Filenames []string `json:"filenames"` Notes map[string][]*Note `json:"notes"` // DEPRECATED. For backward compatibility Bugs is still populated, // but all new code should use Notes instead. Bugs []string `json:"bugs"` // declarations Consts []*Value `json:"consts"` Types []*Type `json:"types"` Vars []*Value `json:"vars"` Funcs []*Func `json:"funcs"` } // Note represents a note comment. type Note struct { Pos token.Pos `json:"pos"` End token.Pos `json:"end"` // position range of the comment containing the marker UID string `json:"uid"` // uid found with the marker Body string `json:"body"` // note body text } // Type represents a type declaration. type Type struct { PackageName string `json:"packageName"` PackageImportPath string `json:"packageImportPath"` Doc string `json:"doc"` Name string `json:"name"` // Decl *ast.GenDecl // associated declarations Consts []*Value `json:"consts"` // sorted list of constants of (mostly) this type Vars []*Value `json:"vars"` // sorted list of variables of (mostly) this type Funcs []*Func `json:"funcs"` // sorted list of functions returning this type Methods []*Func `json:"methods"` // sorted list of methods (including embedded ones) of this type } // Value represents a value declaration. type Value struct { PackageName string `json:"packageName"` PackageImportPath string `json:"packageImportPath"` Doc string `json:"doc"` Names []string `json:"names"` // var or const names in declaration order // Decl *ast.GenDecl } // CopyFuncs produces a json-annotated array of Func objects from an array of GoDoc Func objects. func CopyFuncs(f []*doc.Func, packageName string, packageImportPath string) []*Func { newFuncs := make([]*Func, len(f)) for i, n := range f { newFuncs[i] = &Func{ Doc: n.Doc, Name: n.Name, PackageName: packageName, PackageImportPath: packageImportPath, Orig: n.Orig, Recv: n.Recv, } } return newFuncs } // CopyValues produces a json-annotated array of Value objects from an array of GoDoc Value objects. func CopyValues(c []*doc.Value, packageName string, packageImportPath string) []*Value { newConsts := make([]*Value, len(c)) for i, c := range c { newConsts[i] = &Value{ Doc: c.Doc, Names: c.Names, PackageName: packageName, PackageImportPath: packageImportPath, } } return newConsts } // CopyPackage produces a json-annotated Package object from a GoDoc Package object. func CopyPackage(pkg *doc.Package) Package { newPkg := Package{ Type: "package", Doc: pkg.Doc, Name: pkg.Name, ImportPath: pkg.ImportPath, Imports: pkg.Imports, Filenames: pkg.Filenames, Bugs: pkg.Bugs, } newPkg.Notes = map[string][]*Note{} for key, value := range pkg.Notes { notes := make([]*Note, len(value)) for i, note := range value { notes[i] = &Note{ Pos: note.Pos, End: note.End, UID: note.UID, Body: note.Body, } } newPkg.Notes[key] = notes } newPkg.Consts = CopyValues(pkg.Consts, pkg.Name, pkg.ImportPath) newPkg.Funcs = CopyFuncs(pkg.Funcs, pkg.Name, pkg.ImportPath) newPkg.Types = make([]*Type, len(pkg.Types)) for i, t := range pkg.Types { newPkg.Types[i] = &Type{ Name: t.Name, PackageName: pkg.Name, PackageImportPath: pkg.ImportPath, Consts: CopyValues(t.Consts, pkg.Name, pkg.ImportPath), Doc: t.Doc, Funcs: CopyFuncs(t.Funcs, pkg.Name, pkg.ImportPath), Methods: CopyFuncs(t.Methods, pkg.Name, pkg.ImportPath), Vars: CopyValues(t.Vars, pkg.Name, pkg.ImportPath), } } newPkg.Vars = CopyValues(pkg.Vars, pkg.Name, pkg.ImportPath) return newPkg } func main() { directories := os.Args[1:] for _, dir := range directories { fileSet := token.NewFileSet() pkgs, firstError := parser.ParseDir(fileSet, dir, nil, parser.ParseComments|parser.AllErrors) if firstError != nil { panic(firstError) } for _, pkg := range pkgs { docPkg := doc.New(pkg, dir, 0) cleanedPkg := CopyPackage(docPkg) pkgJSON, err := json.MarshalIndent(cleanedPkg, "", " ") if err != nil { panic(err) } fmt.Printf("%s\n", pkgJSON) } } } sphinx-autoapi-1.8.4/tests/goexample/index.rst000066400000000000000000000002311410652014100214470ustar00rootroot00000000000000Welcome to Go example's documentation! ====================================== .. toctree:: autoapi/index Contents: .. toctree:: :maxdepth: 2 sphinx-autoapi-1.8.4/tests/jsexample/000077500000000000000000000000001410652014100176215ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/jsexample/conf.py000066400000000000000000000010131410652014100211130ustar00rootroot00000000000000# -*- coding: utf-8 -*- templates_path = ["_templates"] source_suffix = ".rst" master_doc = "index" project = u"jsexample" 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 = "jsexampledoc" extensions = ["autoapi.extension"] autoapi_type = "javascript" autoapi_dirs = ["example"] autoapi_file_pattern = "*.js" sphinx-autoapi-1.8.4/tests/jsexample/example/000077500000000000000000000000001410652014100212545ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/jsexample/example/jsdoc-example.js000066400000000000000000000022741410652014100243520ustar00rootroot00000000000000/** * Creates an instance of Circle. * * @constructor * @this {Circle} * @param {number} r The desired radius of the circle. */ function Circle(r) { /** @private */ this.radius = r; /** @private */ this.circumference = 2 * Math.PI * r; } /** * Creates a new Circle from a diameter. * * @param {number} d The desired diameter of the circle. * @return {Circle} The new Circle object. */ Circle.fromDiameter = function (d) { return new Circle(d / 2); }; /** * Calculates the circumference of the Circle. * * @deprecated * @this {Circle} * @return {number} The circumference of the circle. */ Circle.prototype.calculateCircumference = function () { return 2 * Math.PI * this.radius; }; /** * Returns the pre-computed circumference of the Circle. * * @this {Circle} * @return {number} The circumference of the circle. */ Circle.prototype.getCircumference = function () { return this.circumference; }; /** * Find a String representation of the Circle. * * @override * @this {Circle} * @return {string} Human-readable representation of this Circle. */ Circle.prototype.toString = function () { return "A Circle object with radius of " + this.radius + "."; }; sphinx-autoapi-1.8.4/tests/jsexample/index.rst000066400000000000000000000003641410652014100214650ustar00rootroot00000000000000Welcome to jsexample's documentation! ===================================== .. toctree:: autoapi/index Contents: .. toctree:: :maxdepth: 2 Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` sphinx-autoapi-1.8.4/tests/python/000077500000000000000000000000001410652014100171525ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/py38positionalparams/000077500000000000000000000000001410652014100232635ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/py38positionalparams/conf.py000066400000000000000000000007761410652014100245740ustar00rootroot00000000000000# -*- 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" htmlhelp_basename = "pyexampledoc" extensions = ["sphinx.ext.autodoc", "autoapi.extension"] autoapi_type = "python" autoapi_dirs = ["example"] autoapi_file_pattern = "*.py" sphinx-autoapi-1.8.4/tests/python/py38positionalparams/example/000077500000000000000000000000001410652014100247165ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/py38positionalparams/example/example.py000066400000000000000000000013741410652014100267300ustar00rootroot00000000000000# -*- coding: utf-8 -*- """Example module This is a description """ from typing import Optional def f_simple(a, b, /, c, d, *, e, f): print(a, b, c, d, e, f) def f_comment(a, b, /, c, d, *, e, f): # type: (int, int, Optional[int], Optional[int], float, float) -> None print(a, b, c, d, e, f) def f_annotation( a: int, b: int, /, c: Optional[int], d: Optional[int], *, e: float, f: float ) -> None: print(a, b, c, d, e, f) def f_arg_comment( a, # type: int b, # type: int /, c, # type: Optional[int] d, # type: Optional[int] *, e, # type: float f, # type: float ): # type: (...) -> None print(a, b, c, d, e, f) def f_no_cd(a: int, b: int, /, *, e: float, f: float): print(a, b, e, f) sphinx-autoapi-1.8.4/tests/python/py38positionalparams/index.rst000066400000000000000000000007201410652014100251230ustar00rootroot00000000000000.. 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` sphinx-autoapi-1.8.4/tests/python/py3example/000077500000000000000000000000001410652014100212415ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/py3example/conf.py000066400000000000000000000013741410652014100225450ustar00rootroot00000000000000# -*- 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" htmlhelp_basename = "pyexampledoc" extensions = ["sphinx.ext.autodoc", "autoapi.extension"] 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", ] sphinx-autoapi-1.8.4/tests/python/py3example/example/000077500000000000000000000000001410652014100226745ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/py3example/example/example.py000066400000000000000000000061441410652014100247060ustar00rootroot00000000000000# -*- coding: utf-8 -*- """Example module This is a description """ import asyncio import typing from typing import ClassVar, Dict, Iterable, Generic, List, TypeVar, Union, overload from example2 import B T = TypeVar("T") U = TypeVar("U") software = "sphinx" code_snippet = """ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function, unicode_literals # from future.builtins.disabled import * # from builtins import * print("chunky o'block") """ max_rating: int = 10 is_valid: bool if max_rating > 100: is_valid = False else: is_valid = True ratings: List[int] = [0, 1, 2, 3, 4, 5] rating_names: Dict[int, str] = {0: "zero", 1: "one"} def f(start: int, end: int) -> Iterable[int]: "This is f" i = start while i < end: yield i i += 1 mixed_list: List[Union[str, int]] = [1, "two", 3] "This is mixed" def f2(not_yet_a: "A") -> int: ... def f3(imported: B) -> B: ... class MyGeneric(Generic[T, U]): ... @overload def overloaded_func(a: float) -> float: ... @typing.overload def overloaded_func(a: str) -> str: ... def overloaded_func(a: Union[float, str]) -> Union[float, str]: """Overloaded function""" return a * 2 @overload def undoc_overloaded_func(a: str) -> str: ... def undoc_overloaded_func(a: str) -> str: return a * 2 class A: """class A""" is_an_a: ClassVar[bool] = True not_assigned_to: ClassVar[str] def __init__(self): self.instance_var: bool = True """This is an instance_var.""" async def async_method(self, wait: bool) -> int: if wait: await asyncio.sleep(1) return 5 @property def my_prop(self) -> str: """My property.""" return "prop" def my_method(self) -> str: """My method.""" return "method" @overload def overloaded_method(self, a: float) -> float: ... @typing.overload def overloaded_method(self, a: str) -> str: ... def overloaded_method(self, a: Union[float, str]) -> Union[float, str]: """Overloaded method""" return a * 2 @overload def undoc_overloaded_method(self, a: float) -> float: ... def undoc_overloaded_method(self, a: float) -> float: return a * 2 @typing.overload @classmethod def overloaded_class_method(cls, a: float) -> float: ... @overload @classmethod def overloaded_class_method(cls, a: str) -> str: ... @classmethod def overloaded_class_method(cls, a: Union[float, str]) -> Union[float, str]: """Overloaded class method""" return a * 2 class C: @overload def __init__(self, a: int) -> None: ... @typing.overload def __init__(self, a: float) -> None: ... def __init__(self, a: str): ... class D(C): class Da: ... class DB(Da): ... ... async def async_function(wait: bool) -> int: """Blah. Args: wait: Blah """ if wait: await asyncio.sleep(1) return 5 global_a: A = A() class SomeMetaclass(type): ... sphinx-autoapi-1.8.4/tests/python/py3example/example/example2.py000066400000000000000000000000221410652014100247550ustar00rootroot00000000000000class B: pass sphinx-autoapi-1.8.4/tests/python/py3example/index.rst000066400000000000000000000007171410652014100231070ustar00rootroot00000000000000.. 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` sphinx-autoapi-1.8.4/tests/python/py3implicitnamespace/000077500000000000000000000000001410652014100232755ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/py3implicitnamespace/conf.py000066400000000000000000000010711410652014100245730ustar00rootroot00000000000000# -*- 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" htmlhelp_basename = "py3implicitnamespacedoc" extensions = ["sphinx.ext.autodoc", "autoapi.extension"] autoapi_type = "python" autoapi_dirs = ["namespace"] autoapi_file_pattern = "*.py" autoapi_python_use_implicit_namespaces = True sphinx-autoapi-1.8.4/tests/python/py3implicitnamespace/index.rst000066400000000000000000000007611410652014100251420ustar00rootroot00000000000000.. py3implicitnamespace 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 py3implicitnamespace's documentation! ================================================ .. toctree:: autoapi/index Contents: .. toctree:: :maxdepth: 2 Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` sphinx-autoapi-1.8.4/tests/python/py3implicitnamespace/namespace/000077500000000000000000000000001410652014100252315ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/py3implicitnamespace/namespace/example/000077500000000000000000000000001410652014100266645ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/py3implicitnamespace/namespace/example/__init__.py000066400000000000000000000001711410652014100307740ustar00rootroot00000000000000from ..sibling import * from ..sibling.sub_sibling import * def example_method(foo): """Example method""" pass sphinx-autoapi-1.8.4/tests/python/py3implicitnamespace/namespace/sibling/000077500000000000000000000000001410652014100266605ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/py3implicitnamespace/namespace/sibling/__init__.py000066400000000000000000000002261410652014100307710ustar00rootroot00000000000000def first_method(): """First sibling package method.""" return 1 def second_method(): """Second sibling package method.""" return 2 sphinx-autoapi-1.8.4/tests/python/py3implicitnamespace/namespace/sibling/sub_sibling.py000066400000000000000000000002411410652014100315270ustar00rootroot00000000000000def first_sub_method(): """First sub-sibling package method.""" return 1 def second_sub_method(): """Second sub-subpackage method.""" return 2 sphinx-autoapi-1.8.4/tests/python/pyannotationcommentsexample/000077500000000000000000000000001410652014100250175ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pyannotationcommentsexample/conf.py000066400000000000000000000007761410652014100263300ustar00rootroot00000000000000# -*- 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" htmlhelp_basename = "pyexampledoc" extensions = ["sphinx.ext.autodoc", "autoapi.extension"] autoapi_type = "python" autoapi_dirs = ["example"] autoapi_file_pattern = "*.py" sphinx-autoapi-1.8.4/tests/python/pyannotationcommentsexample/example/000077500000000000000000000000001410652014100264525ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pyannotationcommentsexample/example/example.py000066400000000000000000000015151410652014100304610ustar00rootroot00000000000000# -*- coding: utf-8 -*- """Example module This is a description """ from typing import ClassVar, Dict, Iterable, List, Union max_rating = 10 # type: int ratings = [0, 1, 2, 3, 4, 5] # type: List[int] rating_names = {0: "zero", 1: "one"} # type: Dict[int, str] def f( start, # type: int end, # type: int ): # type: (...) -> Iterable[int] i = start while i < end: yield i i += 1 mixed_list = [1, "two", 3] # type: List[Union[str, int]] def f2(not_yet_a): # type: (A) -> int pass class A: is_an_a = True # type: ClassVar[bool] def __init__(self): self.instance_var = True # type: bool """This is an instance_var.""" global_a = A() # type: A def f3(first_arg, **kwargs): # type: (first_arg, Any) -> None """Annotation incorrectly leaves out `**`.""" sphinx-autoapi-1.8.4/tests/python/pyannotationcommentsexample/index.rst000066400000000000000000000007201410652014100266570ustar00rootroot00000000000000.. 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` sphinx-autoapi-1.8.4/tests/python/pyautodoc_typehints/000077500000000000000000000000001410652014100232705ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pyautodoc_typehints/conf.py000066400000000000000000000014661410652014100245760ustar00rootroot00000000000000# -*- 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" 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" sphinx-autoapi-1.8.4/tests/python/pyautodoc_typehints/example/000077500000000000000000000000001410652014100247235ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pyautodoc_typehints/example/example.py000066400000000000000000000001771410652014100267350ustar00rootroot00000000000000class A: def test(a: int) -> bool: """Test. Args: a: Argument """ return False sphinx-autoapi-1.8.4/tests/python/pyautodoc_typehints/example/example2.py000066400000000000000000000001771410652014100270170ustar00rootroot00000000000000class B: def test(a: int) -> bool: """Test. Args: a: Argument """ return False sphinx-autoapi-1.8.4/tests/python/pyautodoc_typehints/index.rst000066400000000000000000000007171410652014100251360ustar00rootroot00000000000000.. 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` sphinx-autoapi-1.8.4/tests/python/pyexample/000077500000000000000000000000001410652014100211565ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pyexample/conf.py000066400000000000000000000010441410652014100224540ustar00rootroot00000000000000# -*- 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" htmlhelp_basename = "pyexampledoc" extensions = ["sphinx.ext.autodoc", "autoapi.extension"] autoapi_type = "python" autoapi_dirs = ["example"] autoapi_file_pattern = "*.py" autoapi_python_class_content = "both" sphinx-autoapi-1.8.4/tests/python/pyexample/example/000077500000000000000000000000001410652014100226115ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pyexample/example/example.py000066400000000000000000000054241410652014100246230ustar00rootroot00000000000000# -*- coding: utf-8 -*- """Example module This is a description """ class Foo(object): """Can we parse arguments from the class docstring? :param attr: Set an attribute. :type attr: str """ class_var = 42 #: Class var docstring another_class_var = 42 """Another class var docstring""" class Meta(object): """A nested class just to test things out""" @classmethod def foo(): """The foo class method""" return True def __init__(self, attr): """Constructor docstring""" self.attr = attr self.attr2 = attr """This is the docstring of an instance attribute. :type: str """ def method_okay(self, foo=None, bar=None): """This method should parse okay""" return True def method_multiline(self, foo=None, bar=None, baz=None): """This is on multiple lines, but should parse okay too pydocstyle gives us lines of source. Test if this means that multiline definitions are covered in the way we're anticipating here """ return True def method_tricky(self, foo=None, bar=dict(foo=1, bar=2)): """This will likely fail our argument testing We parse naively on commas, so the nested dictionary will throw this off """ return True def method_sphinx_docs(self, foo, bar=0): """This method is documented with sphinx style docstrings. :param foo: The first argument. :type foo: int :param int bar: The second argument. :returns: The sum of foo and bar. :rtype: int """ return foo + bar def method_google_docs(self, foo, bar=0): """This method is documented with google style docstrings. Args: foo (int): The first argument. bar (int): The second argument. Returns: int: The sum of foo and bar. """ return foo + bar def method_sphinx_unicode(self): """This docstring uses unicodé. :returns: A string. :rtype: str """ return "sphinx" def method_google_unicode(self): """This docstring uses unicodé. Returns: str: A string. """ return "google" def decorator_okay(func): """This decorator should parse okay.""" def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper class Bar(Foo): def method_okay(self, foo=None, bar=None): pass class ClassWithNoInit: pass class One: """One.""" def __init__(self): """One __init__.""" super().__init__() class MultilineOne(One): """This is a naughty summary line that exists on two lines.""" class Two(One): """Two.""" sphinx-autoapi-1.8.4/tests/python/pyexample/index.rst000066400000000000000000000007351410652014100230240ustar00rootroot00000000000000.. 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 manualapi Contents: .. toctree:: :maxdepth: 2 Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` sphinx-autoapi-1.8.4/tests/python/pyexample/manualapi.rst000066400000000000000000000002321410652014100236540ustar00rootroot00000000000000Autodoc Directives ================== .. autoapimodule:: example :members: :noindex: .. autoapidecorator:: example.decorator_okay :noindex: sphinx-autoapi-1.8.4/tests/python/pyiexample/000077500000000000000000000000001410652014100213275ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pyiexample/conf.py000066400000000000000000000010121410652014100226200ustar00rootroot00000000000000# -*- 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" htmlhelp_basename = "pyexampledoc" extensions = ["sphinx.ext.autodoc", "autoapi.extension"] autoapi_type = "python" autoapi_dirs = ["example"] autoapi_file_patterns = ["*.pyi", "*.py"] sphinx-autoapi-1.8.4/tests/python/pyiexample/example/000077500000000000000000000000001410652014100227625ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pyiexample/example/example.py000066400000000000000000000001061410652014100247640ustar00rootroot00000000000000class DoNotFindThis(object): """pyi files should be preferred.""" sphinx-autoapi-1.8.4/tests/python/pyiexample/example/example.pyi000066400000000000000000000021001410652014100251310ustar00rootroot00000000000000# -*- coding: utf-8 -*- """Example module This is a description """ class Foo(object): """Can we parse arguments from the class docstring? :param attr: Set an attribute. :type attr: str """ class_var = 42 #: Class var docstring another_class_var = 42 """Another class var docstring""" class_var_without_value = ... """A class var without a value.""" class Meta(object): """A nested class just to test things out""" @classmethod def foo(): """The foo class method""" ... def __init__(self, attr): """Constructor docstring""" ... def method_okay(self, foo=None, bar=None): """This method should parse okay""" ... def method_multiline(self, foo=None, bar=None, baz=None): """This is on multiple lines, but should parse okay too pydocstyle gives us lines of source. Test if this means that multiline definitions are covered in the way we're anticipating here """ ... def method_without_docstring(self): ... sphinx-autoapi-1.8.4/tests/python/pyiexample/index.rst000066400000000000000000000007351410652014100231750ustar00rootroot00000000000000.. 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 manualapi Contents: .. toctree:: :maxdepth: 2 Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` sphinx-autoapi-1.8.4/tests/python/pyiexample2/000077500000000000000000000000001410652014100214115ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pyiexample2/conf.py000066400000000000000000000007401410652014100227110ustar00rootroot00000000000000# -*- 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" htmlhelp_basename = "pyexampledoc" extensions = ["sphinx.ext.autodoc", "autoapi.extension"] autoapi_type = "python" autoapi_dirs = ["example"] sphinx-autoapi-1.8.4/tests/python/pyiexample2/example/000077500000000000000000000000001410652014100230445ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pyiexample2/example/example.py000066400000000000000000000001431410652014100250470ustar00rootroot00000000000000# -*- coding: utf-8 -*- """Example module This is a description """ class Foo(object): pass sphinx-autoapi-1.8.4/tests/python/pyiexample2/example/example.pyi000066400000000000000000000001051410652014100252160ustar00rootroot00000000000000class DoNotFindThis(object): """py files should be preferred.""" sphinx-autoapi-1.8.4/tests/python/pyiexample2/index.rst000066400000000000000000000007351410652014100232570ustar00rootroot00000000000000.. 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 manualapi Contents: .. toctree:: :maxdepth: 2 Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` sphinx-autoapi-1.8.4/tests/python/pymovedconfpy/000077500000000000000000000000001410652014100220545ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pymovedconfpy/confpy/000077500000000000000000000000001410652014100233525ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pymovedconfpy/confpy/conf.py000077700000000000000000000000001410652014100305752../../pyexample/conf.pyustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pymovedconfpy/example000077700000000000000000000000001410652014100272222../pyexample/exampleustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pymovedconfpy/index.rst000077700000000000000000000000001410652014100277702../pyexample/index.rstustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pymovedconfpy/manualapi.rst000077700000000000000000000000001410652014100314702../pyexample/manualapi.rstustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/000077500000000000000000000000001410652014100225065ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/000077500000000000000000000000001410652014100241555ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/__init__.py000066400000000000000000000002551410652014100262700ustar00rootroot00000000000000from .subpackage import public_chain from .subpackage.submodule import public_multiple_imports def module_level_method(foo, bar): """A module level method""" pass sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/_private_module.py000066400000000000000000000002331410652014100277030ustar00rootroot00000000000000class PrivateClass(object): """A private class with public facing methods.""" def public_method(): """This is public.""" return 5 sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/binary_data.py000066400000000000000000000000571410652014100270060ustar00rootroot00000000000000# -*- coding: utf-8 -*- data = b"\xf0\xf0\xf0" sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/foo.py000066400000000000000000000033651410652014100253210ustar00rootroot00000000000000"""Example module This is a description """ from ._private_module import PrivateClass as PublicClass from ._subpackage import module_level_method __all__ = ["PublicClass", "Foo"] class Foo(object): class_var = 42 #: Class var docstring another_class_var = 42 """Another class var docstring""" class Meta(object): """A nested class just to test things out""" @classmethod def foo(): """The foo class method""" return True def method_okay(self, foo=None, bar=None): """This method should parse okay""" return True def method_multiline(self, foo=None, bar=None, baz=None): """This is on multiple lines, but should parse okay too pydocstyle gives us lines of source. Test if this means that multiline definitions are covered in the way we're anticipating here """ return True def method_tricky(self, foo=None, bar=dict(foo=1, bar=2)): """This will likely fail our argument testing We parse naively on commas, so the nested dictionary will throw this off """ return True def method_sphinx_docs(self, foo, bar=0): """This method is documented with sphinx style docstrings. :param foo: The first argument. :type foo: int :param int bar: The second argument. :returns: The sum of foo and bar. :rtype: int """ return foo + bar def method_google_docs(self, foo, bar=0): """This method is documented with google style docstrings. Args: foo (int): The first argument. bar (int): The second argument. Returns: int: The sum of foo and bar. """ return foo + bar sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/subpackage/000077500000000000000000000000001410652014100262625ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/subpackage/__init__.py000066400000000000000000000003441410652014100303740ustar00rootroot00000000000000from .submodule import public_chain from .submodule import _private_made_public as now_public_function from .submodule import public_multiple_imports def module_level_method(foo, bar): """A module level method""" pass sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/subpackage/submodule.py000066400000000000000000000004241410652014100306330ustar00rootroot00000000000000def public_chain(): """Part of a public resolution chain.""" return 5 def _private_made_public(): """A private function made public by import.""" return 5 def public_multiple_imports(): """A public function imported in multiple places.""" return 5 sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/unicode_data.py000066400000000000000000000001311410652014100271410ustar00rootroot00000000000000# -*- coding: utf-8 -*- unicode_str = "αβγδεζηθικλμνξοπρςστυφχψ" sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/wildall/000077500000000000000000000000001410652014100256055ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/wildall/__init__.py000066400000000000000000000000261410652014100277140ustar00rootroot00000000000000from .simple import * sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/wildall/simple/000077500000000000000000000000001410652014100270765ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/wildall/simple/__init__.py000066400000000000000000000005761410652014100312170ustar00rootroot00000000000000from ...subpackage import * __all__ = [ "SimpleClass", "simple_function", "public_chain", "module_level_method", "does_not_exist", ] class SimpleClass(object): def simple_method(self): return 5 class NotAllClass(object): def not_all_method(self): return 5 def simple_function(): return 5 def not_all_function(): return 5 sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/wildcard/000077500000000000000000000000001410652014100257465ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/wildcard/__init__.py000066400000000000000000000000331410652014100300530ustar00rootroot00000000000000from ..subpackage import * sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/wildchain/000077500000000000000000000000001410652014100261175ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/wildchain/__init__.py000066400000000000000000000001171410652014100302270ustar00rootroot00000000000000from ..wildcard import module_level_method from ..wildcard import public_chain sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/wildwildchain/000077500000000000000000000000001410652014100267775ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/complex/wildwildchain/__init__.py000066400000000000000000000000321410652014100311030ustar00rootroot00000000000000from ..wildchain import * sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/conf.py000066400000000000000000000007661410652014100240160ustar00rootroot00000000000000# -*- coding: utf-8 -*- templates_path = ["_templates"] source_suffix = ".rst" master_doc = "index" project = u"pypackagecomplex" 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" htmlhelp_basename = "pypackagecomplexdoc" extensions = ["autoapi.extension"] autoapi_type = "python" autoapi_dirs = ["complex"] autoapi_file_pattern = "*.py" sphinx-autoapi-1.8.4/tests/python/pypackagecomplex/index.rst000066400000000000000000000007441410652014100243540ustar00rootroot00000000000000.. pypackagecomplex 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 pypackagecomplex's documentation! ============================================ .. toctree:: autoapi/index Contents: .. toctree:: :maxdepth: 2 Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` sphinx-autoapi-1.8.4/tests/python/pypackageexample/000077500000000000000000000000001410652014100224725ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pypackageexample/conf.py000066400000000000000000000007661410652014100240020ustar00rootroot00000000000000# -*- coding: utf-8 -*- templates_path = ["_templates"] source_suffix = ".rst" master_doc = "index" project = u"pypackageexample" 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" htmlhelp_basename = "pypackageexampledoc" extensions = ["autoapi.extension"] autoapi_type = "python" autoapi_dirs = ["example"] autoapi_file_pattern = "*.py" sphinx-autoapi-1.8.4/tests/python/pypackageexample/example/000077500000000000000000000000001410652014100241255ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pypackageexample/example/__init__.py000066400000000000000000000001401410652014100262310ustar00rootroot00000000000000from . import foo def module_level_method(foo, bar): """A module level method""" pass sphinx-autoapi-1.8.4/tests/python/pypackageexample/example/_private_module.py000066400000000000000000000002331410652014100276530ustar00rootroot00000000000000class PrivateClass(object): """A private class with public facing methods.""" def public_method(): """This is public.""" return 5 sphinx-autoapi-1.8.4/tests/python/pypackageexample/example/foo.py000066400000000000000000000031541410652014100252650ustar00rootroot00000000000000"""Example module This is a description """ class Foo(object): class_var = 42 #: Class var docstring another_class_var = 42 """Another class var docstring""" class Meta(object): """A nested class just to test things out""" @classmethod def foo(): """The foo class method""" return True def method_okay(self, foo=None, bar=None): """This method should parse okay""" return True def method_multiline(self, foo=None, bar=None, baz=None): """This is on multiple lines, but should parse okay too pydocstyle gives us lines of source. Test if this means that multiline definitions are covered in the way we're anticipating here """ return True def method_tricky(self, foo=None, bar=dict(foo=1, bar=2)): """This will likely fail our argument testing We parse naively on commas, so the nested dictionary will throw this off """ return True def method_sphinx_docs(self, foo, bar=0): """This method is documented with sphinx style docstrings. :param foo: The first argument. :type foo: int :param int bar: The second argument. :returns: The sum of foo and bar. :rtype: int """ return foo + bar def method_google_docs(self, foo, bar=0): """This method is documented with google style docstrings. Args: foo (int): The first argument. bar (int): The second argument. Returns: int: The sum of foo and bar. """ return foo + bar sphinx-autoapi-1.8.4/tests/python/pypackageexample/index.rst000066400000000000000000000007351410652014100243400ustar00rootroot00000000000000.. pypackageexample 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 pypackageexample's documentation! ===================================== .. toctree:: autoapi/index Contents: .. toctree:: :maxdepth: 2 Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` sphinx-autoapi-1.8.4/tests/python/pyskipexample/000077500000000000000000000000001410652014100220455ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pyskipexample/conf.py000066400000000000000000000014711410652014100233470ustar00rootroot00000000000000# -*- 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" htmlhelp_basename = "pyexampledoc" extensions = ["sphinx.ext.autodoc", "autoapi.extension"] autoapi_type = "python" autoapi_dirs = ["example"] autoapi_file_pattern = "*.py" autoapi_options = ["members", "undoc-members", "special-members"] SKIP = {"example.foo", "example.Bar", "example.Bar.m", "example.Baf.m", "example.baz"} def maybe_skip_member(app, what, name, obj, skip, options): return name in SKIP def setup(app): app.connect("autoapi-skip-member", maybe_skip_member) sphinx-autoapi-1.8.4/tests/python/pyskipexample/example/000077500000000000000000000000001410652014100235005ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/python/pyskipexample/example/example.py000066400000000000000000000005561410652014100255130ustar00rootroot00000000000000# -*- coding: utf-8 -*- """Example module This is a description """ def foo(): """foo doc""" pass class Bar: """bar doc""" def m(self): """bar m doc""" pass class Baf: """baf doc""" def m(self): """baf m doc""" baz = 100 """baz doc""" anchor = "value" """must be in result document because not ignored""" sphinx-autoapi-1.8.4/tests/python/pyskipexample/index.rst000066400000000000000000000007171410652014100237130ustar00rootroot00000000000000.. 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` sphinx-autoapi-1.8.4/tests/python/test_parser.py000066400000000000000000000074421410652014100220660ustar00rootroot00000000000000# coding=utf8 """Test Python parser""" from io import StringIO import sys from textwrap import dedent import astroid import pytest from autoapi.mappers.python.parser import Parser class TestPythonParser: def parse(self, source): node = astroid.extract_node(source) return Parser().parse(node) def test_parses_basic_file(self): source = """ def foo(bar): pass """ data = self.parse(source)[0] assert data["name"] == "foo" assert data["type"] == "function" def test_parses_all(self): source = """ __all__ = ['Foo', 5.0] """ data = self.parse(source)[0] assert data["name"] == "__all__" assert data["value"] == ["Foo", 5.0] def test_parses_all_multiline(self): source = """ __all__ = [ 'foo', 'bar', ] """ data = self.parse(source)[0] assert data["value"] == ["foo", "bar"] def test_parses_name(self): source = "foo.bar" assert self.parse(source) == {} def test_parses_list(self): name = "__all__" value = [1, 2, 3, 4] source = "{} = {}".format(name, value) data = self.parse(source)[0] assert data["name"] == name assert data["value"] == value def test_parses_nested_list(self): name = "__all__" value = [[1, 2], [3, 4]] source = "{} = {}".format(name, value) data = self.parse(source)[0] assert data["name"] == name assert data["value"] == value def test_arguments(self): """Argument parsing of source""" source = ( "def foobar(self, bar, baz=42, foo=True,\n" " *args, **kwargs):\n" ' "This is a docstring"\n' " return True\n" ) data = self.parse(source)[0] expected = [ (None, "self", None, None), (None, "bar", None, None), (None, "baz", None, "42"), (None, "foo", None, "True"), ("*", "args", None, None), ("**", "kwargs", None, None), ] assert data["args"] == expected def test_advanced_arguments(self): """Advanced argument parsing""" source = ( 'def foobar(self, a, b, c=42, d="string", e=(1,2),\n' ' f={"a": True}, g=None, h=[1,2,3,4],\n' " i=dict(a=True), j=False, *args, **kwargs):\n" ' "This is a docstring"\n' " return True\n" ) data = self.parse(source)[0] expected = [ (None, "self", None, None), (None, "a", None, None), (None, "b", None, None), (None, "c", None, "42"), (None, "d", None, "'string'"), (None, "e", None, "(1, 2)"), (None, "f", None, "{'a': True}"), (None, "g", None, "None"), (None, "h", None, "[1, 2, 3, 4]"), (None, "i", None, "dict(a=True)"), (None, "j", None, "False"), ("*", "args", None, None), ("**", "kwargs", None, None), ] assert data["args"] == expected def test_dict_key_assignment(self): """Ignore assignment to dictionary entries.""" source = """ MY_DICT = {} #@ if condition: MY_DICT['key'] = 'value' MY_DICT['key2'] = 'value2' """ data = self.parse(source)[0] assert data["name"] == "MY_DICT" def test_list_index_assignment(self): """Ignore assignment to indexes.""" source = """ COLOUR = [255, 128, 0] #@ if condition: COLOUR[1] = 255 COLOUR[2] = 255 """ data = self.parse(source)[0] assert data["name"] == "COLOUR" sphinx-autoapi-1.8.4/tests/python/test_pyintegration.py000066400000000000000000000744071410652014100234730ustar00rootroot00000000000000import io import os import pathlib import re import shutil import sys from unittest.mock import patch, Mock, call import pytest import sphinx from sphinx.application import Sphinx import sphinx.util.logging from autoapi.mappers.python import ( PythonModule, PythonFunction, PythonClass, PythonData, PythonMethod, ) import autoapi.settings def rebuild(confoverrides=None, confdir=".", **kwargs): app = Sphinx( srcdir=".", confdir=confdir, outdir="_build/text", doctreedir="_build/.doctrees", buildername="text", confoverrides=confoverrides, **kwargs ) app.build() @pytest.fixture(scope="class") def builder(): cwd = os.getcwd() def build(test_dir, confoverrides=None, **kwargs): os.chdir("tests/python/{0}".format(test_dir)) rebuild(confoverrides=confoverrides, **kwargs) yield build try: shutil.rmtree("_build") finally: os.chdir(cwd) class TestSimpleModule: @pytest.fixture(autouse=True, scope="class") def built(self, builder): builder( "pyexample", warningiserror=True, confoverrides={"suppress_warnings": ["app"]}, ) def test_integration(self): self.check_integration("_build/text/autoapi/example/index.txt") def test_manual_directives(self): example_path = "_build/text/manualapi.txt" # The manual directives should contain the same information self.check_integration(example_path) with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() assert "@example.decorator_okay" in example_file def check_integration(self, example_path): with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() assert "class example.Foo" in example_file assert "class Meta" in example_file assert "attr2" in example_file assert "This is the docstring of an instance attribute." in example_file assert "method_okay(self, foo=None, bar=None)" in example_file assert "method_multiline(self, foo=None, bar=None, baz=None)" in example_file assert "method_tricky(self, foo=None, bar=dict(foo=1, bar=2))" in example_file # Are constructor arguments from the class docstring parsed? assert "Set an attribute" in example_file # "self" should not be included in constructor arguments assert "Foo(self" not in example_file # Overridden methods without their own docstring # should inherit the parent's docstring assert example_file.count("This method should parse okay") == 2 assert not os.path.exists("_build/text/autoapi/method_multiline") # Inherited constructor docstrings should be included in a merged # (autoapi_python_class_content="both") class docstring only once. assert example_file.count("One __init__.") == 3 index_path = "_build/text/index.txt" with io.open(index_path, encoding="utf8") as index_handle: index_file = index_handle.read() assert "API Reference" in index_file assert "Foo" in index_file assert "Meta" in index_file def test_napoleon_integration_not_loaded(self, builder): example_path = "_build/text/autoapi/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() # Check that docstrings are not transformed without napoleon loaded assert "Args" in example_file assert "Returns" in example_file def test_show_inheritance(self, builder): example_path = "_build/text/autoapi/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() assert "Bases:" in example_file class TestMovedConfPy(TestSimpleModule): @pytest.fixture(autouse=True, scope="class") def built(self, builder): builder( "pymovedconfpy", confdir="confpy", warningiserror=True, confoverrides={"suppress_warnings": ["app"]}, ) class TestSimpleModuleDifferentPrimaryDomain: @pytest.fixture(autouse=True, scope="class") def built(self, builder): builder( "pyexample", warningiserror=True, confoverrides={ "autoapi_options": [ "members", "undoc-members", "private-members", "special-members", "imported-members", ], "primary_domain": "cpp", "suppress_warnings": ["app"], }, ) def test_success(self): pass class TestSimpleStubModule: @pytest.fixture(autouse=True, scope="class") def built(self, builder): builder("pyiexample") def test_integration(self): example_path = "_build/text/autoapi/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() # Are pyi files preferred assert "DoNotFindThis" not in example_file assert "class example.Foo" in example_file assert "class Meta" in example_file assert "Another class var docstring" in example_file assert "A class var without a value." in example_file assert "method_okay(self, foo=None, bar=None)" in example_file assert "method_multiline(self, foo=None, bar=None, baz=None)" in example_file assert "method_without_docstring(self)" in example_file # Are constructor arguments from the class docstring parsed? assert "Set an attribute" in example_file class TestSimpleStubModuleNotPreferred: @pytest.fixture(autouse=True, scope="class") def built(self, builder): builder("pyiexample2") def test_integration(self): example_path = "_build/text/autoapi/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() # Are py files preferred assert "DoNotFindThis" not in example_file assert "Foo" in example_file class TestPy3Module: @pytest.fixture(autouse=True, scope="class") def built(self, builder): builder("py3example") def test_integration(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 "Initialize self" not in example_file assert "a new type" not in example_file def test_annotations(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 "software = sphinx" in example_file assert "code_snippet = Multiline-String" in example_file assert "max_rating :int = 10" in example_file assert "is_valid" in example_file assert "ratings" in example_file assert "List[int]" in example_file assert "Dict[int, str]" in example_file assert "start: int" in example_file assert "Iterable[int]" in example_file assert "List[Union[str, int]]" in example_file assert "not_yet_a: A" in example_file assert "imported: example2.B" in example_file assert "-> example2.B" in example_file assert "is_an_a" in example_file assert "ClassVar" in example_file assert "instance_var" in example_file assert "global_a :A" in example_file assert "my_method(self) -> str" in example_file assert "class example.SomeMetaclass" in example_file def test_overload(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 "overloaded_func(a: float" in example_file assert "overloaded_func(a: str" in example_file assert "overloaded_func(a: Union" not in example_file assert "Overloaded function" in example_file assert "overloaded_method(self, a: float" in example_file assert "overloaded_method(self, a: str" in example_file assert "overloaded_method(self, a: Union" not in example_file assert "Overloaded method" in example_file assert "overloaded_class_method(cls, a: float" in example_file assert "overloaded_class_method(cls, a: str" in example_file assert "overloaded_class_method(cls, a: Union" not in example_file assert "Overloaded method" in example_file assert "undoc_overloaded_func" in example_file assert "undoc_overloaded_method" in example_file assert "C(a: int" in example_file assert "C(a: float" in example_file assert "C(a: str" not in example_file assert "C(self, a: int" not in example_file assert "C(self, a: float" not in example_file assert "C(self, a: str" not in example_file def test_async(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 "async async_method" in example_file assert "async example.async_function" in example_file def test_py3_hiding_undoc_overloaded_members(builder): confoverrides = {"autoapi_options": ["members", "special-members"]} builder("py3example", confoverrides=confoverrides) example_path = "_build/text/autoapi/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() assert "overloaded_func" in example_file assert "overloaded_method" in example_file assert "undoc_overloaded_func" not in example_file assert "undoc_overloaded_method" not in example_file class TestAnnotationCommentsModule: @pytest.fixture(autouse=True, scope="class") def built(self, builder): builder("pyannotationcommentsexample") def test_integration(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 "max_rating :int = 10" in example_file assert "ratings" in example_file assert "List[int]" in example_file assert "Dict[int, str]" in example_file # When astroid>2.2.5 # assert "start: int" in example_file # assert "end: int" in example_file assert "Iterable[int]" in example_file assert "List[Union[str, int]]" in example_file assert "not_yet_a: A" in example_file assert "is_an_a" in example_file assert "ClassVar" in example_file assert "instance_var" in example_file assert "global_a :A" in example_file @pytest.mark.skipif( sys.version_info < (3, 8), reason="Positional only arguments need Python >=3.8" ) class TestPositionalOnlyArgumentsModule: @pytest.fixture(autouse=True, scope="class") def built(self, builder): builder("py38positionalparams") def test_integration(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 "f_simple(a, b, /, c, d, *, e, f)" in example_file assert ( "f_comment(a: int, b: int, /, c: Optional[int], d: Optional[int], *, e: float, f: float)" in example_file ) assert ( "f_annotation(a: int, b: int, /, c: Optional[int], d: Optional[int], *, e: float, f: float)" in example_file ) assert ( "f_arg_comment(a: int, b: int, /, c: Optional[int], d: Optional[int], *, e: float, f: float)" in example_file ) assert "f_no_cd(a: int, b: int, /, *, e: float, f: float)" in example_file def test_napoleon_integration_loaded(builder): confoverrides = { "extensions": ["autoapi.extension", "sphinx.ext.autodoc", "sphinx.ext.napoleon"] } builder("pyexample", confoverrides=confoverrides) example_path = "_build/text/autoapi/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() assert "Parameters" in example_file assert "Return type" in example_file assert "Args" not in example_file class TestSimplePackage: @pytest.fixture(autouse=True, scope="class") def built(self, builder): builder("pypackageexample") def test_integration_with_package(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 "example.foo" in example_file assert "example.module_level_method(foo, bar)" in example_file example_foo_path = "_build/text/autoapi/example/foo/index.txt" with io.open(example_foo_path, encoding="utf8") as example_foo_handle: example_foo_file = example_foo_handle.read() assert "class example.foo.Foo" in example_foo_file assert "method_okay(self, foo=None, bar=None)" in example_foo_file index_path = "_build/text/index.txt" with io.open(index_path, encoding="utf8") as index_handle: index_file = index_handle.read() assert "API Reference" in index_file assert "example.foo" in index_file assert "Foo" in index_file assert "module_level_method" in index_file def test_simple_no_false_warnings(builder, caplog): logger = sphinx.util.logging.getLogger("autoapi") logger.logger.addHandler(caplog.handler) builder("pypackageexample") assert "Cannot resolve" not in caplog.text def _test_class_content(builder, class_content): confoverrides = {"autoapi_python_class_content": class_content} builder("pyexample", confoverrides=confoverrides) example_path = "_build/text/autoapi/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() if class_content == "init": assert "Can we parse arguments" not in example_file else: assert "Can we parse arguments" in example_file if class_content not in ("both", "init"): assert "Constructor docstring" not in example_file else: assert "Constructor docstring" in example_file def test_class_class_content(builder): _test_class_content(builder, "class") def test_both_class_content(builder): _test_class_content(builder, "both") def test_init_class_content(builder): _test_class_content(builder, "init") def test_hiding_private_members(builder): confoverrides = {"autoapi_options": ["members", "undoc-members", "special-members"]} builder("pypackageexample", confoverrides=confoverrides) example_path = "_build/text/autoapi/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() assert "private" not in example_file private_path = "_build/text/autoapi/example/_private_module/index.txt" with io.open(private_path, encoding="utf8") as private_handle: private_file = private_handle.read() assert "public_method" in private_file def test_hiding_inheritance(builder): confoverrides = {"autoapi_options": ["members", "undoc-members", "special-members"]} builder("pyexample", confoverrides=confoverrides) example_path = "_build/text/autoapi/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() assert "Bases:" not in example_file def test_hiding_imported_members(builder): confoverrides = {"autoapi_options": ["members", "undoc-members"]} builder("pypackagecomplex", confoverrides=confoverrides) subpackage_path = "_build/text/autoapi/complex/subpackage/index.txt" with io.open(subpackage_path, encoding="utf8") as subpackage_handle: subpackage_file = subpackage_handle.read() assert "Part of a public resolution chain." not in subpackage_file package_path = "_build/text/autoapi/complex/index.txt" with io.open(package_path, encoding="utf8") as package_handle: package_file = package_handle.read() assert "Part of a public resolution chain." not in package_file submodule_path = "_build/text/autoapi/complex/subpackage/submodule/index.txt" with io.open(submodule_path, encoding="utf8") as submodule_handle: submodule_file = submodule_handle.read() assert "A private function made public by import." not in submodule_file def test_inherited_members(builder): confoverrides = { "autoapi_options": ["members", "inherited-members", "undoc-members"] } builder("pyexample", confoverrides=confoverrides) example_path = "_build/text/autoapi/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() assert "class example.Bar" in example_file i = example_file.index("class example.Bar") assert "method_okay" in example_file[i:] def test_skipping_members(builder): builder("pyskipexample") example_path = "_build/text/autoapi/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() assert "foo doc" not in example_file assert "bar doc" not in example_file assert "bar m doc" not in example_file assert "baf doc" in example_file assert "baf m doc" not in example_file assert "baz doc" not in example_file assert "not ignored" in example_file @pytest.mark.parametrize( "value,order", [ ("bysource", [".Foo", ".decorator_okay", ".Bar"]), ("alphabetical", [".Bar", ".Foo", ".decorator_okay"]), ("groupwise", [".Bar", ".Foo", ".decorator_okay"]), ], ) def test_order_members(builder, value, order): confoverrides = {"autoapi_member_order": value} builder("pyexample", confoverrides=confoverrides) example_path = "_build/text/autoapi/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() indexes = [example_file.index(name) for name in order] assert indexes == sorted(indexes) class _CompareInstanceType: def __init__(self, type_): self.type = type_ def __eq__(self, other): return self.type is type(other) def __repr__(self): return "".format(self.type.__name__) def test_skip_members_hook(builder): emit_firstresult_patch = Mock(name="emit_firstresult_patch", return_value=False) with patch("sphinx.application.Sphinx.emit_firstresult", emit_firstresult_patch): builder("pyskipexample") options = ["members", "undoc-members", "special-members"] mock_calls = [ call( "autoapi-skip-member", "module", "example", _CompareInstanceType(PythonModule), False, options, ), call( "autoapi-skip-member", "function", "example.foo", _CompareInstanceType(PythonFunction), False, options, ), call( "autoapi-skip-member", "class", "example.Bar", _CompareInstanceType(PythonClass), False, options, ), call( "autoapi-skip-member", "class", "example.Baf", _CompareInstanceType(PythonClass), False, options, ), call( "autoapi-skip-member", "data", "example.baz", _CompareInstanceType(PythonData), False, options, ), call( "autoapi-skip-member", "data", "example.anchor", _CompareInstanceType(PythonData), False, options, ), call( "autoapi-skip-member", "method", "example.Bar.m", _CompareInstanceType(PythonMethod), False, options, ), call( "autoapi-skip-member", "method", "example.Baf.m", _CompareInstanceType(PythonMethod), False, options, ), ] for mock_call in mock_calls: assert mock_call in emit_firstresult_patch.mock_calls class TestComplexPackage: @pytest.fixture(autouse=True, scope="class") def built(self, builder): builder("pypackagecomplex") def test_public_chain_resolves(self): submodule_path = "_build/text/autoapi/complex/subpackage/submodule/index.txt" with io.open(submodule_path, encoding="utf8") as submodule_handle: submodule_file = submodule_handle.read() assert "Part of a public resolution chain." in submodule_file subpackage_path = "_build/text/autoapi/complex/subpackage/index.txt" with io.open(subpackage_path, encoding="utf8") as subpackage_handle: subpackage_file = subpackage_handle.read() assert "Part of a public resolution chain." in subpackage_file package_path = "_build/text/autoapi/complex/index.txt" with io.open(package_path, encoding="utf8") as package_handle: package_file = package_handle.read() assert "Part of a public resolution chain." in package_file def test_private_made_public(self): submodule_path = "_build/text/autoapi/complex/subpackage/submodule/index.txt" with io.open(submodule_path, encoding="utf8") as submodule_handle: submodule_file = submodule_handle.read() assert "A private function made public by import." in submodule_file def test_multiple_import_locations(self): submodule_path = "_build/text/autoapi/complex/subpackage/submodule/index.txt" with io.open(submodule_path, encoding="utf8") as submodule_handle: submodule_file = submodule_handle.read() assert "A public function imported in multiple places." in submodule_file subpackage_path = "_build/text/autoapi/complex/subpackage/index.txt" with io.open(subpackage_path, encoding="utf8") as subpackage_handle: subpackage_file = subpackage_handle.read() assert "A public function imported in multiple places." in subpackage_file package_path = "_build/text/autoapi/complex/index.txt" with io.open(package_path, encoding="utf8") as package_handle: package_file = package_handle.read() assert "A public function imported in multiple places." in package_file def test_simple_wildcard_imports(self): wildcard_path = "_build/text/autoapi/complex/wildcard/index.txt" with io.open(wildcard_path, encoding="utf8") as wildcard_handle: wildcard_file = wildcard_handle.read() assert "public_chain" in wildcard_file assert "now_public_function" in wildcard_file assert "public_multiple_imports" in wildcard_file assert "module_level_method" in wildcard_file def test_wildcard_chain(self): wildcard_path = "_build/text/autoapi/complex/wildchain/index.txt" with io.open(wildcard_path, encoding="utf8") as wildcard_handle: wildcard_file = wildcard_handle.read() assert "public_chain" in wildcard_file assert "module_level_method" in wildcard_file def test_wildcard_all_imports(self): wildcard_path = "_build/text/autoapi/complex/wildall/index.txt" with io.open(wildcard_path, encoding="utf8") as wildcard_handle: wildcard_file = wildcard_handle.read() assert "not_all" not in wildcard_file assert "NotAllClass" not in wildcard_file assert "does_not_exist" not in wildcard_file assert "SimpleClass" in wildcard_file assert "simple_function" in wildcard_file assert "public_chain" in wildcard_file assert "module_level_method" in wildcard_file def test_no_imports_in_module_with_all(self): foo_path = "_build/text/autoapi/complex/foo/index.txt" with io.open(foo_path, encoding="utf8") as foo_handle: foo_file = foo_handle.read() assert "module_level_method" not in foo_file def test_all_overrides_import_in_module_with_all(self): foo_path = "_build/text/autoapi/complex/foo/index.txt" with io.open(foo_path, encoding="utf8") as foo_handle: foo_file = foo_handle.read() assert "PublicClass" in foo_file def test_parses_unicode_file(self): foo_path = "_build/text/autoapi/complex/unicode_data/index.txt" with io.open(foo_path, encoding="utf8") as foo_handle: foo_file = foo_handle.read() assert "unicode_str" in foo_file class TestComplexPackageParallel: @pytest.fixture(autouse=True, scope="class") def built(self, builder): builder("pypackagecomplex", parallel=2) def test_success(self): pass def test_caching(builder): mtimes = (0, 0) def record_mtime(): nonlocal mtimes mtime = 0 for root, _, files in os.walk("_build/text/autoapi"): for name in files: this_mtime = os.path.getmtime(os.path.join(root, name)) mtime = max(mtime, this_mtime) mtimes = (*mtimes[1:], mtime) builder("pypackagecomplex", confoverrides={"autoapi_keep_files": True}) record_mtime() rebuild(confoverrides={"autoapi_keep_files": True}) record_mtime() assert mtimes[1] == mtimes[0] # Check that adding a file rebuilds the docs extra_file = "complex/new.py" with open(extra_file, "w") as out_f: out_f.write("\n") try: rebuild(confoverrides={"autoapi_keep_files": True}) finally: os.remove(extra_file) record_mtime() assert mtimes[1] != mtimes[0] # Removing a file also rebuilds the docs rebuild(confoverrides={"autoapi_keep_files": True}) record_mtime() assert mtimes[1] != mtimes[0] # Changing not keeping files always builds rebuild() record_mtime() assert mtimes[1] != mtimes[0] class TestImplicitNamespacePackage: @pytest.fixture(autouse=True, scope="class") def built(self, builder): builder("py3implicitnamespace") def test_sibling_import_from_namespace(self): example_path = "_build/text/autoapi/namespace/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() assert "namespace.example.first_method" in example_file def test_sub_sibling_import_from_namespace(self): example_path = "_build/text/autoapi/namespace/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() assert "namespace.example.second_sub_method" in example_file def test_custom_jinja_filters(builder, tmp_path): py_templates = tmp_path / "python" py_templates.mkdir() orig_py_templates = pathlib.Path(autoapi.settings.TEMPLATE_DIR) / "python" orig_template = (orig_py_templates / "class.rst").read_text() (py_templates / "class.rst").write_text( orig_template.replace("obj.docstring", "obj.docstring|prepare_docstring") ) confoverrides = { "autoapi_prepare_jinja_env": ( lambda jinja_env: jinja_env.filters.update( { "prepare_docstring": ( lambda docstring: "This is using custom filters." ) } ) ), "autoapi_template_dir": str(tmp_path), } builder("pyexample", confoverrides=confoverrides) example_path = "_build/text/autoapi/example/index.txt" with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() assert "This is using custom filters." in example_file def test_string_module_attributes(builder): """Test toggle for multi-line string attribute values (GitHub #267).""" keep_rst = { "autoapi_keep_files": True, "autoapi_root": "_build/autoapi", # Preserve RST files under _build for cleanup } builder("py3example", confoverrides=keep_rst) example_path = os.path.join(keep_rst["autoapi_root"], "example", "index.rst") with io.open(example_path, encoding="utf8") as example_handle: example_file = example_handle.read() code_snippet_contents = [ ".. py:data:: code_snippet", " :annotation: = Multiline-String", "", " .. raw:: html", "", "
Show Value", "", " .. code-block:: text", " :linenos:", "", " ", # <--- Line array monstrosity to preserve these leading spaces " # -*- coding: utf-8 -*-", " from __future__ import absolute_import, division, print_function, unicode_literals", " # from future.builtins.disabled import *", " # from builtins import *", "", """ print("chunky o'block")""", "", "", " .. raw:: html", "", "
", ] 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 sphinx-autoapi-1.8.4/tests/templateexample/000077500000000000000000000000001410652014100210205ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/templateexample/conf.py000066400000000000000000000011361410652014100223200ustar00rootroot00000000000000# -*- 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 = ["autoapi.extension"] autoapi_type = "python" autoapi_dirs = ["example"] autoapi_file_pattern = "*.py" autoapi_template_dir = "template_overrides" exclude_patterns = [autoapi_template_dir] sphinx-autoapi-1.8.4/tests/templateexample/example/000077500000000000000000000000001410652014100224535ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/templateexample/example/example.py000066400000000000000000000002151410652014100244560ustar00rootroot00000000000000__author__ = "swenson" import math def example_function(x): """Compute the square root of x and return it.""" return math.sqrt(x) sphinx-autoapi-1.8.4/tests/templateexample/index.rst000066400000000000000000000007201410652014100226600ustar00rootroot00000000000000.. 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` sphinx-autoapi-1.8.4/tests/templateexample/template_overrides/000077500000000000000000000000001410652014100247155ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/templateexample/template_overrides/python/000077500000000000000000000000001410652014100262365ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/templateexample/template_overrides/python/function.rst000066400000000000000000000000441410652014100306130ustar00rootroot00000000000000This is a fuction template override!sphinx-autoapi-1.8.4/tests/test_astroid_utils.py000066400000000000000000000146231410652014100221350ustar00rootroot00000000000000import sys import astroid from autoapi.mappers.python import astroid_utils, objects import pytest def generate_module_names(): for i in range(1, 5): yield ".".join("module{}".format(j) for j in range(i)) yield "package.repeat.repeat" def imported_basename_cases(): for module_name in generate_module_names(): import_ = "import {}".format(module_name) basename = "{}.ImportedClass".format(module_name) expected = basename yield (import_, basename, expected) import_ = "import {} as aliased".format(module_name) basename = "aliased.ImportedClass" yield (import_, basename, expected) if "." in module_name: from_name, attribute = module_name.rsplit(".", 1) import_ = "from {} import {}".format(from_name, attribute) basename = "{}.ImportedClass".format(attribute) yield (import_, basename, expected) import_ += " as aliased" basename = "aliased.ImportedClass" yield (import_, basename, expected) import_ = "from {} import ImportedClass".format(module_name) basename = "ImportedClass" yield (import_, basename, expected) import_ = "from {} import ImportedClass as AliasedClass".format(module_name) basename = "AliasedClass" yield (import_, basename, expected) def generate_args(): for i in range(5): yield ", ".join("arg{}".format(j) for j in range(i)) def imported_call_cases(): for args in generate_args(): for import_, basename, expected in imported_basename_cases(): basename += "({})".format(args) expected += "()" yield import_, basename, expected class TestAstroidUtils: @pytest.mark.parametrize( ("import_", "basename", "expected"), list(imported_basename_cases()) ) def test_can_get_full_imported_basename(self, import_, basename, expected): source = """ {} class ThisClass({}): #@ pass """.format( import_, basename ) node = astroid.extract_node(source) basenames = astroid_utils.resolve_qualname(node.bases[0], node.basenames[0]) assert basenames == expected @pytest.mark.parametrize( ("import_", "basename", "expected"), list(imported_call_cases()) ) def test_can_get_full_function_basename(self, import_, basename, expected): source = """ {} class ThisClass({}): #@ pass """.format( import_, basename ) node = astroid.extract_node(source) basenames = astroid_utils.resolve_qualname(node.bases[0], node.basenames[0]) assert basenames == expected @pytest.mark.parametrize( ("source", "expected"), [ ('a = "a"', ("a", "a")), ("a = 1", ("a", 1)), ("a, b, c = (1, 2, 3)", None), ("a = b = 1", None), ], ) def test_can_get_assign_values(self, source, expected): node = astroid.extract_node(source) value = astroid_utils.get_assign_value(node) assert value == expected @pytest.mark.parametrize( "signature,expected", [ ( "a: bool, b: int = 5", [(None, "a", "bool", None), (None, "b", "int", "5")], ), pytest.param( "a: bool, /, b: int, *, c: str", [ (None, "a", "bool", None), ("/", None, None, None), (None, "b", "int", None), ("*", None, None, None), (None, "c", "str", None), ], marks=pytest.mark.skipif( sys.version_info[:2] < (3, 8), reason="Uses Python 3.8+ syntax" ), ), pytest.param( "a: bool, /, b: int, *args, c: str, **kwargs", [ (None, "a", "bool", None), ("/", None, None, None), (None, "b", "int", None), ("*", "args", None, None), (None, "c", "str", None), ("**", "kwargs", None, None), ], marks=pytest.mark.skipif( sys.version_info[:2] < (3, 8), reason="Uses Python 3.8+ syntax" ), ), pytest.param( "a: int, *args, b: str, **kwargs", [ (None, "a", "int", None), ("*", "args", None, None), (None, "b", "str", None), ("**", "kwargs", None, None), ], marks=pytest.mark.skipif( sys.version_info[:2] < (3, 8), reason="Uses Python 3.8+ syntax" ), ), ], ) def test_parse_annotations(self, signature, expected): node = astroid.extract_node( """ def func({}) -> str: #@ pass """.format( signature ) ) annotations = astroid_utils.get_args_info(node.args) assert annotations == expected @pytest.mark.parametrize( "signature,expected", [ ("a: bool, b: int = 5, c='hi'", "a: bool, b: int = 5, c='hi'"), pytest.param( "a: bool, /, b: int, *, c: str", "a: bool, /, b: int, *, c: str", marks=pytest.mark.skipif( sys.version_info[:2] < (3, 8), reason="Uses Python 3.8+ syntax" ), ), pytest.param( "a: bool, /, b: int, *args, c: str, **kwargs", "a: bool, /, b: int, *args, c: str, **kwargs", marks=pytest.mark.skipif( sys.version_info[:2] < (3, 8), reason="Uses Python 3.8+ syntax" ), ), ("a: int, *args, b: str, **kwargs", "a: int, *args, b: str, **kwargs"), ("a: 'A'", "a: A"), ], ) def test_format_args(self, signature, expected): node = astroid.extract_node( """ def func({}) -> str: #@ pass """.format( signature ) ) args_info = astroid_utils.get_args_info(node.args) formatted = objects._format_args(args_info) assert formatted == expected sphinx-autoapi-1.8.4/tests/test_domains.py000066400000000000000000000156071410652014100207050ustar00rootroot00000000000000"""Test .NET autoapi domain""" from unittest import mock from unittest.mock import patch from autoapi.mappers import dotnet class MockConfig: def __getattr__(self, key): attrs = { "autoapi_dirs": ["/tmp/autoapi/tmp"], "autoapi_root": "/tmp/autoapi/root", } return attrs.get(key, None) class MockApplication: config = MockConfig() def warn(self, *args, **kwargs): pass class TestDotNetSphinxMapper: def test_create_class(self): """Test .NET class instance creation helper""" dom = dotnet.DotNetSphinxMapper(MockApplication()) def _create_class(data): return list(dom.create_class(data))[0] cls = _create_class({"id": "Foo.Bar", "type": "Namespace"}) assert isinstance(cls, dotnet.DotNetNamespace) cls = _create_class({"id": "Foo.Bar", "type": "Class"}) assert isinstance(cls, dotnet.DotNetClass) cls = _create_class({"id": "Foo.Bar", "type": "Property"}) assert isinstance(cls, dotnet.DotNetProperty) cls = _create_class({"id": "Foo.Bar", "type": "Method"}) assert isinstance(cls, dotnet.DotNetMethod) cls = _create_class({"id": "Foo.Bar", "type": "Enum"}) assert isinstance(cls, dotnet.DotNetEnum) cls = _create_class({"id": "Foo.Bar", "type": "Constructor"}) assert isinstance(cls, dotnet.DotNetConstructor) cls = _create_class({"id": "Foo.Bar", "type": "Struct"}) assert isinstance(cls, dotnet.DotNetStruct) cls = _create_class({"id": "Foo.Bar", "type": "Interface"}) assert isinstance(cls, dotnet.DotNetInterface) cls = _create_class({"id": "Foo.Bar", "type": "Delegate"}) assert isinstance(cls, dotnet.DotNetDelegate) cls = _create_class({"id": "Foo.Bar", "type": "Field"}) assert isinstance(cls, dotnet.DotNetField) cls = _create_class({"id": "Foo.Bar", "type": "Event"}) assert isinstance(cls, dotnet.DotNetEvent) def test_create_class_with_children(self): dom = dotnet.DotNetSphinxMapper(MockApplication()) def _create_class(data): return list(dom.create_class(data))[0] cls = _create_class( { "id": "Foo.Bar", "type": "Class", "items": [{"id": "Foo.Bar.Baz", "type": "Method"}], } ) assert isinstance(cls, dotnet.DotNetClass) assert cls.item_map == {} @patch("subprocess.check_output", lambda foo: foo) def test_get_objects(self): """Test basic get objects""" objs = [] def _mock_find(self, patterns, **kwargs): return {"items": ["foo", "bar"]} def _mock_read(self, path): return { "items": [ {"id": "Foo.Bar", "name": "Foo", "type": "property"}, {"id": "Foo.Bar2", "name": "Bar", "type": "property"}, ], "id": "Foo.Bar", "type": "Class", "summary": path, } with patch("autoapi.mappers.dotnet.DotNetSphinxMapper.find_files", _mock_find): with patch( "autoapi.mappers.dotnet.DotNetSphinxMapper.read_file", _mock_read ): dom = dotnet.DotNetSphinxMapper(MockApplication()) dom.load("", "", "") dom.map() objs = dom.objects assert len(objs) == 2 assert objs["Foo.Bar"].id == "Foo.Bar" assert objs["Foo.Bar"].name == "Foo.Bar" assert objs["Foo.Bar2"].id == "Foo.Bar2" assert objs["Foo.Bar2"].name == "Foo.Bar2" class TestDotNetPythonMapper: def test_xml_parse(self): """XML doc comment parsing""" ret = dotnet.DotNetPythonMapper.transform_doc_comments( 'This is an example comment ' ) assert ret == "This is an example comment :any:`FOO`" ret = dotnet.DotNetPythonMapper.transform_doc_comments( 'This is an example comment ' ) assert ret == "This is an example comment FOO" ret = dotnet.DotNetPythonMapper.transform_doc_comments( 'This is an example comment inner foo' ) assert ret == "This is an example comment :dn:ns:`FOO`" ret = dotnet.DotNetPythonMapper.transform_doc_comments( 'Test and Blah' ) assert ret == "Test :dn:prop:`FOO` and :dn:event:`BAR`" ret = dotnet.DotNetPythonMapper.transform_doc_comments( 'This is an example comment ' ) assert ret == "This is an example comment ``FOO``" ret = dotnet.DotNetPythonMapper.transform_doc_comments( 'This is an example comment ' ) assert ret == "This is an example comment ``FOO``" ret = dotnet.DotNetPythonMapper.transform_doc_comments( 'With surrounding characters ss' ) assert ret == r"With surrounding characters s :any:`FOO`\s" ret = dotnet.DotNetPythonMapper.transform_doc_comments( 'With surrounding characters ss' ) assert ret == r"With surrounding characters s ``FOO``\s" def test_xml_transform_escape(self): """XML transform escaping""" ret = dotnet.DotNetPythonMapper.transform_doc_comments( 'Foo Bar' ) assert ret == "Foo :any:`Foo\\`1` Bar" ret = dotnet.DotNetPythonMapper.transform_doc_comments( 'No space beforeor after' ) assert ret == "No space before :dn:meth:`Foo\\`1`\\or after" def test_parsing_obj(self): """Parse out object, test for transforms, etc""" obj = { "uid": "Foo`1", "name": "Foo", "summary": 'Test parsing ', "syntax": { "parameters": [ { "id": "a", "type": "{TUser}", "description": 'Test ', } ], "return": { "type": "Bar", "description": ( 'Test references ' 'and paramrefs ' ), }, }, } mapped = dotnet.DotNetPythonMapper(obj, app=mock.MagicMock(), jinja_env=None) expected = {"name": "a", "type": "{TUser}", "desc": "Test :any:`TUser`"} assert mapped.parameters[0] == expected assert ( mapped.returns["description"] == "Test references :any:`Bar` and paramrefs ``a``" ) sphinx-autoapi-1.8.4/tests/test_integration.py000066400000000000000000000127241410652014100215730ustar00rootroot00000000000000import io import json import os import sys import shutil from contextlib import contextmanager from unittest.mock import patch import pytest import sphinx from sphinx.application import Sphinx from sphinx.errors import ExtensionError @contextmanager def sphinx_build(test_dir, confoverrides=None): os.chdir("tests/{0}".format(test_dir)) try: app = Sphinx( srcdir=".", confdir=".", outdir="_build/text", doctreedir="_build/.doctrees", buildername="text", confoverrides=confoverrides, ) app.build(force_all=True) yield finally: if os.path.exists("_build"): shutil.rmtree("_build") os.chdir("../..") class LanguageIntegrationTests: def _run_test(self, test_dir, test_file, test_string): with sphinx_build(test_dir): with io.open(test_file, encoding="utf8") as fin: text = fin.read().strip() assert test_string in text class TestJavaScript(LanguageIntegrationTests): def _js_read(self, path): return json.load(open("../fixtures/javascript.json")) @patch("autoapi.mappers.javascript.JavaScriptSphinxMapper.read_file", _js_read) def test_integration(self): self._run_test( "jsexample", "_build/text/autoapi/Circle/index.txt", "Creates an instance of Circle", ) @pytest.mark.skipif( sphinx.version_info >= (3,), reason="golangdomain extension does not support sphinx >=3", ) class TestGo(LanguageIntegrationTests): def _go_read(self, path, **kwargs): return json.load(open("../fixtures/go.json")) @patch("autoapi.mappers.go.GoSphinxMapper.read_file", _go_read) def test_integration(self): self._run_test( "goexample", "_build/text/autoapi/main/index.txt", "CopyFuncs produces a json-annotated array of Func objects", ) @pytest.mark.skipif( sphinx.version_info >= (3,), reason="dotnetdomain extension does not support sphinx >=3", ) class TestDotNet(LanguageIntegrationTests): def _dotnet_read(self, path): return json.load(open("../fixtures/dotnet.json")) # Mock this because it's slow otherwise def _dotnet_load(self, patterns, dirs, ignore=()): data = self.read_file(path="inmem") self.paths["inmem"] = data @staticmethod def _dotnet_finished(app, exception): pass @patch("autoapi.mappers.dotnet.DotNetSphinxMapper.load", _dotnet_load) @patch("autoapi.mappers.dotnet.DotNetSphinxMapper.read_file", _dotnet_read) @patch("autoapi.mappers.dotnet.DotNetSphinxMapper.build_finished", _dotnet_finished) def test_integration(self): self._run_test( "dotnetexample", "_build/text/autoapi/Microsoft/AspNet/Identity/IUserStore-TUser/index.txt", "Provides an abstraction for a store which manages user accounts.", ) class TestIntegration(LanguageIntegrationTests): def test_template_overrides(self): self._run_test( "templateexample", "_build/text/autoapi/example/index.txt", "This is a fuction template override", ) class TestTOCTree(LanguageIntegrationTests): def test_toctree_overrides(self): self._run_test("toctreeexample", "_build/text/index.txt", "API Reference") def test_toctree_domain_insertion(self): """ Test that the example_function gets added to the TOC Tree """ self._run_test("toctreeexample", "_build/text/index.txt", "* example_function") class TestExtensionErrors: @pytest.fixture(autouse=True) def unload_go_and_dotned_libraries(self): # unload dotnet and golang domain libraries, because they may be imported before for mod_name in ("sphinxcontrib.dotnetdomain", "sphinxcontrib.golangdomain"): try: del sys.modules[mod_name] except KeyError: pass @pytest.mark.parametrize( "proj_name, override_conf, err_msg", [ ( "toctreeexample", {"autoapi_type": "INVALID VALUE"}, ( "Invalid autoapi_type setting, following values is " 'allowed: "dotnet", "go", "javascript", "python"' ), ), ( "goexample", {"autoapi_type": "go", "extensions": ["autoapi.extension"]}, ( "AutoAPI of type `go` requires following " "packages to be installed and included in extensions list: " "sphinxcontrib.golangdomain (available as " '"sphinxcontrib-golangdomain" on PyPI)' ), ), ( "dotnetexample", {"autoapi_type": "dotnet", "extensions": ["autoapi.extension"]}, ( "AutoAPI of type `dotnet` requires following " "packages to be installed and included in extensions list: " "sphinxcontrib.dotnetdomain (available as " '"sphinxcontrib-dotnetdomain" on PyPI)' ), ), ], ) def test_extension_setup_errors(self, proj_name, override_conf, err_msg): with pytest.raises(ExtensionError) as err_info: with sphinx_build(proj_name, override_conf): pass assert str(err_info.value) == err_msg sphinx-autoapi-1.8.4/tests/test_objects.py000066400000000000000000000133451410652014100207010ustar00rootroot00000000000000# coding=utf8 """Test .NET autoapi objects""" from collections import namedtuple from unittest import mock import os from jinja2 import Environment, FileSystemLoader from autoapi.mappers import dotnet from autoapi.mappers import python from autoapi.settings import TEMPLATE_DIR class TestDotNetObject: def test_type(self): """Test types of some of the objects""" obj = dotnet.DotNetNamespace({"id": "Foo.Bar"}, jinja_env=None, app=None) assert obj.type == "namespace" assert obj.ref_type == "namespace" assert obj.ref_directive == "ns" obj = dotnet.DotNetMethod({"id": "Foo.Bar"}, jinja_env=None, app=None) assert obj.type == "method" assert obj.ref_type == "method" assert obj.ref_directive == "meth" obj = dotnet.DotNetProperty({"id": "Foo.Bar"}, jinja_env=None, app=None) assert obj.type == "property" assert obj.ref_type == "property" assert obj.ref_directive == "prop" obj = dotnet.DotNetEnum({"id": "Foo.Bar"}, jinja_env=None, app=None) assert obj.type == "enum" assert obj.ref_type == "enumeration" assert obj.ref_directive == "enum" obj = dotnet.DotNetStruct({"id": "Foo.Bar"}, jinja_env=None, app=None) assert obj.type == "struct" assert obj.ref_type == "structure" assert obj.ref_directive == "struct" obj = dotnet.DotNetConstructor({"id": "Foo.Bar"}, jinja_env=None, app=None) assert obj.type == "constructor" assert obj.ref_type == "constructor" assert obj.ref_directive == "ctor" obj = dotnet.DotNetInterface({"id": "Foo.Bar"}, jinja_env=None, app=None) assert obj.type == "interface" assert obj.ref_type == "interface" assert obj.ref_directive == "iface" obj = dotnet.DotNetDelegate({"id": "Foo.Bar"}, jinja_env=None, app=None) assert obj.type == "delegate" assert obj.ref_type == "delegate" assert obj.ref_directive == "del" obj = dotnet.DotNetClass({"id": "Foo.Bar"}, jinja_env=None, app=None) assert obj.type == "class" assert obj.ref_type == "class" assert obj.ref_directive == "cls" obj = dotnet.DotNetField({"id": "Foo.Bar"}, jinja_env=None, app=None) assert obj.type == "field" assert obj.ref_type == "field" assert obj.ref_directive == "field" obj = dotnet.DotNetEvent({"id": "Foo.Bar"}, jinja_env=None, app=None) assert obj.type == "event" assert obj.ref_type == "event" assert obj.ref_directive == "event" def test_names(self): """Test names of objects""" obj = dotnet.DotNetNamespace({"id": "Foo.Bar"}, jinja_env=None, app=None) assert obj.name == "Foo.Bar" assert obj.short_name == "Bar" obj = dotnet.DotNetNamespace( {"id": "Foo.Bar.Something`1"}, jinja_env=None, app=None ) assert obj.name == "Foo.Bar.Something`1" assert obj.short_name == "Something`1" def test_namespace_namespace(self): """Namespace parent resolution""" ns = dotnet.DotNetNamespace({"id": "Foo.Bar.Widgets"}, jinja_env=None, app=None) assert ns.namespace == "Foo.Bar" ns = dotnet.DotNetNamespace({"id": "Foo.Bar"}, jinja_env=None, app=None) assert ns.namespace == "Foo" ns = dotnet.DotNetNamespace({"id": "Foo"}, jinja_env=None, app=None) assert ns.namespace is None def test_class_namespace(self): """Class parent resolution""" cls = dotnet.DotNetClass( dict(id="Foo.Bar.Widget", type="class"), jinja_env=None, app=None, ) assert cls.namespace == "Foo.Bar" cls = dotnet.DotNetClass( dict(id="Foo.Bar", type="class"), jinja_env=None, app=None ) assert cls.namespace == "Foo" cls = dotnet.DotNetClass(dict(id="Foo", type="class"), jinja_env=None, app=None) assert cls.namespace is None def test_filename(self): """Object file name""" cls = dotnet.DotNetClass({"id": "Foo.Bar.Widget"}, jinja_env=None, app=None) assert cls.pathname == os.path.join("Foo", "Bar", "Widget") cls = dotnet.DotNetClass({"id": "Foo.Bar.Widget"}, jinja_env=None, app=None) assert cls.pathname == os.path.join("Foo", "Bar", "Widget-T") cls = dotnet.DotNetClass( {"id": "Foo.Bar.Widget(TFoo)"}, jinja_env=None, app=None ) assert cls.pathname == os.path.join("Foo", "Bar", "Widget-T") cls = dotnet.DotNetClass( {"id": "Foo.Foo-Bar.Widget(TFoo)"}, jinja_env=None, app=None ) assert cls.pathname == os.path.join("Foo", "FooBar", "Widget-T") cls = dotnet.DotNetClass({"id": u"Foo.Bär"}, jinja_env=None, app=None) assert cls.pathname == os.path.join("Foo", "Bar") cls = dotnet.DotNetClass({"id": u"Ащщ.юИфк"}, jinja_env=None, app=None) assert cls.pathname == os.path.join("Ashchshch", "iuIfk") def test_rendered_class_escaping(self): """Rendered class escaping""" jinja_env = Environment(loader=FileSystemLoader([TEMPLATE_DIR])) cls = dotnet.DotNetClass( {"id": "Foo.Bar`1", "inheritance": ["Foo.Baz`1"]}, jinja_env=jinja_env, app=mock.MagicMock(), ) assert "* :dn:cls:`Foo.Baz\\`1`\n" in cls.render() def test_include_path(self): """Include path""" cls = dotnet.DotNetClass({"id": "Foo.Bar.Widget"}, jinja_env=None, app=None) assert cls.include_path == "/autoapi/Foo/Bar/Widget/index" cls = dotnet.DotNetClass({"id": "Foo.Bar.Widget"}, jinja_env=None, app=None) cls.url_root = "/autofoo" assert cls.include_path == "/autofoo/Foo/Bar/Widget/index" sphinx-autoapi-1.8.4/tests/toctreeexample/000077500000000000000000000000001410652014100206525ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/toctreeexample/conf.py000066400000000000000000000010071410652014100221470ustar00rootroot00000000000000# -*- 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 = ["autoapi.extension"] autoapi_type = "python" autoapi_dirs = ["example"] autoapi_file_pattern = "*.py" sphinx-autoapi-1.8.4/tests/toctreeexample/example/000077500000000000000000000000001410652014100223055ustar00rootroot00000000000000sphinx-autoapi-1.8.4/tests/toctreeexample/example/example.py000066400000000000000000000002151410652014100243100ustar00rootroot00000000000000__author__ = "swenson" import math def example_function(x): """Compute the square root of x and return it.""" return math.sqrt(x) sphinx-autoapi-1.8.4/tests/toctreeexample/index.rst000066400000000000000000000001401410652014100225060ustar00rootroot00000000000000Welcome to pyexample's documentation! ===================================== .. toctree:: sphinx-autoapi-1.8.4/tox.ini000066400000000000000000000011401410652014100157760ustar00rootroot00000000000000[tox] isolated_build = true envlist = # Keep this in sync with .github/workflows/main.yml py{36,37,38,39} formatting lint docs [testenv] extras = dotnet go deps = pytest commands = pytest {posargs} [testenv:formatting] basepython = python3 skip_install = true deps = black commands = black --check --diff autoapi tests [testenv:lint] skip_install = true deps = pylint~=2.4.2 commands = pylint {posargs:autoapi} [testenv:docs] extras = docs changedir = {toxinidir}/docs commands = sphinx-build -b html -d {envtmpdir}/doctrees . {envtmpdir}/html