mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch '3.x' into 7901_resolve_types_for_overloaded_funcs
This commit is contained in:
8
CHANGES
8
CHANGES
@@ -13,10 +13,14 @@ Deprecated
|
|||||||
Features added
|
Features added
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
* #7849: html: Add :confval:`html_codeblock_linenos_style` to change the style
|
||||||
|
of line numbers for code-blocks
|
||||||
* #7853: C and C++, support parameterized GNU style attributes.
|
* #7853: C and C++, support parameterized GNU style attributes.
|
||||||
* #7888: napoleon: Add aliases Warn and Raise.
|
* #7888: napoleon: Add aliases Warn and Raise.
|
||||||
* C, added :rst:dir:`c:alias` directive for inserting copies
|
* C, added :rst:dir:`c:alias` directive for inserting copies
|
||||||
of existing declarations.
|
of existing declarations.
|
||||||
|
* #7902: html theme: Add a new option :confval:`globaltoc_maxdepth` to control
|
||||||
|
the behavior of globaltoc in sidebar
|
||||||
* #7052: add ``:noindexentry:`` to the Python, C, C++, and Javascript domains.
|
* #7052: add ``:noindexentry:`` to the Python, C, C++, and Javascript domains.
|
||||||
Update the documentation to better reflect the relationship between this option
|
Update the documentation to better reflect the relationship between this option
|
||||||
and the ``:noindex:`` option.
|
and the ``:noindex:`` option.
|
||||||
@@ -25,6 +29,8 @@ Bugs fixed
|
|||||||
----------
|
----------
|
||||||
|
|
||||||
* #7886: autodoc: TypeError is raised on mocking generic-typed classes
|
* #7886: autodoc: TypeError is raised on mocking generic-typed classes
|
||||||
|
* #7935: autodoc: function signature is not shown when the function has a
|
||||||
|
parameter having ``inspect._empty`` as its default value
|
||||||
* #7901: autodoc: type annotations for overloaded functions are not resolved
|
* #7901: autodoc: type annotations for overloaded functions are not resolved
|
||||||
* #7839: autosummary: cannot handle umlauts in function names
|
* #7839: autosummary: cannot handle umlauts in function names
|
||||||
* #7865: autosummary: Failed to extract summary line when abbreviations found
|
* #7865: autosummary: Failed to extract summary line when abbreviations found
|
||||||
@@ -34,6 +40,8 @@ Bugs fixed
|
|||||||
* #7715: LaTeX: ``numfig_secnum_depth > 1`` leads to wrong figure links
|
* #7715: LaTeX: ``numfig_secnum_depth > 1`` leads to wrong figure links
|
||||||
* #7846: html theme: XML-invalid files were generated
|
* #7846: html theme: XML-invalid files were generated
|
||||||
* #7894: gettext: Wrong source info is shown when using rst_epilog
|
* #7894: gettext: Wrong source info is shown when using rst_epilog
|
||||||
|
* #7691: linkcheck: HEAD requests are not used for checking
|
||||||
|
* #7928: py domain: failed to resolve a type annotation for the attribute
|
||||||
* #7869: :rst:role:`abbr` role without an explanation will show the explanation
|
* #7869: :rst:role:`abbr` role without an explanation will show the explanation
|
||||||
from the previous abbr role
|
from the previous abbr role
|
||||||
* C and C++, removed ``noindex`` directive option as it did
|
* C and C++, removed ``noindex`` directive option as it did
|
||||||
|
|||||||
@@ -926,6 +926,15 @@ that use Sphinx's HTMLWriter class.
|
|||||||
|
|
||||||
.. versionadded:: 1.8
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
|
.. confval:: html_codeblock_linenos_style
|
||||||
|
|
||||||
|
The style of line numbers for code-blocks.
|
||||||
|
|
||||||
|
* ``'table'`` -- display line numbers using ``<table>`` tag (default)
|
||||||
|
* ``'inline'`` -- display line numbers using ``<span>`` tag
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
.. confval:: html_context
|
.. confval:: html_context
|
||||||
|
|
||||||
A dictionary of values to pass into the template engine's context for all
|
A dictionary of values to pass into the template engine's context for all
|
||||||
|
|||||||
@@ -172,6 +172,12 @@ These themes are:
|
|||||||
|
|
||||||
.. versionadded:: 3.1
|
.. versionadded:: 3.1
|
||||||
|
|
||||||
|
- **globaltoc_maxdepth** (int): The maximum depth of the toctree in
|
||||||
|
``globaltoc.html`` (see :confval:`html_sidebars`). Set it to -1 to allow
|
||||||
|
unlimited depth. Defaults to the max depth selected in the toctree directive.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
**alabaster**
|
**alabaster**
|
||||||
`Alabaster theme`_ is a modified "Kr" Sphinx theme from @kennethreitz
|
`Alabaster theme`_ is a modified "Kr" Sphinx theme from @kennethreitz
|
||||||
(especially as used in his Requests project), which was itself originally
|
(especially as used in his Requests project), which was itself originally
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ from docutils.utils import relative_path
|
|||||||
from sphinx import package_dir, __display_version__
|
from sphinx import package_dir, __display_version__
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.config import Config
|
from sphinx.config import Config, ENUM
|
||||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||||
from sphinx.domains import Domain, Index, IndexEntry
|
from sphinx.domains import Domain, Index, IndexEntry
|
||||||
from sphinx.environment.adapters.asset import ImageAdapter
|
from sphinx.environment.adapters.asset import ImageAdapter
|
||||||
@@ -886,6 +886,8 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwargs: Any) -> str:
|
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwargs: Any) -> str:
|
||||||
if 'includehidden' not in kwargs:
|
if 'includehidden' not in kwargs:
|
||||||
kwargs['includehidden'] = False
|
kwargs['includehidden'] = False
|
||||||
|
if kwargs.get('maxdepth') == '':
|
||||||
|
kwargs.pop('maxdepth')
|
||||||
return self.render_partial(TocTree(self.env).get_toctree_for(
|
return self.render_partial(TocTree(self.env).get_toctree_for(
|
||||||
docname, self, collapse, **kwargs))['fragment']
|
docname, self, collapse, **kwargs))['fragment']
|
||||||
|
|
||||||
@@ -1226,6 +1228,8 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_config_value('html_search_scorer', '', None)
|
app.add_config_value('html_search_scorer', '', None)
|
||||||
app.add_config_value('html_scaled_image_link', True, 'html')
|
app.add_config_value('html_scaled_image_link', True, 'html')
|
||||||
app.add_config_value('html_baseurl', '', 'html')
|
app.add_config_value('html_baseurl', '', 'html')
|
||||||
|
app.add_config_value('html_codeblock_linenos_style', 'table', 'html',
|
||||||
|
ENUM('table', 'inline'))
|
||||||
app.add_config_value('html_math_renderer', None, 'env')
|
app.add_config_value('html_math_renderer', None, 'env')
|
||||||
app.add_config_value('html4_writer', False, 'html')
|
app.add_config_value('html4_writer', False, 'html')
|
||||||
|
|
||||||
|
|||||||
@@ -77,18 +77,24 @@ ModuleEntry = NamedTuple('ModuleEntry', [('docname', str),
|
|||||||
('deprecated', bool)])
|
('deprecated', bool)])
|
||||||
|
|
||||||
|
|
||||||
def type_to_xref(text: str) -> addnodes.pending_xref:
|
def type_to_xref(text: str, env: BuildEnvironment = None) -> addnodes.pending_xref:
|
||||||
"""Convert a type string to a cross reference node."""
|
"""Convert a type string to a cross reference node."""
|
||||||
if text == 'None':
|
if text == 'None':
|
||||||
reftype = 'obj'
|
reftype = 'obj'
|
||||||
else:
|
else:
|
||||||
reftype = 'class'
|
reftype = 'class'
|
||||||
|
|
||||||
|
if env:
|
||||||
|
kwargs = {'py:module': env.ref_context.get('py:module'),
|
||||||
|
'py:class': env.ref_context.get('py:class')}
|
||||||
|
else:
|
||||||
|
kwargs = {}
|
||||||
|
|
||||||
return pending_xref('', nodes.Text(text),
|
return pending_xref('', nodes.Text(text),
|
||||||
refdomain='py', reftype=reftype, reftarget=text)
|
refdomain='py', reftype=reftype, reftarget=text, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def _parse_annotation(annotation: str) -> List[Node]:
|
def _parse_annotation(annotation: str, env: BuildEnvironment = None) -> List[Node]:
|
||||||
"""Parse type annotation."""
|
"""Parse type annotation."""
|
||||||
def unparse(node: ast.AST) -> List[Node]:
|
def unparse(node: ast.AST) -> List[Node]:
|
||||||
if isinstance(node, ast.Attribute):
|
if isinstance(node, ast.Attribute):
|
||||||
@@ -130,18 +136,22 @@ def _parse_annotation(annotation: str) -> List[Node]:
|
|||||||
else:
|
else:
|
||||||
raise SyntaxError # unsupported syntax
|
raise SyntaxError # unsupported syntax
|
||||||
|
|
||||||
|
if env is None:
|
||||||
|
warnings.warn("The env parameter for _parse_annotation becomes required now.",
|
||||||
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tree = ast_parse(annotation)
|
tree = ast_parse(annotation)
|
||||||
result = unparse(tree)
|
result = unparse(tree)
|
||||||
for i, node in enumerate(result):
|
for i, node in enumerate(result):
|
||||||
if isinstance(node, nodes.Text):
|
if isinstance(node, nodes.Text):
|
||||||
result[i] = type_to_xref(str(node))
|
result[i] = type_to_xref(str(node), env)
|
||||||
return result
|
return result
|
||||||
except SyntaxError:
|
except SyntaxError:
|
||||||
return [type_to_xref(annotation)]
|
return [type_to_xref(annotation, env)]
|
||||||
|
|
||||||
|
|
||||||
def _parse_arglist(arglist: str) -> addnodes.desc_parameterlist:
|
def _parse_arglist(arglist: str, env: BuildEnvironment = None) -> addnodes.desc_parameterlist:
|
||||||
"""Parse a list of arguments using AST parser"""
|
"""Parse a list of arguments using AST parser"""
|
||||||
params = addnodes.desc_parameterlist(arglist)
|
params = addnodes.desc_parameterlist(arglist)
|
||||||
sig = signature_from_str('(%s)' % arglist)
|
sig = signature_from_str('(%s)' % arglist)
|
||||||
@@ -167,7 +177,7 @@ def _parse_arglist(arglist: str) -> addnodes.desc_parameterlist:
|
|||||||
node += addnodes.desc_sig_name('', param.name)
|
node += addnodes.desc_sig_name('', param.name)
|
||||||
|
|
||||||
if param.annotation is not param.empty:
|
if param.annotation is not param.empty:
|
||||||
children = _parse_annotation(param.annotation)
|
children = _parse_annotation(param.annotation, env)
|
||||||
node += addnodes.desc_sig_punctuation('', ':')
|
node += addnodes.desc_sig_punctuation('', ':')
|
||||||
node += nodes.Text(' ')
|
node += nodes.Text(' ')
|
||||||
node += addnodes.desc_sig_name('', '', *children) # type: ignore
|
node += addnodes.desc_sig_name('', '', *children) # type: ignore
|
||||||
@@ -415,7 +425,7 @@ class PyObject(ObjectDescription):
|
|||||||
signode += addnodes.desc_name(name, name)
|
signode += addnodes.desc_name(name, name)
|
||||||
if arglist:
|
if arglist:
|
||||||
try:
|
try:
|
||||||
signode += _parse_arglist(arglist)
|
signode += _parse_arglist(arglist, self.env)
|
||||||
except SyntaxError:
|
except SyntaxError:
|
||||||
# fallback to parse arglist original parser.
|
# fallback to parse arglist original parser.
|
||||||
# it supports to represent optional arguments (ex. "func(foo [, bar])")
|
# it supports to represent optional arguments (ex. "func(foo [, bar])")
|
||||||
@@ -430,7 +440,7 @@ class PyObject(ObjectDescription):
|
|||||||
signode += addnodes.desc_parameterlist()
|
signode += addnodes.desc_parameterlist()
|
||||||
|
|
||||||
if retann:
|
if retann:
|
||||||
children = _parse_annotation(retann)
|
children = _parse_annotation(retann, self.env)
|
||||||
signode += addnodes.desc_returns(retann, '', *children)
|
signode += addnodes.desc_returns(retann, '', *children)
|
||||||
|
|
||||||
anno = self.options.get('annotation')
|
anno = self.options.get('annotation')
|
||||||
@@ -626,7 +636,7 @@ class PyVariable(PyObject):
|
|||||||
|
|
||||||
typ = self.options.get('type')
|
typ = self.options.get('type')
|
||||||
if typ:
|
if typ:
|
||||||
annotations = _parse_annotation(typ)
|
annotations = _parse_annotation(typ, self.env)
|
||||||
signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), *annotations)
|
signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), *annotations)
|
||||||
|
|
||||||
value = self.options.get('value')
|
value = self.options.get('value')
|
||||||
@@ -872,7 +882,7 @@ class PyAttribute(PyObject):
|
|||||||
|
|
||||||
typ = self.options.get('type')
|
typ = self.options.get('type')
|
||||||
if typ:
|
if typ:
|
||||||
annotations = _parse_annotation(typ)
|
annotations = _parse_annotation(typ, self.env)
|
||||||
signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), *annotations)
|
signode += addnodes.desc_annotation(typ, '', nodes.Text(': '), *annotations)
|
||||||
|
|
||||||
value = self.options.get('value')
|
value = self.options.get('value')
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ class EventManager:
|
|||||||
raise
|
raise
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise ExtensionError(__("Handler %r for event %r threw an exception") %
|
raise ExtensionError(__("Handler %r for event %r threw an exception") %
|
||||||
(listener.handler, name)) from exc
|
(listener.handler, name), exc) from exc
|
||||||
return results
|
return results
|
||||||
|
|
||||||
def emit_firstresult(self, name: str, *args: Any,
|
def emit_firstresult(self, name: str, *args: Any,
|
||||||
|
|||||||
@@ -8,4 +8,4 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
#}
|
#}
|
||||||
<h3><a href="{{ pathto(master_doc)|e }}">{{ _('Table of Contents') }}</a></h3>
|
<h3><a href="{{ pathto(master_doc)|e }}">{{ _('Table of Contents') }}</a></h3>
|
||||||
{{ toctree(includehidden=theme_globaltoc_includehidden, collapse=theme_globaltoc_collapse) }}
|
{{ toctree(includehidden=theme_globaltoc_includehidden, collapse=theme_globaltoc_collapse, maxdepth=theme_globaltoc_maxdepth) }}
|
||||||
|
|||||||
@@ -12,3 +12,4 @@ body_max_width = 800
|
|||||||
navigation_with_keys = False
|
navigation_with_keys = False
|
||||||
globaltoc_collapse = true
|
globaltoc_collapse = true
|
||||||
globaltoc_includehidden = false
|
globaltoc_includehidden = false
|
||||||
|
globaltoc_maxdepth =
|
||||||
|
|||||||
@@ -485,7 +485,13 @@ def signature(subject: Callable, bound_method: bool = False, follow_wrapped: boo
|
|||||||
if len(parameters) > 0:
|
if len(parameters) > 0:
|
||||||
parameters.pop(0)
|
parameters.pop(0)
|
||||||
|
|
||||||
return inspect.Signature(parameters, return_annotation=return_annotation)
|
# To allow to create signature object correctly for pure python functions,
|
||||||
|
# pass an internal parameter __validate_parameters__=False to Signature
|
||||||
|
#
|
||||||
|
# For example, this helps a function having a default value `inspect._empty`.
|
||||||
|
# refs: https://github.com/sphinx-doc/sphinx/issues/7935
|
||||||
|
return inspect.Signature(parameters, return_annotation=return_annotation, # type: ignore
|
||||||
|
__validate_parameters__=False)
|
||||||
|
|
||||||
|
|
||||||
def evaluate_signature(sig: inspect.Signature, globalns: Dict = None, localns: Dict = None
|
def evaluate_signature(sig: inspect.Signature, globalns: Dict = None, localns: Dict = None
|
||||||
|
|||||||
@@ -124,4 +124,4 @@ def head(url: str, **kwargs: Any) -> requests.Response:
|
|||||||
headers.setdefault('User-Agent', useragent_header[0][1])
|
headers.setdefault('User-Agent', useragent_header[0][1])
|
||||||
|
|
||||||
with ignore_insecure_warning(**kwargs):
|
with ignore_insecure_warning(**kwargs):
|
||||||
return requests.get(url, **kwargs)
|
return requests.head(url, **kwargs)
|
||||||
|
|||||||
@@ -445,6 +445,9 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator):
|
|||||||
else:
|
else:
|
||||||
opts = {}
|
opts = {}
|
||||||
|
|
||||||
|
if linenos and self.builder.config.html_codeblock_linenos_style:
|
||||||
|
linenos = self.builder.config.html_codeblock_linenos_style
|
||||||
|
|
||||||
highlighted = self.highlighter.highlight_block(
|
highlighted = self.highlighter.highlight_block(
|
||||||
node.rawsource, lang, opts=opts, linenos=linenos,
|
node.rawsource, lang, opts=opts, linenos=linenos,
|
||||||
location=(self.builder.current_docname, node.line), **highlight_args
|
location=(self.builder.current_docname, node.line), **highlight_args
|
||||||
|
|||||||
@@ -397,6 +397,9 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|||||||
else:
|
else:
|
||||||
opts = {}
|
opts = {}
|
||||||
|
|
||||||
|
if linenos and self.builder.config.html_codeblock_linenos_style:
|
||||||
|
linenos = self.builder.config.html_codeblock_linenos_style
|
||||||
|
|
||||||
highlighted = self.highlighter.highlight_block(
|
highlighted = self.highlighter.highlight_block(
|
||||||
node.rawsource, lang, opts=opts, linenos=linenos,
|
node.rawsource, lang, opts=opts, linenos=linenos,
|
||||||
location=(self.builder.current_docname, node.line), **highlight_args
|
location=(self.builder.current_docname, node.line), **highlight_args
|
||||||
|
|||||||
7
tests/roots/test-reST-code-block/index.rst
Normal file
7
tests/roots/test-reST-code-block/index.rst
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
.. code-block::
|
||||||
|
:linenos:
|
||||||
|
|
||||||
|
def hello(name)
|
||||||
|
print("hello", name)
|
||||||
|
|
||||||
|
hello("Sphinx")
|
||||||
@@ -1575,3 +1575,21 @@ def test_html_scaled_image_link(app):
|
|||||||
assert re.search('\n<img alt="_images/img.png" class="no-scaled-link"'
|
assert re.search('\n<img alt="_images/img.png" class="no-scaled-link"'
|
||||||
' src="_images/img.png" style="[^"]+" />',
|
' src="_images/img.png" style="[^"]+" />',
|
||||||
context)
|
context)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('html', testroot='reST-code-block',
|
||||||
|
confoverrides={'html_codeblock_linenos_style': 'table'})
|
||||||
|
def test_html_codeblock_linenos_style_table(app):
|
||||||
|
app.build()
|
||||||
|
content = (app.outdir / 'index.html').read_text()
|
||||||
|
|
||||||
|
assert '<div class="linenodiv"><pre>1\n2\n3\n4</pre></div>' in content
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('html', testroot='reST-code-block',
|
||||||
|
confoverrides={'html_codeblock_linenos_style': 'inline'})
|
||||||
|
def test_html_codeblock_linenos_style_inline(app):
|
||||||
|
app.build()
|
||||||
|
content = (app.outdir / 'index.html').read_text()
|
||||||
|
|
||||||
|
assert '<span class="lineno">1 </span>' in content
|
||||||
|
|||||||
@@ -236,18 +236,18 @@ def test_get_full_qualified_name():
|
|||||||
assert domain.get_full_qualified_name(node) == 'module1.Class.func'
|
assert domain.get_full_qualified_name(node) == 'module1.Class.func'
|
||||||
|
|
||||||
|
|
||||||
def test_parse_annotation():
|
def test_parse_annotation(app):
|
||||||
doctree = _parse_annotation("int")
|
doctree = _parse_annotation("int", app.env)
|
||||||
assert_node(doctree, ([pending_xref, "int"],))
|
assert_node(doctree, ([pending_xref, "int"],))
|
||||||
assert_node(doctree[0], pending_xref, refdomain="py", reftype="class", reftarget="int")
|
assert_node(doctree[0], pending_xref, refdomain="py", reftype="class", reftarget="int")
|
||||||
|
|
||||||
doctree = _parse_annotation("List[int]")
|
doctree = _parse_annotation("List[int]", app.env)
|
||||||
assert_node(doctree, ([pending_xref, "List"],
|
assert_node(doctree, ([pending_xref, "List"],
|
||||||
[desc_sig_punctuation, "["],
|
[desc_sig_punctuation, "["],
|
||||||
[pending_xref, "int"],
|
[pending_xref, "int"],
|
||||||
[desc_sig_punctuation, "]"]))
|
[desc_sig_punctuation, "]"]))
|
||||||
|
|
||||||
doctree = _parse_annotation("Tuple[int, int]")
|
doctree = _parse_annotation("Tuple[int, int]", app.env)
|
||||||
assert_node(doctree, ([pending_xref, "Tuple"],
|
assert_node(doctree, ([pending_xref, "Tuple"],
|
||||||
[desc_sig_punctuation, "["],
|
[desc_sig_punctuation, "["],
|
||||||
[pending_xref, "int"],
|
[pending_xref, "int"],
|
||||||
@@ -255,14 +255,14 @@ def test_parse_annotation():
|
|||||||
[pending_xref, "int"],
|
[pending_xref, "int"],
|
||||||
[desc_sig_punctuation, "]"]))
|
[desc_sig_punctuation, "]"]))
|
||||||
|
|
||||||
doctree = _parse_annotation("Tuple[()]")
|
doctree = _parse_annotation("Tuple[()]", app.env)
|
||||||
assert_node(doctree, ([pending_xref, "Tuple"],
|
assert_node(doctree, ([pending_xref, "Tuple"],
|
||||||
[desc_sig_punctuation, "["],
|
[desc_sig_punctuation, "["],
|
||||||
[desc_sig_punctuation, "("],
|
[desc_sig_punctuation, "("],
|
||||||
[desc_sig_punctuation, ")"],
|
[desc_sig_punctuation, ")"],
|
||||||
[desc_sig_punctuation, "]"]))
|
[desc_sig_punctuation, "]"]))
|
||||||
|
|
||||||
doctree = _parse_annotation("Callable[[int, int], int]")
|
doctree = _parse_annotation("Callable[[int, int], int]", app.env)
|
||||||
assert_node(doctree, ([pending_xref, "Callable"],
|
assert_node(doctree, ([pending_xref, "Callable"],
|
||||||
[desc_sig_punctuation, "["],
|
[desc_sig_punctuation, "["],
|
||||||
[desc_sig_punctuation, "["],
|
[desc_sig_punctuation, "["],
|
||||||
@@ -275,12 +275,11 @@ def test_parse_annotation():
|
|||||||
[desc_sig_punctuation, "]"]))
|
[desc_sig_punctuation, "]"]))
|
||||||
|
|
||||||
# None type makes an object-reference (not a class reference)
|
# None type makes an object-reference (not a class reference)
|
||||||
doctree = _parse_annotation("None")
|
doctree = _parse_annotation("None", app.env)
|
||||||
assert_node(doctree, ([pending_xref, "None"],))
|
assert_node(doctree, ([pending_xref, "None"],))
|
||||||
assert_node(doctree[0], pending_xref, refdomain="py", reftype="obj", reftarget="None")
|
assert_node(doctree[0], pending_xref, refdomain="py", reftype="obj", reftarget="None")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_pyfunction_signature(app):
|
def test_pyfunction_signature(app):
|
||||||
text = ".. py:function:: hello(name: str) -> str"
|
text = ".. py:function:: hello(name: str) -> str"
|
||||||
doctree = restructuredtext.parse(app, text)
|
doctree = restructuredtext.parse(app, text)
|
||||||
@@ -458,14 +457,22 @@ def test_pyobject_prefix(app):
|
|||||||
|
|
||||||
|
|
||||||
def test_pydata(app):
|
def test_pydata(app):
|
||||||
text = ".. py:data:: var\n"
|
text = (".. py:module:: example\n"
|
||||||
|
".. py:data:: var\n"
|
||||||
|
" :type: int\n")
|
||||||
domain = app.env.get_domain('py')
|
domain = app.env.get_domain('py')
|
||||||
doctree = restructuredtext.parse(app, text)
|
doctree = restructuredtext.parse(app, text)
|
||||||
assert_node(doctree, (addnodes.index,
|
assert_node(doctree, (nodes.target,
|
||||||
[desc, ([desc_signature, desc_name, "var"],
|
addnodes.index,
|
||||||
|
addnodes.index,
|
||||||
|
[desc, ([desc_signature, ([desc_addname, "example."],
|
||||||
|
[desc_name, "var"],
|
||||||
|
[desc_annotation, (": ",
|
||||||
|
[pending_xref, "int"])])],
|
||||||
[desc_content, ()])]))
|
[desc_content, ()])]))
|
||||||
assert 'var' in domain.objects
|
assert_node(doctree[3][0][2][1], pending_xref, **{"py:module": "example"})
|
||||||
assert domain.objects['var'] == ('index', 'var', 'data')
|
assert 'example.var' in domain.objects
|
||||||
|
assert domain.objects['example.var'] == ('index', 'example.var', 'data')
|
||||||
|
|
||||||
|
|
||||||
def test_pyfunction(app):
|
def test_pyfunction(app):
|
||||||
@@ -698,6 +705,8 @@ def test_pyattribute(app):
|
|||||||
[desc_sig_punctuation, "]"])],
|
[desc_sig_punctuation, "]"])],
|
||||||
[desc_annotation, " = ''"])],
|
[desc_annotation, " = ''"])],
|
||||||
[desc_content, ()]))
|
[desc_content, ()]))
|
||||||
|
assert_node(doctree[1][1][1][0][1][1], pending_xref, **{"py:class": "Class"})
|
||||||
|
assert_node(doctree[1][1][1][0][1][3], pending_xref, **{"py:class": "Class"})
|
||||||
assert 'Class.attr' in domain.objects
|
assert 'Class.attr' in domain.objects
|
||||||
assert domain.objects['Class.attr'] == ('index', 'Class.attr', 'attribute')
|
assert domain.objects['Class.attr'] == ('index', 'Class.attr', 'attribute')
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ def test_signature_partialmethod():
|
|||||||
|
|
||||||
def test_signature_annotations():
|
def test_signature_annotations():
|
||||||
from typing_test_data import (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10,
|
from typing_test_data import (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10,
|
||||||
f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, Node)
|
f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, Node)
|
||||||
|
|
||||||
# Class annotations
|
# Class annotations
|
||||||
sig = inspect.signature(f0)
|
sig = inspect.signature(f0)
|
||||||
@@ -214,6 +214,10 @@ def test_signature_annotations():
|
|||||||
sig = inspect.signature(f19)
|
sig = inspect.signature(f19)
|
||||||
assert stringify_signature(sig) == '(*args: int, **kwargs: str)'
|
assert stringify_signature(sig) == '(*args: int, **kwargs: str)'
|
||||||
|
|
||||||
|
# default value is inspect.Signature.empty
|
||||||
|
sig = inspect.signature(f21)
|
||||||
|
assert stringify_signature(sig) == "(arg1='whatever', arg2)"
|
||||||
|
|
||||||
# type hints by string
|
# type hints by string
|
||||||
sig = inspect.signature(Node.children)
|
sig = inspect.signature(Node.children)
|
||||||
if (3, 5, 0) <= sys.version_info < (3, 5, 3):
|
if (3, 5, 0) <= sys.version_info < (3, 5, 3):
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from inspect import Signature
|
||||||
from numbers import Integral
|
from numbers import Integral
|
||||||
from typing import Any, Dict, List, TypeVar, Union, Callable, Tuple, Optional
|
from typing import Any, Dict, List, TypeVar, Union, Callable, Tuple, Optional
|
||||||
|
|
||||||
@@ -100,6 +101,9 @@ def f20() -> Optional[Union[int, str]]:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def f21(arg1='whatever', arg2=Signature.empty):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Node:
|
class Node:
|
||||||
def __init__(self, parent: Optional['Node']) -> None:
|
def __init__(self, parent: Optional['Node']) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user