diff --git a/doc/domains.rst b/doc/domains.rst index 2aaf218c0..a259cbccd 100644 --- a/doc/domains.rst +++ b/doc/domains.rst @@ -359,6 +359,18 @@ single word, like this:: :param int priority: The priority of the message, can be a number 1-5 +.. versionadded:: 1.5 + +Container types such as lists and dictionaries can be linked automatically +using the following syntax:: + + :type priorities: list(int) + :type priorities: list[int] + :type mapping: dict(str, int) + :type mapping: dict[str, int] + :type point: tuple(float, float) + :type point: tuple[float, float] + .. _python-roles: Cross-referencing Python objects diff --git a/doc/ext/example_google.py b/doc/ext/example_google.py index c3ba273b8..34a720e36 100644 --- a/doc/ext/example_google.py +++ b/doc/ext/example_google.py @@ -211,14 +211,14 @@ class ExampleClass(object): param1 (str): Description of `param1`. param2 (:obj:`int`, optional): Description of `param2`. Multiple lines are supported. - param3 (:obj:`list` of :obj:`str`): Description of `param3`. + param3 (list(str)): Description of `param3`. """ self.attr1 = param1 self.attr2 = param2 self.attr3 = param3 #: Doc comment *inline* with attribute - #: list of str: Doc comment *before* attribute, with type specified + #: list(str): Doc comment *before* attribute, with type specified self.attr4 = ['attr4'] self.attr5 = None @@ -231,7 +231,7 @@ class ExampleClass(object): @property def readwrite_property(self): - """:obj:`list` of :obj:`str`: Properties with both a getter and setter + """list(str): Properties with both a getter and setter should only be documented in their getter method. If the setter method contains notable behavior, it should be diff --git a/doc/ext/example_numpy.py b/doc/ext/example_numpy.py index 0e71008e1..7a2db94cc 100644 --- a/doc/ext/example_numpy.py +++ b/doc/ext/example_numpy.py @@ -260,7 +260,7 @@ class ExampleClass(object): ---------- param1 : str Description of `param1`. - param2 : :obj:`list` of :obj:`str` + param2 : list(str) Description of `param2`. Multiple lines are supported. param3 : :obj:`int`, optional @@ -271,7 +271,7 @@ class ExampleClass(object): self.attr2 = param2 self.attr3 = param3 #: Doc comment *inline* with attribute - #: list of str: Doc comment *before* attribute, with type specified + #: list(str): Doc comment *before* attribute, with type specified self.attr4 = ["attr4"] self.attr5 = None @@ -284,7 +284,7 @@ class ExampleClass(object): @property def readwrite_property(self): - """:obj:`list` of :obj:`str`: Properties with both a getter and setter + """list(str): Properties with both a getter and setter should only be documented in their getter method. If the setter method contains notable behavior, it should be diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index 06a6b3002..3d7e10467 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -101,6 +101,27 @@ class PyXrefMixin(object): break return result + def make_xrefs(self, rolename, domain, target, innernode=nodes.emphasis, + contnode=None): + delims = '(\s*[\[\]\(\),]\s*)' + delims_re = re.compile(delims) + sub_targets = re.split(delims, target) + + split_contnode = bool(contnode and contnode.astext() == target) + + results = [] + for sub_target in sub_targets: + if split_contnode: + contnode = nodes.Text(sub_target) + + if delims_re.match(sub_target): + results.append(contnode or innernode(sub_target, sub_target)) + else: + results.append(self.make_xref(rolename, domain, sub_target, + innernode, contnode)) + + return results + class PyField(PyXrefMixin, Field): pass diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index c3d5bb3d0..f306b4ddc 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -24,7 +24,7 @@ from sphinx.util.pycompat import UnicodeMixin _directive_regex = re.compile(r'\.\. \S+::') _google_section_regex = re.compile(r'^(\s|\w)+:\s*$') -_google_typed_arg_regex = re.compile(r'\s*(.+?)\s*\(\s*(.+?)\s*\)') +_google_typed_arg_regex = re.compile(r'\s*(.+?)\s*\(\s*(.*[^\s]+)\s*\)') _numpy_section_regex = re.compile(r'^[=\-`:\'"~^_*+#<>]{2,}\s*$') _single_colon_regex = re.compile(r'(?