Skip to content

Commit

Permalink
py domain: Support type union operator (PEP-604) (refs: sphinx-doc#8775)
Browse files Browse the repository at this point in the history
Upgrade annotation parser for python domain to support type union
operator introduced in PEP-604.  It's available on all python
interpreters.
  • Loading branch information
tk0miya committed Jan 31, 2021
1 parent be20f17 commit 151a83e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES
Expand Up @@ -54,6 +54,7 @@ Features added
* #8004: napoleon: Type definitions in Google style docstrings are rendered as
references when :confval:`napoleon_preprocess_types` enabled
* #6241: mathjax: Include mathjax.js only on the document using equations
* #8775: py domain: Support type union operator (PEP-604)
* #8651: std domain: cross-reference for a rubric having inline item is broken
* #7642: std domain: Optimize case-insensitive match of term
* #8681: viewcode: Support incremental build
Expand Down
9 changes: 8 additions & 1 deletion sphinx/domains/python.py
Expand Up @@ -100,12 +100,19 @@ def _parse_annotation(annotation: str, env: BuildEnvironment = None) -> List[Nod
def unparse(node: ast.AST) -> List[Node]:
if isinstance(node, ast.Attribute):
return [nodes.Text("%s.%s" % (unparse(node.value)[0], node.attr))]
elif isinstance(node, ast.BinOp):
result = unparse(node.left) # type: List[Node]
result.extend(unparse(node.op))
result.extend(unparse(node.right))
return result
elif isinstance(node, ast.BitOr):
return [addnodes.desc_sig_punctuation('', ' | ')]
elif isinstance(node, ast.Expr):
return unparse(node.value)
elif isinstance(node, ast.Index):
return unparse(node.value)
elif isinstance(node, ast.List):
result = [addnodes.desc_sig_punctuation('', '[')] # type: List[Node]
result = [addnodes.desc_sig_punctuation('', '[')]
for elem in node.elts:
result.extend(unparse(elem))
result.append(addnodes.desc_sig_punctuation('', ', '))
Expand Down
24 changes: 24 additions & 0 deletions tests/test_domain_py.py
Expand Up @@ -429,6 +429,18 @@ def test_pyfunction_with_number_literals(app):
[nodes.inline, "1_6_0"])])])


def test_pyfunction_with_union_type_operator(app):
text = ".. py:function:: hello(age: int | None)"
doctree = restructuredtext.parse(app, text)
assert_node(doctree[1][0][1],
[desc_parameterlist, ([desc_parameter, ([desc_sig_name, "age"],
[desc_sig_punctuation, ":"],
" ",
[desc_sig_name, ([pending_xref, "int"],
[desc_sig_punctuation, " | "],
[pending_xref, "None"])])])])


def test_optional_pyfunction_signature(app):
text = ".. py:function:: compile(source [, filename [, symbol]]) -> ast object"
doctree = restructuredtext.parse(app, text)
Expand Down Expand Up @@ -496,6 +508,18 @@ def test_pydata_signature_old(app):
domain="py", objtype="data", noindex=False)


def test_pydata_with_union_type_operator(app):
text = (".. py:data:: version\n"
" :type: int | str")
doctree = restructuredtext.parse(app, text)
assert_node(doctree[1][0],
([desc_name, "version"],
[desc_annotation, (": ",
[pending_xref, "int"],
[desc_sig_punctuation, " | "],
[pending_xref, "str"])]))


def test_pyobject_prefix(app):
text = (".. py:class:: Foo\n"
"\n"
Expand Down

0 comments on commit 151a83e

Please sign in to comment.