Skip to content

Commit 4ad45ce

Browse files
authored
Merge pull request #9602 from tk0miya/9576_Literal_xref
Fix #9576: py domain: Literal typehint was converted to a cross reference
2 parents 6c38f68 + 34664ce commit 4ad45ce

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

CHANGES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Bugs fixed
4040
* #9267: html theme: CSS and JS files added by theme were loaded twice
4141
* #9585: py domain: ``:type:`` option for :rst:dir:`py:property` directive does
4242
not create a hyperlink
43+
* #9576: py domain: Literal typehint was converted to a cross reference
4344
* #9535 comment: C++, fix parsing of defaulted function parameters that are
4445
function pointers.
4546
* #9564: smartquotes: don't adjust typography for text with

sphinx/domains/python.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def unparse(node: ast.AST) -> List[Node]:
123123
if node.value is Ellipsis:
124124
return [addnodes.desc_sig_punctuation('', "...")]
125125
else:
126-
return [nodes.Text(node.value)]
126+
return [nodes.Text(repr(node.value))]
127127
elif isinstance(node, ast.Expr):
128128
return unparse(node.value)
129129
elif isinstance(node, ast.Index):
@@ -149,6 +149,12 @@ def unparse(node: ast.AST) -> List[Node]:
149149
result.append(addnodes.desc_sig_punctuation('', '['))
150150
result.extend(unparse(node.slice))
151151
result.append(addnodes.desc_sig_punctuation('', ']'))
152+
153+
# Wrap the Text nodes inside brackets by literal node if the subscript is a Literal
154+
if result[0] in ('Literal', 'typing.Literal'):
155+
for i, subnode in enumerate(result[1:], start=1):
156+
if isinstance(subnode, nodes.Text):
157+
result[i] = nodes.literal('', '', subnode)
152158
return result
153159
elif isinstance(node, ast.Tuple):
154160
if node.elts:
@@ -179,7 +185,9 @@ def unparse(node: ast.AST) -> List[Node]:
179185
tree = ast_parse(annotation)
180186
result = unparse(tree)
181187
for i, node in enumerate(result):
182-
if isinstance(node, nodes.Text) and node.strip():
188+
if isinstance(node, nodes.literal):
189+
result[i] = node[0]
190+
elif isinstance(node, nodes.Text) and node.strip():
183191
result[i] = type_to_xref(str(node), env)
184192
return result
185193
except SyntaxError:

tests/test_domain_py.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,27 @@ def test_parse_annotation(app):
342342
assert_node(doctree[0], pending_xref, refdomain="py", reftype="obj", reftarget="None")
343343

344344

345+
@pytest.mark.skipif(sys.version_info < (3, 8), reason='python 3.8+ is required.')
346+
def test_parse_annotation_Literal(app):
347+
doctree = _parse_annotation("Literal[True, False]", app.env)
348+
assert_node(doctree, ([pending_xref, "Literal"],
349+
[desc_sig_punctuation, "["],
350+
"True",
351+
[desc_sig_punctuation, ", "],
352+
"False",
353+
[desc_sig_punctuation, "]"]))
354+
355+
doctree = _parse_annotation("typing.Literal[0, 1, 'abc']", app.env)
356+
assert_node(doctree, ([pending_xref, "typing.Literal"],
357+
[desc_sig_punctuation, "["],
358+
"0",
359+
[desc_sig_punctuation, ", "],
360+
"1",
361+
[desc_sig_punctuation, ", "],
362+
"'abc'",
363+
[desc_sig_punctuation, "]"]))
364+
365+
345366
def test_pyfunction_signature(app):
346367
text = ".. py:function:: hello(name: str) -> str"
347368
doctree = restructuredtext.parse(app, text)

0 commit comments

Comments
 (0)