From 088b04917033f142b9e9830a2dca86f8d3bc95f1 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 13 Aug 2020 23:16:59 +0900 Subject: [PATCH 1/9] Fix #8103: autodoc: cached_property is not considered as a property sphinx.util.inspect:isproperty() does not considers that cached_property decorator that has been added since Python 3.8 is a kind of properties. This fixes it. --- CHANGES | 1 + sphinx/util/inspect.py | 5 +++++ .../target/cached_property.py | 7 +++++++ tests/test_ext_autodoc.py | 20 +++++++++++++++++++ 4 files changed, 33 insertions(+) create mode 100644 tests/roots/test-ext-autodoc/target/cached_property.py diff --git a/CHANGES b/CHANGES index b0b8de1ea..e78905ee6 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ Features added Bugs fixed ---------- +* #8103: autodoc: functools.cached_property is not considered as a property * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index a5c64f882..37997e6b2 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -304,6 +304,11 @@ def iscoroutinefunction(obj: Any) -> bool: def isproperty(obj: Any) -> bool: """Check if the object is property.""" + if sys.version_info > (3, 8): + from functools import cached_property # cached_property is available since py3.8 + if isinstance(obj, cached_property): + return True + return isinstance(obj, property) diff --git a/tests/roots/test-ext-autodoc/target/cached_property.py b/tests/roots/test-ext-autodoc/target/cached_property.py new file mode 100644 index 000000000..63ec09f8e --- /dev/null +++ b/tests/roots/test-ext-autodoc/target/cached_property.py @@ -0,0 +1,7 @@ +from functools import cached_property + + +class Foo: + @cached_property + def prop(self) -> int: + return 1 diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py index 15e1f3539..b7d3bc54e 100644 --- a/tests/test_ext_autodoc.py +++ b/tests/test_ext_autodoc.py @@ -881,6 +881,26 @@ def test_autodoc_descriptor(app): ] +@pytest.mark.skipif(sys.version_info < (3, 8), + reason='cached_property is available since python3.8.') +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_autodoc_cached_property(app): + options = {"members": None, + "undoc-members": True} + actual = do_autodoc(app, 'class', 'target.cached_property.Foo', options) + assert list(actual) == [ + '', + '.. py:class:: Foo()', + ' :module: target.cached_property', + '', + '', + ' .. py:method:: Foo.prop', + ' :module: target.cached_property', + ' :property:', + '', + ] + + @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_member_order(app): # case member-order='bysource' From 1bca9f9587cfdfc82293c4c83679c6e3a03b5c3f Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 14 Aug 2020 00:07:01 +0900 Subject: [PATCH 2/9] Close #8100: html: Show a better error message for html_static_files The HTML Builder crashes if error raised on copying html_static_files. This handles the exception and show a better error message to let users the reason of errors (ex. failed on extracting Jinja templates). --- CHANGES | 3 +++ sphinx/builders/html/__init__.py | 13 +++++++++++-- sphinx/util/fileutil.py | 18 +++++++++++++----- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index b0b8de1ea..119235eac 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,9 @@ Deprecated Features added -------------- +* #8100: html: Show a better error message for failures on copying + html_static_files + Bugs fixed ---------- diff --git a/sphinx/builders/html/__init__.py b/sphinx/builders/html/__init__.py index 923212a99..c30aa9cfd 100644 --- a/sphinx/builders/html/__init__.py +++ b/sphinx/builders/html/__init__.py @@ -751,18 +751,27 @@ class StandaloneHTMLBuilder(Builder): copyfile(jsfile, path.join(self.outdir, '_static', '_stemmer.js')) def copy_theme_static_files(self, context: Dict) -> None: + def onerror(filename: str, error: Exception) -> None: + logger.warning(__('Failed to copy a file in html_static_file: %s: %r'), + filename, error) + if self.theme: for entry in self.theme.get_theme_dirs()[::-1]: copy_asset(path.join(entry, 'static'), path.join(self.outdir, '_static'), - excluded=DOTFILES, context=context, renderer=self.templates) + excluded=DOTFILES, context=context, + renderer=self.templates, onerror=onerror) def copy_html_static_files(self, context: Dict) -> None: + def onerror(filename: str, error: Exception) -> None: + logger.warning(__('Failed to copy a file in html_static_file: %s: %r'), + filename, error) + excluded = Matcher(self.config.exclude_patterns + ["**/.*"]) for entry in self.config.html_static_path: copy_asset(path.join(self.confdir, entry), path.join(self.outdir, '_static'), - excluded, context=context, renderer=self.templates) + excluded, context=context, renderer=self.templates, onerror=onerror) def copy_html_logo(self) -> None: if self.config.html_logo: diff --git a/sphinx/util/fileutil.py b/sphinx/util/fileutil.py index d8e896d48..eec1ae463 100644 --- a/sphinx/util/fileutil.py +++ b/sphinx/util/fileutil.py @@ -10,7 +10,7 @@ import os import posixpath -from typing import Dict +from typing import Callable, Dict from docutils.utils import relative_path @@ -56,7 +56,8 @@ def copy_asset_file(source: str, destination: str, def copy_asset(source: str, destination: str, excluded: PathMatcher = lambda path: False, - context: Dict = None, renderer: "BaseRenderer" = None) -> None: + context: Dict = None, renderer: "BaseRenderer" = None, + onerror: Callable[[str, Exception], None] = None) -> None: """Copy asset files to destination recursively. On copying, it expands the template variables if context argument is given and @@ -67,6 +68,7 @@ def copy_asset(source: str, destination: str, excluded: PathMatcher = lambda pat :param excluded: The matcher to determine the given path should be copied or not :param context: The template variables. If not given, template files are simply copied :param renderer: The template engine. If not given, SphinxRenderer is used by default + :param onerror: The error handler. """ if not os.path.exists(source): return @@ -90,6 +92,12 @@ def copy_asset(source: str, destination: str, excluded: PathMatcher = lambda pat for filename in files: if not excluded(posixpath.join(reldir, filename)): - copy_asset_file(posixpath.join(root, filename), - posixpath.join(destination, reldir), - context, renderer) + try: + copy_asset_file(posixpath.join(root, filename), + posixpath.join(destination, reldir), + context, renderer) + except Exception as exc: + if onerror: + onerror(posixpath.join(root, filename), exc) + else: + raise From 4313060c8a7fe0aa60bdf1d370453fbd350de9fd Mon Sep 17 00:00:00 2001 From: Gaurav Lalchandani Date: Sat, 22 Aug 2020 20:00:41 +0530 Subject: [PATCH 3/9] Fixes #8146: When identifying bases, only use classes from builtins In inheritance_diagram extension, while iterating over bases, we verify if the base class is one of the Python built-in class or not. As of now, we simply check for its presence in all `builtins` objects. Please note, `builtins` not only has built-in classes, but also functions (like `open`) and other built-in objects. To avoid any sort of future problem, it seems better to only use classes (and of course exception classes). --- sphinx/ext/inheritance_diagram.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py index 7b2383fca..71a123b15 100644 --- a/sphinx/ext/inheritance_diagram.py +++ b/sphinx/ext/inheritance_diagram.py @@ -66,6 +66,10 @@ module_sig_re = re.compile(r'''^(?:([\w.]*)\.)? # module names ''', re.VERBOSE) +py_builtins = [obj for obj in vars(builtins).values() + if inspect.isclass(obj)] + + def try_import(objname: str) -> Any: """Import a object or module using *name* and *currentmodule*. *name* should be a relative name from *currentmodule* or @@ -178,7 +182,6 @@ class InheritanceGraph: traverse to. Multiple names can be specified separated by comma. """ all_classes = {} - py_builtins = vars(builtins).values() def recurse(cls: Any) -> None: if not show_builtins and cls in py_builtins: From fd3d654c17874d4cbffbd8e9379728f83a31b30b Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sat, 12 Sep 2020 16:04:41 +0900 Subject: [PATCH 4/9] Fix #8190: autodoc: parse error for docstring w/o ending blank lines autodoc raises a parsing error if some extension generates a docstring not having blank lines at the tail. This appends a blank line if generated one does not contain it. --- CHANGES | 2 ++ sphinx/ext/autodoc/__init__.py | 5 +++++ tests/test_ext_autodoc_events.py | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index fde891098..c8de2d7e6 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,8 @@ Bugs fixed * #8085: i18n: Add support for having single text domain * #8143: autodoc: AttributeError is raised when False value is passed to autodoc_default_options +* #8190: autodoc: parsing error is raised if some extension replaces docstring + by string not ending with blank lines * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index ed02c2c90..23fb43a4d 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -535,6 +535,11 @@ class Documenter: self.env.app.emit('autodoc-process-docstring', self.objtype, self.fullname, self.object, self.options, docstringlines) + + if docstringlines and docstringlines[-1] != '': + # append a blank line to the end of the docstring + docstringlines.append('') + yield from docstringlines def get_sourcename(self) -> str: diff --git a/tests/test_ext_autodoc_events.py b/tests/test_ext_autodoc_events.py index 4e8348abc..7ddc952ab 100644 --- a/tests/test_ext_autodoc_events.py +++ b/tests/test_ext_autodoc_events.py @@ -28,7 +28,8 @@ def test_process_docstring(app): '.. py:function:: func()', ' :module: target.process_docstring', '', - ' my docstring' + ' my docstring', + '', ] From 564a577a4a27e24efe02e9ff1cb9013dc472ed80 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 13 Sep 2020 11:10:33 +0900 Subject: [PATCH 5/9] Fix #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex --- CHANGES | 1 + sphinx/builders/latex/__init__.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 89980530f..abf169928 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,7 @@ Bugs fixed * #8143: autodoc: AttributeError is raised when False value is passed to autodoc_default_options * #8192: napoleon: description is disappeared when it contains inline literals +* #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex * #8093: The highlight warning has wrong location in some builders (LaTeX, singlehtml and so on) diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index 88c471675..ffb17d2eb 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -505,7 +505,7 @@ def validate_latex_theme_options(app: Sphinx, config: Config) -> None: def install_pakcages_for_ja(app: Sphinx) -> None: """Install packages for Japanese.""" - if app.config.language == 'ja': + if app.config.language == 'ja' and app.config.latex_engine in ('platex', 'uplatex'): app.add_latex_package('pxjahyper', after_hyperref=True) From 500f45fd4c34559cdbf9f28eae3e159fc5b7f2d8 Mon Sep 17 00:00:00 2001 From: Jakob Lykke Andersen Date: Sun, 13 Sep 2020 16:25:09 +0200 Subject: [PATCH 6/9] C, recursive alias declarations Fixes sphinx-doc/sphinx#8141 --- CHANGES | 2 + doc/usage/restructuredtext/domains.rst | 12 +++++ sphinx/domains/c.py | 70 +++++++++++++++++++------- 3 files changed, 65 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index dca1b4a2e..8a5da7a19 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,8 @@ Features added * #8100: html: Show a better error message for failures on copying html_static_files +* #8141: C: added a ``maxdepth`` option to :rst:dir:`c:alias` to insert + nested declarations. Bugs fixed ---------- diff --git a/doc/usage/restructuredtext/domains.rst b/doc/usage/restructuredtext/domains.rst index 311b03d66..f3754ab7c 100644 --- a/doc/usage/restructuredtext/domains.rst +++ b/doc/usage/restructuredtext/domains.rst @@ -744,6 +744,18 @@ The following directive can be used for this purpose. .. versionadded:: 3.2 + + .. rubric:: Options + + .. rst:directive:option:: maxdepth: int + + Insert nested declarations as well, up to the total depth given. + Use 0 for infinite depth and 1 for just the mentioned declaration. + Defaults to 1. + + .. versionadded:: 3.3 + + .. c:namespace-pop:: diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index c759dacbd..304c871ea 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -136,8 +136,8 @@ class ASTIdentifier(ASTBaseBase): reftype='identifier', reftarget=targetText, modname=None, classname=None) - # key = symbol.get_lookup_key() - # pnode['c:parent_key'] = key + key = symbol.get_lookup_key() + pnode['c:parent_key'] = key if self.is_anon(): pnode += nodes.strong(text="[anonymous]") else: @@ -1562,6 +1562,11 @@ class Symbol: for s in sChild.get_all_symbols(): yield s + @property + def children(self) -> Iterator["Symbol"]: + for c in self._children: + yield c + @property def children_recurse_anon(self) -> Iterator["Symbol"]: for c in self._children: @@ -3408,10 +3413,13 @@ class CNamespacePopObject(SphinxDirective): class AliasNode(nodes.Element): - def __init__(self, sig: str, env: "BuildEnvironment" = None, + def __init__(self, sig: str, maxdepth: int, document: Any, env: "BuildEnvironment" = None, parentKey: LookupKey = None) -> None: super().__init__() self.sig = sig + self.maxdepth = maxdepth + assert maxdepth >= 0 + self.document = document if env is not None: if 'c:parent_symbol' not in env.temp_data: root = env.domaindata['c']['root_symbol'] @@ -3428,6 +3436,37 @@ class AliasNode(nodes.Element): class AliasTransform(SphinxTransform): default_priority = ReferencesResolver.default_priority - 1 + def _render_symbol(self, s: Symbol, maxdepth: int, document: Any) -> List[Node]: + nodes = [] # type: List[Node] + options = dict() # type: ignore + signode = addnodes.desc_signature('', '') + nodes.append(signode) + s.declaration.describe_signature(signode, 'markName', self.env, options) + if maxdepth == 0: + recurse = True + elif maxdepth == 1: + recurse = False + else: + maxdepth -= 1 + recurse = True + if recurse: + content = addnodes.desc_content() + desc = addnodes.desc() + content.append(desc) + desc.document = document + desc['domain'] = 'c' + # 'desctype' is a backwards compatible attribute + desc['objtype'] = desc['desctype'] = 'alias' + desc['noindex'] = True + + for sChild in s.children: + childNodes = self._render_symbol(sChild, maxdepth, document) + desc.extend(childNodes) + + if len(desc.children) != 0: + nodes.append(content) + return nodes + def apply(self, **kwargs: Any) -> None: for node in self.document.traverse(AliasNode): sig = node.sig @@ -3468,17 +3507,16 @@ class AliasTransform(SphinxTransform): logger.warning("Could not find C declaration for alias '%s'." % name, location=node) node.replace_self(signode) - else: - nodes = [] - options = dict() # type: ignore - signode = addnodes.desc_signature(sig, '') - nodes.append(signode) - s.declaration.describe_signature(signode, 'markName', self.env, options) - node.replace_self(nodes) + continue + + nodes = self._render_symbol(s, maxdepth=node.maxdepth, document=node.document) + node.replace_self(nodes) class CAliasObject(ObjectDescription): - option_spec = {} # type: Dict + option_spec = { + 'maxdepth': directives.nonnegative_int + } # type: Dict def run(self) -> List[Node]: if ':' in self.name: @@ -3494,16 +3532,10 @@ class CAliasObject(ObjectDescription): node['noindex'] = True self.names = [] # type: List[str] + maxdepth = self.options.get('maxdepth', 1) signatures = self.get_signatures() for i, sig in enumerate(signatures): - node.append(AliasNode(sig, env=self.env)) - - contentnode = addnodes.desc_content() - node.append(contentnode) - self.before_content() - self.state.nested_parse(self.content, self.content_offset, contentnode) - self.env.temp_data['object'] = None - self.after_content() + node.append(AliasNode(sig, maxdepth, self.state.document, env=self.env)) return [node] From 5ef4825b57c8fd84488e38f7f5cf78ccf3d72698 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Mon, 10 Aug 2020 02:23:52 +0900 Subject: [PATCH 7/9] Close #8081: latex: Allow to add LaTeX package until writing tex file This postpones the evaluation of LaTeX packages via ``app.add_latex_package()`` to just before writing .tex file. That allows extensions to add LaTeX packages during reading and resolving phase. --- CHANGES | 5 +++++ doc/extdev/deprecated.rst | 10 ++++++++++ sphinx/builders/latex/__init__.py | 28 +++++++++++++++++++++------- sphinx/testing/util.py | 2 -- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index 738baf341..b459af41e 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,9 @@ Incompatible changes Deprecated ---------- +* ``sphinx.builders.latex.LaTeXBuilder.usepackages`` +* ``sphinx.builders.latex.LaTeXBuilder.usepackages_afger_hyperref`` + Features added -------------- @@ -17,6 +20,8 @@ Features added html_static_files * #8141: C: added a ``maxdepth`` option to :rst:dir:`c:alias` to insert nested declarations. +* #8081: LaTeX: Allow to add LaTeX package via ``app.add_latex_package()`` until + just before writing .tex file Bugs fixed ---------- diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst index 829bfc32b..d7ad21fff 100644 --- a/doc/extdev/deprecated.rst +++ b/doc/extdev/deprecated.rst @@ -26,6 +26,16 @@ The following is a list of deprecated interfaces. - (will be) Removed - Alternatives + * - ``sphinx.builders.latex.LaTeXBuilder.usepackages`` + - 3.3 + - 5.0 + - N/A + + * - ``sphinx.builders.latex.LaTeXBuilder.usepackages_afger_hyperref`` + - 3.3 + - 5.0 + - N/A + * - ``sphinx.ext.autodoc.members_set_option()`` - 3.2 - 5.0 diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index ffb17d2eb..b58a44adf 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -24,7 +24,7 @@ from sphinx.builders.latex.constants import ADDITIONAL_SETTINGS, DEFAULT_SETTING from sphinx.builders.latex.theming import Theme, ThemeFactory from sphinx.builders.latex.util import ExtBabel from sphinx.config import Config, ENUM -from sphinx.deprecation import RemovedInSphinx40Warning +from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning from sphinx.environment.adapters.asset import ImageAdapter from sphinx.errors import NoUri, SphinxError from sphinx.locale import _, __ @@ -128,8 +128,6 @@ class LaTeXBuilder(Builder): self.docnames = [] # type: Iterable[str] self.document_data = [] # type: List[Tuple[str, str, str, str, str, bool]] self.themes = ThemeFactory(self.app) - self.usepackages = self.app.registry.latex_packages - self.usepackages_after_hyperref = self.app.registry.latex_packages_after_hyperref texescape.init() self.init_context() @@ -179,10 +177,6 @@ class LaTeXBuilder(Builder): key = (self.config.latex_engine, self.config.language[:2]) self.context.update(ADDITIONAL_SETTINGS.get(key, {})) - # Apply extension settings to context - self.context['packages'] = self.usepackages - self.context['packages_after_hyperref'] = self.usepackages_after_hyperref - # Apply user settings to context self.context.update(self.config.latex_elements) self.context['release'] = self.config.release @@ -203,6 +197,13 @@ class LaTeXBuilder(Builder): # Show the release label only if release value exists self.context.setdefault('releasename', _('Release')) + def update_context(self) -> None: + """Update template variables for .tex file just before writing.""" + # Apply extension settings to context + registry = self.app.registry + self.context['packages'] = registry.latex_packages + self.context['packages_after_hyperref'] = registry.latex_packages_after_hyperref + def init_babel(self) -> None: self.babel = ExtBabel(self.config.language, not self.context['babel']) if self.config.language and not self.babel.is_supported_language(): @@ -290,6 +291,7 @@ class LaTeXBuilder(Builder): doctree['tocdepth'] = tocdepth self.post_process_images(doctree) self.update_doc_context(title, author, theme) + self.update_context() with progress_message(__("writing")): docsettings._author = author @@ -448,6 +450,18 @@ class LaTeXBuilder(Builder): filename = path.join(package_dir, 'templates', 'latex', 'sphinxmessages.sty_t') copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer()) + @property + def usepackages(self) -> List[Tuple[str, str]]: + warnings.warn('LaTeXBuilder.usepackages is deprecated.', + RemovedInSphinx50Warning, stacklevel=2) + return self.app.registry.latex_packages + + @property + def usepackages_after_hyperref(self) -> List[Tuple[str, str]]: + warnings.warn('LaTeXBuilder.usepackages_after_hyperref is deprecated.', + RemovedInSphinx50Warning, stacklevel=2) + return self.app.registry.latex_packages_after_hyperref + def patch_settings(settings: Any) -> Any: """Make settings object to show deprecation messages.""" diff --git a/sphinx/testing/util.py b/sphinx/testing/util.py index 5ac334068..80ca84cb3 100644 --- a/sphinx/testing/util.py +++ b/sphinx/testing/util.py @@ -21,7 +21,6 @@ from docutils.nodes import Node from docutils.parsers.rst import directives, roles from sphinx import application, locale -from sphinx.builders.latex import LaTeXBuilder from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.pycode import ModuleAnalyzer from sphinx.testing.path import path @@ -141,7 +140,6 @@ class SphinxTestApp(application.Sphinx): def cleanup(self, doctrees: bool = False) -> None: ModuleAnalyzer.cache.clear() - LaTeXBuilder.usepackages = [] locale.translators.clear() sys.path[:] = self._saved_path sys.modules.pop('autodoc_fodder', None) From a0116eaa582810e56a4661a22a574baf6bff33f1 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Sun, 20 Sep 2020 17:36:01 -0500 Subject: [PATCH 8/9] Fix typo: anchestor -> ancestor. --- doc/usage/extensions/autodoc.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/usage/extensions/autodoc.rst b/doc/usage/extensions/autodoc.rst index 71f49c240..802be3bd0 100644 --- a/doc/usage/extensions/autodoc.rst +++ b/doc/usage/extensions/autodoc.rst @@ -229,7 +229,7 @@ inserting them into the page source under a suitable :rst:dir:`py:module`, .. versionchanged:: 3.0 - It takes an anchestor class name as an argument. + It takes an ancestor class name as an argument. * It's possible to override the signature for explicitly documented callable objects (functions, methods, classes) with the regular syntax that will From 189406f65b19330b31f124e77a6d501a8611ed3f Mon Sep 17 00:00:00 2001 From: Nathan Shammah Date: Wed, 23 Sep 2020 19:53:47 +0200 Subject: [PATCH 9/9] add mitiq to examples --- EXAMPLES | 1 + 1 file changed, 1 insertion(+) diff --git a/EXAMPLES b/EXAMPLES index b87d8e73e..19f23172f 100644 --- a/EXAMPLES +++ b/EXAMPLES @@ -330,6 +330,7 @@ Documentation using a custom theme or integrated in a website * `Lasso `__ * `Mako `__ * `MirrorBrain `__ +* `Mitiq `__ * `MongoDB `__ * `Music21 `__ * `MyHDL `__