mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Google types now greedily match the closing parenthesis. Also removed name from returns section in Google docstrings. Instead, everything before the colon is treated as the type.
1782 lines
42 KiB
Python
1782 lines
42 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
test_napoleon_docstring
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Tests for :mod:`sphinx.ext.napoleon.docstring` module.
|
|
|
|
|
|
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
|
:license: BSD, see LICENSE for details.
|
|
"""
|
|
|
|
from collections import namedtuple
|
|
|
|
# inspect.cleandoc() implements the trim() function from PEP 257
|
|
from inspect import cleandoc
|
|
from textwrap import dedent
|
|
from unittest import TestCase
|
|
|
|
from sphinx.ext.napoleon import Config
|
|
from sphinx.ext.napoleon.docstring import GoogleDocstring, NumpyDocstring
|
|
from util import mock
|
|
|
|
|
|
class NamedtupleSubclass(namedtuple('NamedtupleSubclass', ('attr1', 'attr2'))):
|
|
"""Sample namedtuple subclass
|
|
|
|
Attributes
|
|
----------
|
|
attr1 : Arbitrary type
|
|
Quick description of attr1
|
|
attr2 : Another arbitrary type
|
|
Quick description of attr2
|
|
attr3 : Type
|
|
|
|
Adds a newline after the type
|
|
|
|
"""
|
|
# To avoid creating a dict, as a namedtuple doesn't have it:
|
|
__slots__ = ()
|
|
|
|
def __new__(cls, attr1, attr2=None):
|
|
return super(NamedtupleSubclass, cls).__new__(cls, attr1, attr2)
|
|
|
|
|
|
class BaseDocstringTest(TestCase):
|
|
pass
|
|
|
|
|
|
class NamedtupleSubclassTest(BaseDocstringTest):
|
|
def test_attributes_docstring(self):
|
|
config = Config()
|
|
actual = str(NumpyDocstring(cleandoc(NamedtupleSubclass.__doc__),
|
|
config=config, app=None, what='class',
|
|
name='NamedtupleSubclass', obj=NamedtupleSubclass))
|
|
expected = """\
|
|
Sample namedtuple subclass
|
|
|
|
.. attribute:: attr1
|
|
|
|
*Arbitrary type* -- Quick description of attr1
|
|
|
|
.. attribute:: attr2
|
|
|
|
*Another arbitrary type* -- Quick description of attr2
|
|
|
|
.. attribute:: attr3
|
|
|
|
*Type* -- Adds a newline after the type
|
|
"""
|
|
|
|
self.assertEqual(expected, actual)
|
|
|
|
|
|
class GoogleDocstringTest(BaseDocstringTest):
|
|
docstrings = [(
|
|
"""Single line summary""",
|
|
"""Single line summary"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Extended description
|
|
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
Extended description
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Args:
|
|
arg1(str):Extended
|
|
description of arg1
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:Parameters: **arg1** (*str*) -- Extended
|
|
description of arg1
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Args:
|
|
arg1(str):Extended
|
|
description of arg1
|
|
arg2 ( int ) : Extended
|
|
description of arg2
|
|
|
|
Keyword Args:
|
|
kwarg1(str):Extended
|
|
description of kwarg1
|
|
kwarg2 ( int ) : Extended
|
|
description of kwarg2""",
|
|
"""
|
|
Single line summary
|
|
|
|
:Parameters: * **arg1** (*str*) -- Extended
|
|
description of arg1
|
|
* **arg2** (*int*) -- Extended
|
|
description of arg2
|
|
|
|
:Keyword Arguments: * **kwarg1** (*str*) -- Extended
|
|
description of kwarg1
|
|
* **kwarg2** (*int*) -- Extended
|
|
description of kwarg2
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Arguments:
|
|
arg1(str):Extended
|
|
description of arg1
|
|
arg2 ( int ) : Extended
|
|
description of arg2
|
|
|
|
Keyword Arguments:
|
|
kwarg1(str):Extended
|
|
description of kwarg1
|
|
kwarg2 ( int ) : Extended
|
|
description of kwarg2""",
|
|
"""
|
|
Single line summary
|
|
|
|
:Parameters: * **arg1** (*str*) -- Extended
|
|
description of arg1
|
|
* **arg2** (*int*) -- Extended
|
|
description of arg2
|
|
|
|
:Keyword Arguments: * **kwarg1** (*str*) -- Extended
|
|
description of kwarg1
|
|
* **kwarg2** (*int*) -- Extended
|
|
description of kwarg2
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Return:
|
|
str:Extended
|
|
description of return value
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:returns: *str* -- Extended
|
|
description of return value
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Returns:
|
|
str:Extended
|
|
description of return value
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:returns: *str* -- Extended
|
|
description of return value
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Returns:
|
|
Extended
|
|
description of return value
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:returns: Extended
|
|
description of return value
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Args:
|
|
arg1(str):Extended
|
|
description of arg1
|
|
*args: Variable length argument list.
|
|
**kwargs: Arbitrary keyword arguments.
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:Parameters: * **arg1** (*str*) -- Extended
|
|
description of arg1
|
|
* **\\*args** -- Variable length argument list.
|
|
* **\\*\\*kwargs** -- Arbitrary keyword arguments.
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Args:
|
|
arg1 (list(int)): Description
|
|
arg2 (list[int]): Description
|
|
arg3 (dict(str, int)): Description
|
|
arg4 (dict[str, int]): Description
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:Parameters: * **arg1** (*list(int)*) -- Description
|
|
* **arg2** (*list[int]*) -- Description
|
|
* **arg3** (*dict(str, int)*) -- Description
|
|
* **arg4** (*dict[str, int]*) -- Description
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Yield:
|
|
str:Extended
|
|
description of yielded value
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:Yields: *str* -- Extended
|
|
description of yielded value
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Yields:
|
|
Extended
|
|
description of yielded value
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:Yields: Extended
|
|
description of yielded value
|
|
"""
|
|
)]
|
|
|
|
def test_docstrings(self):
|
|
config = Config(
|
|
napoleon_use_param=False,
|
|
napoleon_use_rtype=False,
|
|
napoleon_use_keyword=False
|
|
)
|
|
for docstring, expected in self.docstrings:
|
|
actual = str(GoogleDocstring(dedent(docstring), config))
|
|
expected = dedent(expected)
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_parameters_with_class_reference(self):
|
|
docstring = """\
|
|
Construct a new XBlock.
|
|
|
|
This class should only be used by runtimes.
|
|
|
|
Arguments:
|
|
runtime (:class:`Runtime`): Use it to access the environment.
|
|
It is available in XBlock code as ``self.runtime``.
|
|
|
|
field_data (:class:`FieldData`): Interface used by the XBlock
|
|
fields to access their data from wherever it is persisted.
|
|
|
|
scope_ids (:class:`ScopeIds`): Identifiers needed to resolve scopes.
|
|
|
|
"""
|
|
|
|
actual = str(GoogleDocstring(docstring))
|
|
expected = """\
|
|
Construct a new XBlock.
|
|
|
|
This class should only be used by runtimes.
|
|
|
|
:param runtime: Use it to access the environment.
|
|
It is available in XBlock code as ``self.runtime``.
|
|
:type runtime: :class:`Runtime`
|
|
:param field_data: Interface used by the XBlock
|
|
fields to access their data from wherever it is persisted.
|
|
:type field_data: :class:`FieldData`
|
|
:param scope_ids: Identifiers needed to resolve scopes.
|
|
:type scope_ids: :class:`ScopeIds`
|
|
"""
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_attributes_with_class_reference(self):
|
|
docstring = """\
|
|
Attributes:
|
|
in_attr(:class:`numpy.ndarray`): super-dooper attribute
|
|
"""
|
|
|
|
actual = str(GoogleDocstring(docstring))
|
|
expected = """\
|
|
.. attribute:: in_attr
|
|
|
|
:class:`numpy.ndarray` -- super-dooper attribute
|
|
"""
|
|
self.assertEqual(expected, actual)
|
|
|
|
docstring = """\
|
|
Attributes:
|
|
in_attr(numpy.ndarray): super-dooper attribute
|
|
"""
|
|
|
|
actual = str(GoogleDocstring(docstring))
|
|
expected = """\
|
|
.. attribute:: in_attr
|
|
|
|
*numpy.ndarray* -- super-dooper attribute
|
|
"""
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_code_block_in_returns_section(self):
|
|
docstring = """
|
|
Returns:
|
|
foobar: foo::
|
|
|
|
codecode
|
|
codecode
|
|
"""
|
|
expected = """
|
|
:returns:
|
|
|
|
foo::
|
|
|
|
codecode
|
|
codecode
|
|
:rtype: foobar
|
|
"""
|
|
actual = str(GoogleDocstring(docstring))
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_colon_in_return_type(self):
|
|
docstring = """Example property.
|
|
|
|
Returns:
|
|
:py:class:`~.module.submodule.SomeClass`: an example instance
|
|
if available, None if not available.
|
|
"""
|
|
expected = """Example property.
|
|
|
|
:returns: an example instance
|
|
if available, None if not available.
|
|
:rtype: :py:class:`~.module.submodule.SomeClass`
|
|
"""
|
|
actual = str(GoogleDocstring(docstring))
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_xrefs_in_return_type(self):
|
|
docstring = """Example Function
|
|
|
|
Returns:
|
|
:class:`numpy.ndarray`: A :math:`n \\times 2` array containing
|
|
a bunch of math items
|
|
"""
|
|
expected = """Example Function
|
|
|
|
:returns: A :math:`n \\times 2` array containing
|
|
a bunch of math items
|
|
:rtype: :class:`numpy.ndarray`
|
|
"""
|
|
actual = str(GoogleDocstring(docstring))
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_raises_types(self):
|
|
docstrings = [("""
|
|
Example Function
|
|
|
|
Raises:
|
|
RuntimeError:
|
|
A setting wasn't specified, or was invalid.
|
|
ValueError:
|
|
Something something value error.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: * :exc:`RuntimeError` -- A setting wasn't specified, or was invalid.
|
|
* :exc:`ValueError` -- Something something value error.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises:
|
|
InvalidDimensionsError
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: :exc:`InvalidDimensionsError`
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises:
|
|
Invalid Dimensions Error
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: Invalid Dimensions Error
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises:
|
|
Invalid Dimensions Error: With description
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: *Invalid Dimensions Error* -- With description
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises:
|
|
InvalidDimensionsError: If the dimensions couldn't be parsed.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: :exc:`InvalidDimensionsError` -- If the dimensions couldn't be parsed.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises:
|
|
Invalid Dimensions Error: If the dimensions couldn't be parsed.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: *Invalid Dimensions Error* -- If the dimensions couldn't be parsed.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises:
|
|
If the dimensions couldn't be parsed.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: If the dimensions couldn't be parsed.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises:
|
|
:class:`exc.InvalidDimensionsError`
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: :class:`exc.InvalidDimensionsError`
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises:
|
|
:class:`exc.InvalidDimensionsError`: If the dimensions couldn't be parsed.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: :class:`exc.InvalidDimensionsError` -- If the dimensions couldn't """
|
|
"""be parsed.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises:
|
|
:class:`exc.InvalidDimensionsError`: If the dimensions couldn't be parsed,
|
|
then a :class:`exc.InvalidDimensionsError` will be raised.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: :class:`exc.InvalidDimensionsError` -- If the dimensions couldn't """
|
|
"""be parsed,
|
|
then a :class:`exc.InvalidDimensionsError` will be raised.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises:
|
|
:class:`exc.InvalidDimensionsError`: If the dimensions couldn't be parsed.
|
|
:class:`exc.InvalidArgumentsError`: If the arguments are invalid.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: * :class:`exc.InvalidDimensionsError` -- If the dimensions """
|
|
"""couldn't be parsed.
|
|
* :class:`exc.InvalidArgumentsError` -- If the arguments are invalid.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises:
|
|
:class:`exc.InvalidDimensionsError`
|
|
:class:`exc.InvalidArgumentsError`
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: * :class:`exc.InvalidDimensionsError`
|
|
* :class:`exc.InvalidArgumentsError`
|
|
""")]
|
|
for docstring, expected in docstrings:
|
|
actual = str(GoogleDocstring(docstring))
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_kwargs_in_arguments(self):
|
|
docstring = """Allows to create attributes binded to this device.
|
|
|
|
Some other paragraph.
|
|
|
|
Code sample for usage::
|
|
|
|
dev.bind(loopback=Loopback)
|
|
dev.loopback.configure()
|
|
|
|
Arguments:
|
|
**kwargs: name/class pairs that will create resource-managers
|
|
bound as instance attributes to this instance. See code
|
|
example above.
|
|
"""
|
|
expected = """Allows to create attributes binded to this device.
|
|
|
|
Some other paragraph.
|
|
|
|
Code sample for usage::
|
|
|
|
dev.bind(loopback=Loopback)
|
|
dev.loopback.configure()
|
|
|
|
:param \\*\\*kwargs: name/class pairs that will create resource-managers
|
|
bound as instance attributes to this instance. See code
|
|
example above.
|
|
"""
|
|
actual = str(GoogleDocstring(docstring))
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_section_header_formatting(self):
|
|
docstrings = [("""
|
|
Summary line
|
|
|
|
Example:
|
|
Multiline reStructuredText
|
|
literal code block
|
|
|
|
""", """
|
|
Summary line
|
|
|
|
.. rubric:: Example
|
|
|
|
Multiline reStructuredText
|
|
literal code block
|
|
"""),
|
|
################################
|
|
("""
|
|
Summary line
|
|
|
|
Example::
|
|
|
|
Multiline reStructuredText
|
|
literal code block
|
|
|
|
""", """
|
|
Summary line
|
|
|
|
Example::
|
|
|
|
Multiline reStructuredText
|
|
literal code block
|
|
"""),
|
|
################################
|
|
("""
|
|
Summary line
|
|
|
|
:Example:
|
|
|
|
Multiline reStructuredText
|
|
literal code block
|
|
|
|
""", """
|
|
Summary line
|
|
|
|
:Example:
|
|
|
|
Multiline reStructuredText
|
|
literal code block
|
|
""")]
|
|
for docstring, expected in docstrings:
|
|
actual = str(GoogleDocstring(docstring))
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_list_in_parameter_description(self):
|
|
docstring = """One line summary.
|
|
|
|
Parameters:
|
|
no_list (int):
|
|
one_bullet_empty (int):
|
|
*
|
|
one_bullet_single_line (int):
|
|
- first line
|
|
one_bullet_two_lines (int):
|
|
+ first line
|
|
continued
|
|
two_bullets_single_line (int):
|
|
- first line
|
|
- second line
|
|
two_bullets_two_lines (int):
|
|
* first line
|
|
continued
|
|
* second line
|
|
continued
|
|
one_enumeration_single_line (int):
|
|
1. first line
|
|
one_enumeration_two_lines (int):
|
|
1) first line
|
|
continued
|
|
two_enumerations_one_line (int):
|
|
(iii) first line
|
|
(iv) second line
|
|
two_enumerations_two_lines (int):
|
|
a. first line
|
|
continued
|
|
b. second line
|
|
continued
|
|
one_definition_one_line (int):
|
|
item 1
|
|
first line
|
|
one_definition_two_lines (int):
|
|
item 1
|
|
first line
|
|
continued
|
|
two_definitions_one_line (int):
|
|
item 1
|
|
first line
|
|
item 2
|
|
second line
|
|
two_definitions_two_lines (int):
|
|
item 1
|
|
first line
|
|
continued
|
|
item 2
|
|
second line
|
|
continued
|
|
one_definition_blank_line (int):
|
|
item 1
|
|
|
|
first line
|
|
|
|
extra first line
|
|
|
|
two_definitions_blank_lines (int):
|
|
item 1
|
|
|
|
first line
|
|
|
|
extra first line
|
|
|
|
item 2
|
|
|
|
second line
|
|
|
|
extra second line
|
|
|
|
definition_after_inline_text (int): text line
|
|
|
|
item 1
|
|
first line
|
|
|
|
definition_after_normal_text (int):
|
|
text line
|
|
|
|
item 1
|
|
first line
|
|
"""
|
|
|
|
expected = """One line summary.
|
|
|
|
:param no_list:
|
|
:type no_list: int
|
|
:param one_bullet_empty:
|
|
*
|
|
:type one_bullet_empty: int
|
|
:param one_bullet_single_line:
|
|
- first line
|
|
:type one_bullet_single_line: int
|
|
:param one_bullet_two_lines:
|
|
+ first line
|
|
continued
|
|
:type one_bullet_two_lines: int
|
|
:param two_bullets_single_line:
|
|
- first line
|
|
- second line
|
|
:type two_bullets_single_line: int
|
|
:param two_bullets_two_lines:
|
|
* first line
|
|
continued
|
|
* second line
|
|
continued
|
|
:type two_bullets_two_lines: int
|
|
:param one_enumeration_single_line:
|
|
1. first line
|
|
:type one_enumeration_single_line: int
|
|
:param one_enumeration_two_lines:
|
|
1) first line
|
|
continued
|
|
:type one_enumeration_two_lines: int
|
|
:param two_enumerations_one_line:
|
|
(iii) first line
|
|
(iv) second line
|
|
:type two_enumerations_one_line: int
|
|
:param two_enumerations_two_lines:
|
|
a. first line
|
|
continued
|
|
b. second line
|
|
continued
|
|
:type two_enumerations_two_lines: int
|
|
:param one_definition_one_line:
|
|
item 1
|
|
first line
|
|
:type one_definition_one_line: int
|
|
:param one_definition_two_lines:
|
|
item 1
|
|
first line
|
|
continued
|
|
:type one_definition_two_lines: int
|
|
:param two_definitions_one_line:
|
|
item 1
|
|
first line
|
|
item 2
|
|
second line
|
|
:type two_definitions_one_line: int
|
|
:param two_definitions_two_lines:
|
|
item 1
|
|
first line
|
|
continued
|
|
item 2
|
|
second line
|
|
continued
|
|
:type two_definitions_two_lines: int
|
|
:param one_definition_blank_line:
|
|
item 1
|
|
|
|
first line
|
|
|
|
extra first line
|
|
:type one_definition_blank_line: int
|
|
:param two_definitions_blank_lines:
|
|
item 1
|
|
|
|
first line
|
|
|
|
extra first line
|
|
|
|
item 2
|
|
|
|
second line
|
|
|
|
extra second line
|
|
:type two_definitions_blank_lines: int
|
|
:param definition_after_inline_text: text line
|
|
|
|
item 1
|
|
first line
|
|
:type definition_after_inline_text: int
|
|
:param definition_after_normal_text: text line
|
|
|
|
item 1
|
|
first line
|
|
:type definition_after_normal_text: int
|
|
"""
|
|
config = Config(napoleon_use_param=True)
|
|
actual = str(GoogleDocstring(docstring, config))
|
|
self.assertEqual(expected, actual)
|
|
|
|
expected = """One line summary.
|
|
|
|
:Parameters: * **no_list** (*int*)
|
|
* **one_bullet_empty** (*int*) --
|
|
|
|
*
|
|
* **one_bullet_single_line** (*int*) --
|
|
|
|
- first line
|
|
* **one_bullet_two_lines** (*int*) --
|
|
|
|
+ first line
|
|
continued
|
|
* **two_bullets_single_line** (*int*) --
|
|
|
|
- first line
|
|
- second line
|
|
* **two_bullets_two_lines** (*int*) --
|
|
|
|
* first line
|
|
continued
|
|
* second line
|
|
continued
|
|
* **one_enumeration_single_line** (*int*) --
|
|
|
|
1. first line
|
|
* **one_enumeration_two_lines** (*int*) --
|
|
|
|
1) first line
|
|
continued
|
|
* **two_enumerations_one_line** (*int*) --
|
|
|
|
(iii) first line
|
|
(iv) second line
|
|
* **two_enumerations_two_lines** (*int*) --
|
|
|
|
a. first line
|
|
continued
|
|
b. second line
|
|
continued
|
|
* **one_definition_one_line** (*int*) --
|
|
|
|
item 1
|
|
first line
|
|
* **one_definition_two_lines** (*int*) --
|
|
|
|
item 1
|
|
first line
|
|
continued
|
|
* **two_definitions_one_line** (*int*) --
|
|
|
|
item 1
|
|
first line
|
|
item 2
|
|
second line
|
|
* **two_definitions_two_lines** (*int*) --
|
|
|
|
item 1
|
|
first line
|
|
continued
|
|
item 2
|
|
second line
|
|
continued
|
|
* **one_definition_blank_line** (*int*) --
|
|
|
|
item 1
|
|
|
|
first line
|
|
|
|
extra first line
|
|
* **two_definitions_blank_lines** (*int*) --
|
|
|
|
item 1
|
|
|
|
first line
|
|
|
|
extra first line
|
|
|
|
item 2
|
|
|
|
second line
|
|
|
|
extra second line
|
|
* **definition_after_inline_text** (*int*) -- text line
|
|
|
|
item 1
|
|
first line
|
|
* **definition_after_normal_text** (*int*) -- text line
|
|
|
|
item 1
|
|
first line
|
|
"""
|
|
config = Config(napoleon_use_param=False)
|
|
actual = str(GoogleDocstring(docstring, config))
|
|
self.assertEqual(expected, actual)
|
|
|
|
|
|
class NumpyDocstringTest(BaseDocstringTest):
|
|
docstrings = [(
|
|
"""Single line summary""",
|
|
"""Single line summary"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Extended description
|
|
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
Extended description
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Parameters
|
|
----------
|
|
arg1:str
|
|
Extended
|
|
description of arg1
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:Parameters: **arg1** (*str*) -- Extended
|
|
description of arg1
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Parameters
|
|
----------
|
|
arg1:str
|
|
Extended
|
|
description of arg1
|
|
arg2 : int
|
|
Extended
|
|
description of arg2
|
|
|
|
Keyword Arguments
|
|
-----------------
|
|
kwarg1:str
|
|
Extended
|
|
description of kwarg1
|
|
kwarg2 : int
|
|
Extended
|
|
description of kwarg2
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:Parameters: * **arg1** (*str*) -- Extended
|
|
description of arg1
|
|
* **arg2** (*int*) -- Extended
|
|
description of arg2
|
|
|
|
:Keyword Arguments: * **kwarg1** (*str*) -- Extended
|
|
description of kwarg1
|
|
* **kwarg2** (*int*) -- Extended
|
|
description of kwarg2
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Return
|
|
------
|
|
str
|
|
Extended
|
|
description of return value
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:returns: *str* -- Extended
|
|
description of return value
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Returns
|
|
-------
|
|
str
|
|
Extended
|
|
description of return value
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:returns: *str* -- Extended
|
|
description of return value
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Parameters
|
|
----------
|
|
arg1:str
|
|
Extended description of arg1
|
|
*args:
|
|
Variable length argument list.
|
|
**kwargs:
|
|
Arbitrary keyword arguments.
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:Parameters: * **arg1** (*str*) -- Extended description of arg1
|
|
* **\\*args** -- Variable length argument list.
|
|
* **\\*\\*kwargs** -- Arbitrary keyword arguments.
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Yield
|
|
-----
|
|
str
|
|
Extended
|
|
description of yielded value
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:Yields: *str* -- Extended
|
|
description of yielded value
|
|
"""
|
|
), (
|
|
"""
|
|
Single line summary
|
|
|
|
Yields
|
|
------
|
|
str
|
|
Extended
|
|
description of yielded value
|
|
""",
|
|
"""
|
|
Single line summary
|
|
|
|
:Yields: *str* -- Extended
|
|
description of yielded value
|
|
"""
|
|
)]
|
|
|
|
def test_docstrings(self):
|
|
config = Config(
|
|
napoleon_use_param=False,
|
|
napoleon_use_rtype=False,
|
|
napoleon_use_keyword=False)
|
|
for docstring, expected in self.docstrings:
|
|
actual = str(NumpyDocstring(dedent(docstring), config))
|
|
expected = dedent(expected)
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_parameters_with_class_reference(self):
|
|
docstring = """\
|
|
Parameters
|
|
----------
|
|
param1 : :class:`MyClass <name.space.MyClass>` instance
|
|
|
|
"""
|
|
|
|
config = Config(napoleon_use_param=False)
|
|
actual = str(NumpyDocstring(docstring, config))
|
|
expected = """\
|
|
:Parameters: **param1** (:class:`MyClass <name.space.MyClass>` instance)
|
|
"""
|
|
self.assertEqual(expected, actual)
|
|
|
|
config = Config(napoleon_use_param=True)
|
|
actual = str(NumpyDocstring(docstring, config))
|
|
expected = """\
|
|
:param param1:
|
|
:type param1: :class:`MyClass <name.space.MyClass>` instance
|
|
"""
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_parameters_without_class_reference(self):
|
|
docstring = """\
|
|
Parameters
|
|
----------
|
|
param1 : MyClass instance
|
|
|
|
"""
|
|
|
|
config = Config(napoleon_use_param=False)
|
|
actual = str(NumpyDocstring(docstring, config))
|
|
expected = """\
|
|
:Parameters: **param1** (*MyClass instance*)
|
|
"""
|
|
self.assertEqual(expected, actual)
|
|
|
|
config = Config(napoleon_use_param=True)
|
|
actual = str(NumpyDocstring(dedent(docstring), config))
|
|
expected = """\
|
|
:param param1:
|
|
:type param1: MyClass instance
|
|
"""
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_see_also_refs(self):
|
|
docstring = """\
|
|
numpy.multivariate_normal(mean, cov, shape=None, spam=None)
|
|
|
|
See Also
|
|
--------
|
|
some, other, funcs
|
|
otherfunc : relationship
|
|
|
|
"""
|
|
|
|
actual = str(NumpyDocstring(docstring))
|
|
|
|
expected = """\
|
|
numpy.multivariate_normal(mean, cov, shape=None, spam=None)
|
|
|
|
.. seealso::
|
|
|
|
:obj:`some`, :obj:`other`, :obj:`funcs`
|
|
\n\
|
|
:obj:`otherfunc`
|
|
relationship
|
|
"""
|
|
self.assertEqual(expected, actual)
|
|
|
|
docstring = """\
|
|
numpy.multivariate_normal(mean, cov, shape=None, spam=None)
|
|
|
|
See Also
|
|
--------
|
|
some, other, funcs
|
|
otherfunc : relationship
|
|
|
|
"""
|
|
|
|
config = Config()
|
|
app = mock.Mock()
|
|
actual = str(NumpyDocstring(docstring, config, app, "method"))
|
|
|
|
expected = """\
|
|
numpy.multivariate_normal(mean, cov, shape=None, spam=None)
|
|
|
|
.. seealso::
|
|
|
|
:meth:`some`, :meth:`other`, :meth:`funcs`
|
|
\n\
|
|
:meth:`otherfunc`
|
|
relationship
|
|
"""
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_colon_in_return_type(self):
|
|
docstring = """
|
|
Summary
|
|
|
|
Returns
|
|
-------
|
|
:py:class:`~my_mod.my_class`
|
|
an instance of :py:class:`~my_mod.my_class`
|
|
"""
|
|
|
|
expected = """
|
|
Summary
|
|
|
|
:returns: an instance of :py:class:`~my_mod.my_class`
|
|
:rtype: :py:class:`~my_mod.my_class`
|
|
"""
|
|
|
|
config = Config()
|
|
app = mock.Mock()
|
|
actual = str(NumpyDocstring(docstring, config, app, "method"))
|
|
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_underscore_in_attribute(self):
|
|
docstring = """
|
|
Attributes
|
|
----------
|
|
|
|
arg_ : type
|
|
some description
|
|
"""
|
|
|
|
expected = """
|
|
:ivar arg_: some description
|
|
:vartype arg_: type
|
|
"""
|
|
|
|
config = Config(napoleon_use_ivar=True)
|
|
app = mock.Mock()
|
|
actual = str(NumpyDocstring(docstring, config, app, "class"))
|
|
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_raises_types(self):
|
|
docstrings = [("""
|
|
Example Function
|
|
|
|
Raises
|
|
------
|
|
RuntimeError
|
|
|
|
A setting wasn't specified, or was invalid.
|
|
ValueError
|
|
|
|
Something something value error.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: * :exc:`RuntimeError` -- A setting wasn't specified, or was invalid.
|
|
* :exc:`ValueError` -- Something something value error.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises
|
|
------
|
|
InvalidDimensionsError
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: :exc:`InvalidDimensionsError`
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises
|
|
------
|
|
Invalid Dimensions Error
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: Invalid Dimensions Error
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises
|
|
------
|
|
Invalid Dimensions Error
|
|
With description
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: *Invalid Dimensions Error* -- With description
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises
|
|
------
|
|
InvalidDimensionsError
|
|
If the dimensions couldn't be parsed.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: :exc:`InvalidDimensionsError` -- If the dimensions couldn't be parsed.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises
|
|
------
|
|
Invalid Dimensions Error
|
|
If the dimensions couldn't be parsed.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: *Invalid Dimensions Error* -- If the dimensions couldn't be parsed.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises
|
|
------
|
|
If the dimensions couldn't be parsed.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: If the dimensions couldn't be parsed.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises
|
|
------
|
|
:class:`exc.InvalidDimensionsError`
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: :class:`exc.InvalidDimensionsError`
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises
|
|
------
|
|
:class:`exc.InvalidDimensionsError`
|
|
If the dimensions couldn't be parsed.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: :class:`exc.InvalidDimensionsError` -- If the dimensions couldn't """
|
|
"""be parsed.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises
|
|
------
|
|
:class:`exc.InvalidDimensionsError`
|
|
If the dimensions couldn't be parsed,
|
|
then a :class:`exc.InvalidDimensionsError` will be raised.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: :class:`exc.InvalidDimensionsError` -- If the dimensions couldn't """
|
|
"""be parsed,
|
|
then a :class:`exc.InvalidDimensionsError` will be raised.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises
|
|
------
|
|
:class:`exc.InvalidDimensionsError`
|
|
If the dimensions couldn't be parsed.
|
|
:class:`exc.InvalidArgumentsError`
|
|
If the arguments are invalid.
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: * :class:`exc.InvalidDimensionsError` -- If the dimensions """
|
|
"""couldn't be parsed.
|
|
* :class:`exc.InvalidArgumentsError` -- If the arguments """
|
|
"""are invalid.
|
|
"""),
|
|
################################
|
|
("""
|
|
Example Function
|
|
|
|
Raises
|
|
------
|
|
:class:`exc.InvalidDimensionsError`
|
|
:class:`exc.InvalidArgumentsError`
|
|
|
|
""", """
|
|
Example Function
|
|
|
|
:raises: * :class:`exc.InvalidDimensionsError`
|
|
* :class:`exc.InvalidArgumentsError`
|
|
""")]
|
|
for docstring, expected in docstrings:
|
|
config = Config()
|
|
app = mock.Mock()
|
|
actual = str(NumpyDocstring(docstring, config, app, "method"))
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_xrefs_in_return_type(self):
|
|
docstring = """
|
|
Example Function
|
|
|
|
Returns
|
|
-------
|
|
:class:`numpy.ndarray`
|
|
A :math:`n \\times 2` array containing
|
|
a bunch of math items
|
|
"""
|
|
expected = """
|
|
Example Function
|
|
|
|
:returns: A :math:`n \\times 2` array containing
|
|
a bunch of math items
|
|
:rtype: :class:`numpy.ndarray`
|
|
"""
|
|
config = Config()
|
|
app = mock.Mock()
|
|
actual = str(NumpyDocstring(docstring, config, app, "method"))
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_section_header_underline_length(self):
|
|
docstrings = [("""
|
|
Summary line
|
|
|
|
Example
|
|
-
|
|
Multiline example
|
|
body
|
|
|
|
""", """
|
|
Summary line
|
|
|
|
Example
|
|
-
|
|
Multiline example
|
|
body
|
|
"""),
|
|
################################
|
|
("""
|
|
Summary line
|
|
|
|
Example
|
|
--
|
|
Multiline example
|
|
body
|
|
|
|
""", """
|
|
Summary line
|
|
|
|
.. rubric:: Example
|
|
|
|
Multiline example
|
|
body
|
|
"""),
|
|
################################
|
|
("""
|
|
Summary line
|
|
|
|
Example
|
|
-------
|
|
Multiline example
|
|
body
|
|
|
|
""", """
|
|
Summary line
|
|
|
|
.. rubric:: Example
|
|
|
|
Multiline example
|
|
body
|
|
"""),
|
|
################################
|
|
("""
|
|
Summary line
|
|
|
|
Example
|
|
------------
|
|
Multiline example
|
|
body
|
|
|
|
""", """
|
|
Summary line
|
|
|
|
.. rubric:: Example
|
|
|
|
Multiline example
|
|
body
|
|
""")]
|
|
for docstring, expected in docstrings:
|
|
actual = str(NumpyDocstring(docstring))
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_list_in_parameter_description(self):
|
|
docstring = """One line summary.
|
|
|
|
Parameters
|
|
----------
|
|
no_list : int
|
|
one_bullet_empty : int
|
|
*
|
|
one_bullet_single_line : int
|
|
- first line
|
|
one_bullet_two_lines : int
|
|
+ first line
|
|
continued
|
|
two_bullets_single_line : int
|
|
- first line
|
|
- second line
|
|
two_bullets_two_lines : int
|
|
* first line
|
|
continued
|
|
* second line
|
|
continued
|
|
one_enumeration_single_line : int
|
|
1. first line
|
|
one_enumeration_two_lines : int
|
|
1) first line
|
|
continued
|
|
two_enumerations_one_line : int
|
|
(iii) first line
|
|
(iv) second line
|
|
two_enumerations_two_lines : int
|
|
a. first line
|
|
continued
|
|
b. second line
|
|
continued
|
|
one_definition_one_line : int
|
|
item 1
|
|
first line
|
|
one_definition_two_lines : int
|
|
item 1
|
|
first line
|
|
continued
|
|
two_definitions_one_line : int
|
|
item 1
|
|
first line
|
|
item 2
|
|
second line
|
|
two_definitions_two_lines : int
|
|
item 1
|
|
first line
|
|
continued
|
|
item 2
|
|
second line
|
|
continued
|
|
one_definition_blank_line : int
|
|
item 1
|
|
|
|
first line
|
|
|
|
extra first line
|
|
|
|
two_definitions_blank_lines : int
|
|
item 1
|
|
|
|
first line
|
|
|
|
extra first line
|
|
|
|
item 2
|
|
|
|
second line
|
|
|
|
extra second line
|
|
|
|
definition_after_normal_text : int
|
|
text line
|
|
|
|
item 1
|
|
first line
|
|
"""
|
|
|
|
expected = """One line summary.
|
|
|
|
:param no_list:
|
|
:type no_list: int
|
|
:param one_bullet_empty:
|
|
*
|
|
:type one_bullet_empty: int
|
|
:param one_bullet_single_line:
|
|
- first line
|
|
:type one_bullet_single_line: int
|
|
:param one_bullet_two_lines:
|
|
+ first line
|
|
continued
|
|
:type one_bullet_two_lines: int
|
|
:param two_bullets_single_line:
|
|
- first line
|
|
- second line
|
|
:type two_bullets_single_line: int
|
|
:param two_bullets_two_lines:
|
|
* first line
|
|
continued
|
|
* second line
|
|
continued
|
|
:type two_bullets_two_lines: int
|
|
:param one_enumeration_single_line:
|
|
1. first line
|
|
:type one_enumeration_single_line: int
|
|
:param one_enumeration_two_lines:
|
|
1) first line
|
|
continued
|
|
:type one_enumeration_two_lines: int
|
|
:param two_enumerations_one_line:
|
|
(iii) first line
|
|
(iv) second line
|
|
:type two_enumerations_one_line: int
|
|
:param two_enumerations_two_lines:
|
|
a. first line
|
|
continued
|
|
b. second line
|
|
continued
|
|
:type two_enumerations_two_lines: int
|
|
:param one_definition_one_line:
|
|
item 1
|
|
first line
|
|
:type one_definition_one_line: int
|
|
:param one_definition_two_lines:
|
|
item 1
|
|
first line
|
|
continued
|
|
:type one_definition_two_lines: int
|
|
:param two_definitions_one_line:
|
|
item 1
|
|
first line
|
|
item 2
|
|
second line
|
|
:type two_definitions_one_line: int
|
|
:param two_definitions_two_lines:
|
|
item 1
|
|
first line
|
|
continued
|
|
item 2
|
|
second line
|
|
continued
|
|
:type two_definitions_two_lines: int
|
|
:param one_definition_blank_line:
|
|
item 1
|
|
|
|
first line
|
|
|
|
extra first line
|
|
:type one_definition_blank_line: int
|
|
:param two_definitions_blank_lines:
|
|
item 1
|
|
|
|
first line
|
|
|
|
extra first line
|
|
|
|
item 2
|
|
|
|
second line
|
|
|
|
extra second line
|
|
:type two_definitions_blank_lines: int
|
|
:param definition_after_normal_text: text line
|
|
|
|
item 1
|
|
first line
|
|
:type definition_after_normal_text: int
|
|
"""
|
|
config = Config(napoleon_use_param=True)
|
|
actual = str(NumpyDocstring(docstring, config))
|
|
self.assertEqual(expected, actual)
|
|
|
|
expected = """One line summary.
|
|
|
|
:Parameters: * **no_list** (*int*)
|
|
* **one_bullet_empty** (*int*) --
|
|
|
|
*
|
|
* **one_bullet_single_line** (*int*) --
|
|
|
|
- first line
|
|
* **one_bullet_two_lines** (*int*) --
|
|
|
|
+ first line
|
|
continued
|
|
* **two_bullets_single_line** (*int*) --
|
|
|
|
- first line
|
|
- second line
|
|
* **two_bullets_two_lines** (*int*) --
|
|
|
|
* first line
|
|
continued
|
|
* second line
|
|
continued
|
|
* **one_enumeration_single_line** (*int*) --
|
|
|
|
1. first line
|
|
* **one_enumeration_two_lines** (*int*) --
|
|
|
|
1) first line
|
|
continued
|
|
* **two_enumerations_one_line** (*int*) --
|
|
|
|
(iii) first line
|
|
(iv) second line
|
|
* **two_enumerations_two_lines** (*int*) --
|
|
|
|
a. first line
|
|
continued
|
|
b. second line
|
|
continued
|
|
* **one_definition_one_line** (*int*) --
|
|
|
|
item 1
|
|
first line
|
|
* **one_definition_two_lines** (*int*) --
|
|
|
|
item 1
|
|
first line
|
|
continued
|
|
* **two_definitions_one_line** (*int*) --
|
|
|
|
item 1
|
|
first line
|
|
item 2
|
|
second line
|
|
* **two_definitions_two_lines** (*int*) --
|
|
|
|
item 1
|
|
first line
|
|
continued
|
|
item 2
|
|
second line
|
|
continued
|
|
* **one_definition_blank_line** (*int*) --
|
|
|
|
item 1
|
|
|
|
first line
|
|
|
|
extra first line
|
|
* **two_definitions_blank_lines** (*int*) --
|
|
|
|
item 1
|
|
|
|
first line
|
|
|
|
extra first line
|
|
|
|
item 2
|
|
|
|
second line
|
|
|
|
extra second line
|
|
* **definition_after_normal_text** (*int*) -- text line
|
|
|
|
item 1
|
|
first line
|
|
"""
|
|
config = Config(napoleon_use_param=False)
|
|
actual = str(NumpyDocstring(docstring, config))
|
|
self.assertEqual(expected, actual)
|
|
|
|
def test_keywords_with_types(self):
|
|
docstring = """\
|
|
Do as you please
|
|
|
|
Keyword Args:
|
|
gotham_is_yours (None): shall interfere.
|
|
"""
|
|
actual = str(GoogleDocstring(docstring))
|
|
expected = """\
|
|
Do as you please
|
|
|
|
:keyword gotham_is_yours: shall interfere.
|
|
:kwtype gotham_is_yours: None
|
|
"""
|
|
self.assertEqual(expected, actual)
|