Fix #9576: py domain: Literal typehint was converted to a cross reference

The content of Literal typehint should not be converted to cross
references.
This commit is contained in:
Takeshi KOMIYA
2021-09-02 02:25:31 +09:00
parent 80fbbb8462
commit 34664ce4ce
3 changed files with 32 additions and 2 deletions

View File

@@ -40,6 +40,7 @@ Bugs fixed
* #9267: html theme: CSS and JS files added by theme were loaded twice
* #9585: py domain: ``:type:`` option for :rst:dir:`py:property` directive does
not create a hyperlink
* #9576: py domain: Literal typehint was converted to a cross reference
* #9535 comment: C++, fix parsing of defaulted function parameters that are
function pointers.
* #9564: smartquotes: don't adjust typography for text with

View File

@@ -123,7 +123,7 @@ def _parse_annotation(annotation: str, env: BuildEnvironment = None) -> List[Nod
if node.value is Ellipsis:
return [addnodes.desc_sig_punctuation('', "...")]
else:
return [nodes.Text(node.value)]
return [nodes.Text(repr(node.value))]
elif isinstance(node, ast.Expr):
return unparse(node.value)
elif isinstance(node, ast.Index):
@@ -149,6 +149,12 @@ def _parse_annotation(annotation: str, env: BuildEnvironment = None) -> List[Nod
result.append(addnodes.desc_sig_punctuation('', '['))
result.extend(unparse(node.slice))
result.append(addnodes.desc_sig_punctuation('', ']'))
# Wrap the Text nodes inside brackets by literal node if the subscript is a Literal
if result[0] in ('Literal', 'typing.Literal'):
for i, subnode in enumerate(result[1:], start=1):
if isinstance(subnode, nodes.Text):
result[i] = nodes.literal('', '', subnode)
return result
elif isinstance(node, ast.Tuple):
if node.elts:
@@ -179,7 +185,9 @@ def _parse_annotation(annotation: str, env: BuildEnvironment = None) -> List[Nod
tree = ast_parse(annotation)
result = unparse(tree)
for i, node in enumerate(result):
if isinstance(node, nodes.Text) and node.strip():
if isinstance(node, nodes.literal):
result[i] = node[0]
elif isinstance(node, nodes.Text) and node.strip():
result[i] = type_to_xref(str(node), env)
return result
except SyntaxError:

View File

@@ -342,6 +342,27 @@ def test_parse_annotation(app):
assert_node(doctree[0], pending_xref, refdomain="py", reftype="obj", reftarget="None")
@pytest.mark.skipif(sys.version_info < (3, 8), reason='python 3.8+ is required.')
def test_parse_annotation_Literal(app):
doctree = _parse_annotation("Literal[True, False]", app.env)
assert_node(doctree, ([pending_xref, "Literal"],
[desc_sig_punctuation, "["],
"True",
[desc_sig_punctuation, ", "],
"False",
[desc_sig_punctuation, "]"]))
doctree = _parse_annotation("typing.Literal[0, 1, 'abc']", app.env)
assert_node(doctree, ([pending_xref, "typing.Literal"],
[desc_sig_punctuation, "["],
"0",
[desc_sig_punctuation, ", "],
"1",
[desc_sig_punctuation, ", "],
"'abc'",
[desc_sig_punctuation, "]"]))
def test_pyfunction_signature(app):
text = ".. py:function:: hello(name: str) -> str"
doctree = restructuredtext.parse(app, text)