From a99675bf78eec8024792da6448e89ea534c59b5a Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 30 Jul 2020 01:41:18 +0900 Subject: [PATCH] Fix #8008: py domain: failed to parse a type annotation containing ellipsis Fix _parse_annotation() does not support a type annotation having ellipsis. --- CHANGES | 1 + sphinx/domains/python.py | 14 ++++++++++++++ tests/test_domain_py.py | 14 ++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/CHANGES b/CHANGES index ff9236469..4da2823e9 100644 --- a/CHANGES +++ b/CHANGES @@ -69,6 +69,7 @@ Bugs fixed * #7691: linkcheck: HEAD requests are not used for checking * #4888: i18n: Failed to add an explicit title to ``:ref:`` role on translation * #7928: py domain: failed to resolve a type annotation for the attribute +* #8008: py domain: failed to parse a type annotation containing ellipsis * #7994: std domain: option directive does not generate old node_id compatible with 2.x or older * #7968: i18n: The content of ``math`` directive is interpreted as reST on diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index fb167828f..f4bc58b69 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -11,6 +11,7 @@ import builtins import inspect import re +import sys import typing import warnings from inspect import Parameter @@ -134,6 +135,19 @@ def _parse_annotation(annotation: str, env: BuildEnvironment = None) -> List[Nod return result else: + if sys.version_info >= (3, 6): + if isinstance(node, ast.Constant): + if node.value is Ellipsis: + return [addnodes.desc_sig_punctuation('', "...")] + else: + return [nodes.Text(node.value)] + + if sys.version_info < (3, 8): + if isinstance(node, ast.Ellipsis): + return [addnodes.desc_sig_punctuation('', "...")] + elif isinstance(node, ast.NameConstant): + return [nodes.Text(node.value)] + raise SyntaxError # unsupported syntax if env is None: diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py index ccf539b6d..b98f37912 100644 --- a/tests/test_domain_py.py +++ b/tests/test_domain_py.py @@ -262,6 +262,14 @@ def test_parse_annotation(app): [desc_sig_punctuation, ")"], [desc_sig_punctuation, "]"])) + doctree = _parse_annotation("Tuple[int, ...]", app.env) + assert_node(doctree, ([pending_xref, "Tuple"], + [desc_sig_punctuation, "["], + [pending_xref, "int"], + [desc_sig_punctuation, ", "], + [desc_sig_punctuation, "..."], + [desc_sig_punctuation, "]"])) + doctree = _parse_annotation("Callable[[int, int], int]", app.env) assert_node(doctree, ([pending_xref, "Callable"], [desc_sig_punctuation, "["], @@ -274,6 +282,12 @@ def test_parse_annotation(app): [pending_xref, "int"], [desc_sig_punctuation, "]"])) + doctree = _parse_annotation("List[None]", app.env) + assert_node(doctree, ([pending_xref, "List"], + [desc_sig_punctuation, "["], + [pending_xref, "None"], + [desc_sig_punctuation, "]"])) + # None type makes an object-reference (not a class reference) doctree = _parse_annotation("None", app.env) assert_node(doctree, ([pending_xref, "None"],))