summaryrefslogtreecommitdiffstats
path: root/tests/test_ext_napoleon_docstring.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_ext_napoleon_docstring.py')
-rw-r--r--tests/test_ext_napoleon_docstring.py2660
1 files changed, 0 insertions, 2660 deletions
diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py
deleted file mode 100644
index 87fad61..0000000
--- a/tests/test_ext_napoleon_docstring.py
+++ /dev/null
@@ -1,2660 +0,0 @@
-"""Tests for :mod:`sphinx.ext.napoleon.docstring` module."""
-
-import re
-from collections import namedtuple
-from inspect import cleandoc
-from textwrap import dedent
-from unittest import mock
-
-import pytest
-
-from sphinx.ext.napoleon import Config
-from sphinx.ext.napoleon.docstring import (
- GoogleDocstring,
- NumpyDocstring,
- _convert_numpy_type_spec,
- _recombine_set_tokens,
- _token_type,
- _tokenize_type_spec,
-)
-
-from .ext_napoleon_pep526_data_google import PEP526GoogleClass
-from .ext_napoleon_pep526_data_numpy import PEP526NumpyClass
-
-
-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().__new__(cls, attr1, attr2)
-
-
-class TestNamedtupleSubclass:
- 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
-
- Quick description of attr1
-
- :type: Arbitrary type
-
-.. attribute:: attr2
-
- Quick description of attr2
-
- :type: Another arbitrary type
-
-.. attribute:: attr3
-
- Adds a newline after the type
-
- :type: Type
-"""
-
- assert expected == actual
-
-
-class TestInlineAttribute:
- inline_google_docstring = ('inline description with '
- '``a : in code``, '
- 'a :ref:`reference`, '
- 'a `link <https://foo.bar>`_, '
- 'a :meta public:, '
- 'a :meta field: value and '
- 'an host:port and HH:MM strings.')
-
- @staticmethod
- def _docstring(source):
- rst = GoogleDocstring(source, config=Config(), app=None, what='attribute', name='some_data', obj=0)
- return str(rst)
-
- def test_class_data_member(self):
- source = 'data member description:\n\n- a: b'
- actual = self._docstring(source).splitlines()
- assert actual == ['data member description:', '', '- a: b']
-
- def test_class_data_member_inline(self):
- source = f'CustomType: {self.inline_google_docstring}'
- actual = self._docstring(source).splitlines()
- assert actual == [self.inline_google_docstring, '', ':type: CustomType']
-
- def test_class_data_member_inline_no_type(self):
- source = self.inline_google_docstring
- actual = self._docstring(source).splitlines()
- assert actual == [source]
-
- def test_class_data_member_inline_ref_in_type(self):
- source = f':class:`int`: {self.inline_google_docstring}'
- actual = self._docstring(source).splitlines()
- assert actual == [self.inline_google_docstring, '', ':type: :class:`int`']
-
-
-class TestGoogleDocstring:
- 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
-
- Returns:
- Extended
- """,
- """
- Single line summary
-
- :returns: Extended
- """,
- ), (
- """
- 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
-
- Receive:
- arg1 (list(int)): Description
- arg2 (list[int]): Description
- """,
- """
- Single line summary
-
- :Receives: * **arg1** (*list(int)*) -- Description
- * **arg2** (*list[int]*) -- Description
- """,
- ), (
- """
- Single line summary
-
- Receives:
- arg1 (list(int)): Description
- arg2 (list[int]): Description
- """,
- """
- Single line summary
-
- :Receives: * **arg1** (*list(int)*) -- Description
- * **arg2** (*list[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
- """,
- ), (
- """
- Single line summary
-
- Args:
-
- arg1 (list of str): Extended
- description of arg1.
- arg2 (tuple of int): Extended
- description of arg2.
- arg3 (tuple of list of float): Extended
- description of arg3.
- arg4 (int, float, or list of bool): Extended
- description of arg4.
- arg5 (list of int, float, or bool): Extended
- description of arg5.
- arg6 (list of int or float): Extended
- description of arg6.
- """,
- """
- Single line summary
-
- :Parameters: * **arg1** (*list of str*) -- Extended
- description of arg1.
- * **arg2** (*tuple of int*) -- Extended
- description of arg2.
- * **arg3** (*tuple of list of float*) -- Extended
- description of arg3.
- * **arg4** (*int, float, or list of bool*) -- Extended
- description of arg4.
- * **arg5** (*list of int, float, or bool*) -- Extended
- description of arg5.
- * **arg6** (*list of int or float*) -- Extended
- description of arg6.
- """,
- )]
-
- def test_sphinx_admonitions(self):
- admonition_map = {
- 'Attention': 'attention',
- 'Caution': 'caution',
- 'Danger': 'danger',
- 'Error': 'error',
- 'Hint': 'hint',
- 'Important': 'important',
- 'Note': 'note',
- 'Tip': 'tip',
- 'Todo': 'todo',
- 'Warning': 'warning',
- 'Warnings': 'warning',
- }
- config = Config()
- for section, admonition in admonition_map.items():
- # Multiline
- actual = str(GoogleDocstring(f"{section}:\n"
- " this is the first line\n"
- "\n"
- " and this is the second line\n",
- config))
- expect = (f".. {admonition}::\n"
- "\n"
- " this is the first line\n"
- " \n"
- " and this is the second line\n"
- )
- assert expect == actual
-
- # Single line
- actual = str(GoogleDocstring(f"{section}:\n"
- " this is a single line\n",
- config))
- expect = f".. {admonition}:: this is a single line\n"
- assert expect == actual
-
- 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)
- assert 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:`~typing.Dict`\\[:class:`int`,:class:`str`\\]): 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:`~typing.Dict`\\[:class:`int`,:class:`str`\\]
-: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`
-"""
- assert 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
-
- super-dooper attribute
-
- :type: :class:`numpy.ndarray`
-"""
- assert expected == actual
-
- docstring = """\
-Attributes:
- in_attr(numpy.ndarray): super-dooper attribute
-"""
-
- actual = str(GoogleDocstring(docstring))
- expected = """\
-.. attribute:: in_attr
-
- super-dooper attribute
-
- :type: numpy.ndarray
-"""
-
- def test_attributes_with_use_ivar(self):
- docstring = """\
-Attributes:
- foo (int): blah blah
- bar (str): blah blah
-"""
-
- config = Config(napoleon_use_ivar=True)
- actual = str(GoogleDocstring(docstring, config, obj=self.__class__))
- expected = """\
-:ivar foo: blah blah
-:vartype foo: int
-:ivar bar: blah blah
-:vartype bar: str
-"""
- assert 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))
- assert 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))
- assert 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))
- assert 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.
- :py:class:`AttributeError`
- errors for missing attributes.
- ~InvalidDimensionsError
- If the dimensions couldn't be parsed.
- `InvalidArgumentsError`
- If the arguments are invalid.
- :exc:`~ValueError`
- If the arguments are wrong.
-
-""", """
-Example Function
-
-:raises RuntimeError: A setting wasn't specified, or was invalid.
-:raises ValueError: Something something value error.
-:raises AttributeError: errors for missing attributes.
-:raises ~InvalidDimensionsError: If the dimensions couldn't be parsed.
-:raises InvalidArgumentsError: If the arguments are invalid.
-:raises ~ValueError: If the arguments are wrong.
-"""),
- ################################
- ("""
-Example Function
-
-Raises:
- InvalidDimensionsError
-
-""", """
-Example Function
-
-:raises 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 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 exc.InvalidDimensionsError:
-"""),
- ################################
- ("""
-Example Function
-
-Raises:
- :class:`exc.InvalidDimensionsError`: If the dimensions couldn't be parsed.
-
-""", """
-Example Function
-
-:raises 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 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 exc.InvalidDimensionsError: If the dimensions couldn't be parsed.
-:raises exc.InvalidArgumentsError: If the arguments are invalid.
-"""),
- ################################
- ("""
-Example Function
-
-Raises:
- :class:`exc.InvalidDimensionsError`
- :class:`exc.InvalidArgumentsError`
-
-""", """
-Example Function
-
-:raises exc.InvalidDimensionsError:
-:raises exc.InvalidArgumentsError:
-""")]
- for docstring, expected in docstrings:
- actual = str(GoogleDocstring(docstring))
- assert 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))
- assert 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))
- assert 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))
- assert 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))
- assert expected == actual
-
- def test_custom_generic_sections(self):
-
- docstrings = (("""\
-Really Important Details:
- You should listen to me!
-""", """.. rubric:: Really Important Details
-
-You should listen to me!
-"""),
- ("""\
-Sooper Warning:
- Stop hitting yourself!
-""", """:Warns: **Stop hitting yourself!**
-"""),
- ("""\
-Params Style:
- arg1 (int): Description of arg1
- arg2 (str): Description of arg2
-
-""", """\
-:Params Style: * **arg1** (*int*) -- Description of arg1
- * **arg2** (*str*) -- Description of arg2
-"""),
- ("""\
-Returns Style:
- description of custom section
-
-""", """:Returns Style: description of custom section
-"""))
-
- testConfig = Config(napoleon_custom_sections=['Really Important Details',
- ('Sooper Warning', 'warns'),
- ('Params Style', 'params_style'),
- ('Returns Style', 'returns_style')])
-
- for docstring, expected in docstrings:
- actual = str(GoogleDocstring(docstring, testConfig))
- assert expected == actual
-
- def test_noindex(self):
- docstring = """
-Attributes:
- arg
- description
-
-Methods:
- func(i, j)
- description
-"""
-
- expected = """
-.. attribute:: arg
- :no-index:
-
- description
-
-.. method:: func(i, j)
- :no-index:
-
-
- description
-""" # noqa: W293
- config = Config()
- actual = str(GoogleDocstring(docstring, config=config, app=None, what='module',
- options={'no-index': True}))
- assert 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
-"""
- assert expected == actual
-
- def test_pep526_annotations(self):
- # Test class attributes annotations
- config = Config(
- napoleon_attr_annotations=True,
- )
- actual = str(GoogleDocstring(cleandoc(PEP526GoogleClass.__doc__), config, app=None, what="class",
- obj=PEP526GoogleClass))
- expected = """\
-Sample class with PEP 526 annotations and google docstring
-
-.. attribute:: attr1
-
- Attr1 description.
-
- :type: int
-
-.. attribute:: attr2
-
- Attr2 description.
-
- :type: str
-"""
- assert expected == actual
-
- def test_preprocess_types(self):
- docstring = """\
-Do as you please
-
-Yield:
- str:Extended
-"""
- actual = str(GoogleDocstring(docstring))
- expected = """\
-Do as you please
-
-:Yields: *str* -- Extended
-"""
- assert expected == actual
-
- config = Config(napoleon_preprocess_types=True)
- actual = str(GoogleDocstring(docstring, config))
- expected = """\
-Do as you please
-
-:Yields: :py:class:`str` -- Extended
-"""
- assert expected == actual
-
-
-class TestNumpyDocstring:
- 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** (:class:`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** (:class:`str`) -- Extended
- description of arg1
- * **arg2** (:class:`int`) -- Extended
- description of arg2
-
- :Keyword Arguments: * **kwarg1** (:class:`str`) -- Extended
- description of kwarg1
- * **kwarg2** (:class:`int`) -- Extended
- description of kwarg2
- """,
- ), (
- """
- Single line summary
-
- Return
- ------
- str
- Extended
- description of return value
- """,
- """
- Single line summary
-
- :returns: :class:`str` -- Extended
- description of return value
- """,
- ), (
- """
- Single line summary
-
- Returns
- -------
- str
- Extended
- description of return value
- """,
- """
- Single line summary
-
- :returns: :class:`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** (:class:`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, **kwargs:
- Variable length argument list and arbitrary keyword arguments.
- """,
- """
- Single line summary
-
- :Parameters: * **arg1** (:class:`str`) -- Extended description of arg1
- * **\\*args, \\*\\*kwargs** -- Variable length argument list and arbitrary keyword arguments.
- """,
- ), (
- """
- Single line summary
-
- Receive
- -------
- arg1:str
- Extended
- description of arg1
- arg2 : int
- Extended
- description of arg2
- """,
- """
- Single line summary
-
- :Receives: * **arg1** (:class:`str`) -- Extended
- description of arg1
- * **arg2** (:class:`int`) -- Extended
- description of arg2
- """,
- ), (
- """
- Single line summary
-
- Receives
- --------
- arg1:str
- Extended
- description of arg1
- arg2 : int
- Extended
- description of arg2
- """,
- """
- Single line summary
-
- :Receives: * **arg1** (:class:`str`) -- Extended
- description of arg1
- * **arg2** (:class:`int`) -- Extended
- description of arg2
- """,
- ), (
- """
- Single line summary
-
- Yield
- -----
- str
- Extended
- description of yielded value
- """,
- """
- Single line summary
-
- :Yields: :class:`str` -- Extended
- description of yielded value
- """,
- ), (
- """
- Single line summary
-
- Yields
- ------
- str
- Extended
- description of yielded value
- """,
- """
- Single line summary
-
- :Yields: :class:`str` -- Extended
- description of yielded value
- """,
- )]
-
- def test_sphinx_admonitions(self):
- admonition_map = {
- 'Attention': 'attention',
- 'Caution': 'caution',
- 'Danger': 'danger',
- 'Error': 'error',
- 'Hint': 'hint',
- 'Important': 'important',
- 'Note': 'note',
- 'Tip': 'tip',
- 'Todo': 'todo',
- 'Warning': 'warning',
- 'Warnings': 'warning',
- }
- config = Config()
- for section, admonition in admonition_map.items():
- # Multiline
- actual = str(NumpyDocstring(f"{section}\n"
- f"{'-' * len(section)}\n"
- " this is the first line\n"
- "\n"
- " and this is the second line\n",
- config))
- expect = (f".. {admonition}::\n"
- "\n"
- " this is the first line\n"
- " \n"
- " and this is the second line\n"
- )
- assert expect == actual
-
- # Single line
- actual = str(NumpyDocstring(f"{section}\n"
- f"{'-' * len(section)}\n"
- f" this is a single line\n",
- config))
- expect = f".. {admonition}:: this is a single line\n"
- assert expect == actual
-
- def test_docstrings(self):
- config = Config(
- napoleon_use_param=False,
- napoleon_use_rtype=False,
- napoleon_use_keyword=False,
- napoleon_preprocess_types=True)
- for docstring, expected in self.docstrings:
- actual = str(NumpyDocstring(dedent(docstring), config))
- expected = dedent(expected)
- assert expected == actual
-
- def test_type_preprocessor(self):
- docstring = dedent("""
- Single line summary
-
- Parameters
- ----------
- arg1:str
- Extended
- description of arg1
- """)
-
- config = Config(napoleon_preprocess_types=False, napoleon_use_param=False)
- actual = str(NumpyDocstring(docstring, config))
- expected = dedent("""
- Single line summary
-
- :Parameters: **arg1** (*str*) -- Extended
- description of arg1
- """)
- assert expected == actual
-
- def test_parameters_with_class_reference(self):
- docstring = """\
-Parameters
-----------
-param1 : :class:`MyClass <name.space.MyClass>` instance
-
-Other Parameters
-----------------
-param2 : :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)
-
-:Other Parameters: **param2** (:class:`MyClass <name.space.MyClass>` instance)
-"""
- assert expected == actual
-
- config = Config(napoleon_use_param=True)
- actual = str(NumpyDocstring(docstring, config))
- expected = """\
-:param param1:
-:type param1: :class:`MyClass <name.space.MyClass>` instance
-
-:param param2:
-:type param2: :class:`MyClass <name.space.MyClass>` instance
-"""
- assert expected == actual
-
- def test_multiple_parameters(self):
- docstring = """\
-Parameters
-----------
-x1, x2 : array_like
- Input arrays, description of ``x1``, ``x2``.
-
-"""
-
- config = Config(napoleon_use_param=False)
- actual = str(NumpyDocstring(docstring, config))
- expected = """\
-:Parameters: **x1, x2** (*array_like*) -- Input arrays, description of ``x1``, ``x2``.
-"""
- assert expected == actual
-
- config = Config(napoleon_use_param=True)
- actual = str(NumpyDocstring(dedent(docstring), config))
- expected = """\
-:param x1: Input arrays, description of ``x1``, ``x2``.
-:type x1: array_like
-:param x2: Input arrays, description of ``x1``, ``x2``.
-:type x2: array_like
-"""
- assert 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*)
-"""
- assert expected == actual
-
- config = Config(napoleon_use_param=True)
- actual = str(NumpyDocstring(dedent(docstring), config))
- expected = """\
-:param param1:
-:type param1: MyClass instance
-"""
- assert 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
-"""
- assert 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::
-
- :obj:`some`, :obj:`other`, :obj:`funcs`
- \n\
- :obj:`otherfunc`
- relationship
-"""
- assert expected == actual
-
- docstring = """\
-numpy.multivariate_normal(mean, cov, shape=None, spam=None)
-
-See Also
---------
-some, other, :func:`funcs`
-otherfunc : relationship
-
-"""
- translations = {
- "other": "MyClass.other",
- "otherfunc": ":func:`~my_package.otherfunc`",
- }
- config = Config(napoleon_type_aliases=translations)
- app = mock.Mock()
- actual = str(NumpyDocstring(docstring, config, app, "method"))
-
- expected = """\
-numpy.multivariate_normal(mean, cov, shape=None, spam=None)
-
-.. seealso::
-
- :obj:`some`, :obj:`MyClass.other`, :func:`funcs`
- \n\
- :func:`~my_package.otherfunc`
- relationship
-"""
- assert 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"))
-
- assert 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"))
-
- assert expected == actual
-
- def test_underscore_in_attribute_strip_signature_backslash(self):
- docstring = """
-Attributes
-----------
-
-arg_ : type
- some description
-"""
-
- expected = """
-:ivar arg\\_: some description
-:vartype arg\\_: type
-"""
-
- config = Config(napoleon_use_ivar=True)
- config.strip_signature_backslash = True
- app = mock.Mock()
- actual = str(NumpyDocstring(docstring, config, app, "class"))
-
- assert expected == actual
-
- def test_return_types(self):
- docstring = dedent("""
- Returns
- -------
- DataFrame
- a dataframe
- """)
- expected = dedent("""
- :returns: a dataframe
- :rtype: :class:`~pandas.DataFrame`
- """)
- translations = {
- "DataFrame": "~pandas.DataFrame",
- }
- config = Config(
- napoleon_use_param=True,
- napoleon_use_rtype=True,
- napoleon_preprocess_types=True,
- napoleon_type_aliases=translations,
- )
- actual = str(NumpyDocstring(docstring, config))
- assert expected == actual
-
- def test_yield_types(self):
- docstring = dedent("""
- Example Function
-
- Yields
- ------
- scalar or array-like
- The result of the computation
- """)
- expected = dedent("""
- Example Function
-
- :Yields: :term:`scalar` or :class:`array-like <numpy.ndarray>` -- The result of the computation
- """)
- translations = {
- "scalar": ":term:`scalar`",
- "array-like": ":class:`array-like <numpy.ndarray>`",
- }
- config = Config(napoleon_type_aliases=translations, napoleon_preprocess_types=True)
- app = mock.Mock()
- actual = str(NumpyDocstring(docstring, config, app, "method"))
- assert 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 RuntimeError: A setting wasn't specified, or was invalid.
-:raises ValueError: Something something value error.
-"""),
- ################################
- ("""
-Example Function
-
-Raises
-------
-InvalidDimensionsError
-
-""", """
-Example Function
-
-:raises 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 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 exc.InvalidDimensionsError:
-"""),
- ################################
- ("""
-Example Function
-
-Raises
-------
-:class:`exc.InvalidDimensionsError`
- If the dimensions couldn't be parsed.
-
-""", """
-Example Function
-
-:raises 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 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 exc.InvalidDimensionsError: If the dimensions couldn't be parsed.
-:raises exc.InvalidArgumentsError: If the arguments are invalid.
-"""),
- ################################
- ("""
-Example Function
-
-Raises
-------
-CustomError
- If the dimensions couldn't be parsed.
-
-""", """
-Example Function
-
-:raises package.CustomError: If the dimensions couldn't be parsed.
-"""),
- ################################
- ("""
-Example Function
-
-Raises
-------
-AnotherError
- If the dimensions couldn't be parsed.
-
-""", """
-Example Function
-
-:raises ~package.AnotherError: If the dimensions couldn't be parsed.
-"""),
- ################################
- ("""
-Example Function
-
-Raises
-------
-:class:`exc.InvalidDimensionsError`
-:class:`exc.InvalidArgumentsError`
-
-""", """
-Example Function
-
-:raises exc.InvalidDimensionsError:
-:raises exc.InvalidArgumentsError:
-""")]
- for docstring, expected in docstrings:
- translations = {
- "CustomError": "package.CustomError",
- "AnotherError": ":py:exc:`~package.AnotherError`",
- }
- config = Config(napoleon_type_aliases=translations, napoleon_preprocess_types=True)
- app = mock.Mock()
- actual = str(NumpyDocstring(docstring, config, app, "method"))
- assert 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"))
- assert 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))
- assert 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))
- assert expected == actual
-
- expected = """One line summary.
-
-:Parameters: * **no_list** (:class:`int`)
- * **one_bullet_empty** (:class:`int`) --
-
- *
- * **one_bullet_single_line** (:class:`int`) --
-
- - first line
- * **one_bullet_two_lines** (:class:`int`) --
-
- + first line
- continued
- * **two_bullets_single_line** (:class:`int`) --
-
- - first line
- - second line
- * **two_bullets_two_lines** (:class:`int`) --
-
- * first line
- continued
- * second line
- continued
- * **one_enumeration_single_line** (:class:`int`) --
-
- 1. first line
- * **one_enumeration_two_lines** (:class:`int`) --
-
- 1) first line
- continued
- * **two_enumerations_one_line** (:class:`int`) --
-
- (iii) first line
- (iv) second line
- * **two_enumerations_two_lines** (:class:`int`) --
-
- a. first line
- continued
- b. second line
- continued
- * **one_definition_one_line** (:class:`int`) --
-
- item 1
- first line
- * **one_definition_two_lines** (:class:`int`) --
-
- item 1
- first line
- continued
- * **two_definitions_one_line** (:class:`int`) --
-
- item 1
- first line
- item 2
- second line
- * **two_definitions_two_lines** (:class:`int`) --
-
- item 1
- first line
- continued
- item 2
- second line
- continued
- * **one_definition_blank_line** (:class:`int`) --
-
- item 1
-
- first line
-
- extra first line
- * **two_definitions_blank_lines** (:class:`int`) --
-
- item 1
-
- first line
-
- extra first line
-
- item 2
-
- second line
-
- extra second line
- * **definition_after_normal_text** (:class:`int`) -- text line
-
- item 1
- first line
-"""
- config = Config(napoleon_use_param=False, napoleon_preprocess_types=True)
- actual = str(NumpyDocstring(docstring, config))
- assert expected == actual
-
- def test_token_type(self):
- tokens = (
- ("1", "literal"),
- ("-4.6", "literal"),
- ("2j", "literal"),
- ("'string'", "literal"),
- ('"another_string"', "literal"),
- ("{1, 2}", "literal"),
- ("{'va{ue', 'set'}", "literal"),
- ("optional", "control"),
- ("default", "control"),
- (", ", "delimiter"),
- (" of ", "delimiter"),
- (" or ", "delimiter"),
- (": ", "delimiter"),
- ("True", "obj"),
- ("None", "obj"),
- ("name", "obj"),
- (":py:class:`Enum`", "reference"),
- )
-
- for token, expected in tokens:
- actual = _token_type(token)
- assert expected == actual
-
- def test_tokenize_type_spec(self):
- specs = (
- "str",
- "defaultdict",
- "int, float, or complex",
- "int or float or None, optional",
- "list of list of int or float, optional",
- "tuple of list of str, float, or int",
- '{"F", "C", "N"}',
- "{'F', 'C', 'N'}, default: 'F'",
- "{'F', 'C', 'N or C'}, default 'F'",
- "str, default: 'F or C'",
- "int, default: None",
- "int, default None",
- "int, default :obj:`None`",
- '"ma{icious"',
- r"'with \'quotes\''",
- )
-
- tokens = (
- ["str"],
- ["defaultdict"],
- ["int", ", ", "float", ", or ", "complex"],
- ["int", " or ", "float", " or ", "None", ", ", "optional"],
- ["list", " of ", "list", " of ", "int", " or ", "float", ", ", "optional"],
- ["tuple", " of ", "list", " of ", "str", ", ", "float", ", or ", "int"],
- ["{", '"F"', ", ", '"C"', ", ", '"N"', "}"],
- ["{", "'F'", ", ", "'C'", ", ", "'N'", "}", ", ", "default", ": ", "'F'"],
- ["{", "'F'", ", ", "'C'", ", ", "'N or C'", "}", ", ", "default", " ", "'F'"],
- ["str", ", ", "default", ": ", "'F or C'"],
- ["int", ", ", "default", ": ", "None"],
- ["int", ", ", "default", " ", "None"],
- ["int", ", ", "default", " ", ":obj:`None`"],
- ['"ma{icious"'],
- [r"'with \'quotes\''"],
- )
-
- for spec, expected in zip(specs, tokens):
- actual = _tokenize_type_spec(spec)
- assert expected == actual
-
- def test_recombine_set_tokens(self):
- tokens = (
- ["{", "1", ", ", "2", "}"],
- ["{", '"F"', ", ", '"C"', ", ", '"N"', "}", ", ", "optional"],
- ["{", "'F'", ", ", "'C'", ", ", "'N'", "}", ", ", "default", ": ", "None"],
- ["{", "'F'", ", ", "'C'", ", ", "'N'", "}", ", ", "default", " ", "None"],
- )
-
- combined_tokens = (
- ["{1, 2}"],
- ['{"F", "C", "N"}', ", ", "optional"],
- ["{'F', 'C', 'N'}", ", ", "default", ": ", "None"],
- ["{'F', 'C', 'N'}", ", ", "default", " ", "None"],
- )
-
- for tokens_, expected in zip(tokens, combined_tokens):
- actual = _recombine_set_tokens(tokens_)
- assert expected == actual
-
- def test_recombine_set_tokens_invalid(self):
- tokens = (
- ["{", "1", ", ", "2"],
- ['"F"', ", ", '"C"', ", ", '"N"', "}", ", ", "optional"],
- ["{", "1", ", ", "2", ", ", "default", ": ", "None"],
- )
- combined_tokens = (
- ["{1, 2"],
- ['"F"', ", ", '"C"', ", ", '"N"', "}", ", ", "optional"],
- ["{1, 2", ", ", "default", ": ", "None"],
- )
-
- for tokens_, expected in zip(tokens, combined_tokens):
- actual = _recombine_set_tokens(tokens_)
- assert expected == actual
-
- def test_convert_numpy_type_spec(self):
- translations = {
- "DataFrame": "pandas.DataFrame",
- }
-
- specs = (
- "",
- "optional",
- "str, optional",
- "int or float or None, default: None",
- "list of tuple of str, optional",
- "int, default None",
- '{"F", "C", "N"}',
- "{'F', 'C', 'N'}, default: 'N'",
- "{'F', 'C', 'N'}, default 'N'",
- "DataFrame, optional",
- )
-
- converted = (
- "",
- "*optional*",
- ":class:`str`, *optional*",
- ":class:`int` or :class:`float` or :obj:`None`, *default*: :obj:`None`",
- ":class:`list` of :class:`tuple` of :class:`str`, *optional*",
- ":class:`int`, *default* :obj:`None`",
- '``{"F", "C", "N"}``',
- "``{'F', 'C', 'N'}``, *default*: ``'N'``",
- "``{'F', 'C', 'N'}``, *default* ``'N'``",
- ":class:`pandas.DataFrame`, *optional*",
- )
-
- for spec, expected in zip(specs, converted):
- actual = _convert_numpy_type_spec(spec, translations=translations)
- assert expected == actual
-
- def test_parameter_types(self):
- docstring = dedent("""\
- Parameters
- ----------
- param1 : DataFrame
- the data to work on
- param2 : int or float or None, optional
- a parameter with different types
- param3 : dict-like, optional
- a optional mapping
- param4 : int or float or None, optional
- a optional parameter with different types
- param5 : {"F", "C", "N"}, optional
- a optional parameter with fixed values
- param6 : int, default None
- different default format
- param7 : mapping of hashable to str, optional
- a optional mapping
- param8 : ... or Ellipsis
- ellipsis
- param9 : tuple of list of int
- a parameter with tuple of list of int
- """)
- expected = dedent("""\
- :param param1: the data to work on
- :type param1: :class:`DataFrame`
- :param param2: a parameter with different types
- :type param2: :class:`int` or :class:`float` or :obj:`None`, *optional*
- :param param3: a optional mapping
- :type param3: :term:`dict-like <mapping>`, *optional*
- :param param4: a optional parameter with different types
- :type param4: :class:`int` or :class:`float` or :obj:`None`, *optional*
- :param param5: a optional parameter with fixed values
- :type param5: ``{"F", "C", "N"}``, *optional*
- :param param6: different default format
- :type param6: :class:`int`, *default* :obj:`None`
- :param param7: a optional mapping
- :type param7: :term:`mapping` of :term:`hashable` to :class:`str`, *optional*
- :param param8: ellipsis
- :type param8: :obj:`... <Ellipsis>` or :obj:`Ellipsis`
- :param param9: a parameter with tuple of list of int
- :type param9: :class:`tuple` of :class:`list` of :class:`int`
- """)
- translations = {
- "dict-like": ":term:`dict-like <mapping>`",
- "mapping": ":term:`mapping`",
- "hashable": ":term:`hashable`",
- }
- config = Config(
- napoleon_use_param=True,
- napoleon_use_rtype=True,
- napoleon_preprocess_types=True,
- napoleon_type_aliases=translations,
- )
- actual = str(NumpyDocstring(docstring, config))
- assert expected == actual
-
- def test_token_type_invalid(self, warning):
- tokens = (
- "{1, 2",
- "}",
- "'abc",
- "def'",
- '"ghi',
- 'jkl"',
- )
- errors = (
- r".+: invalid value set \(missing closing brace\):",
- r".+: invalid value set \(missing opening brace\):",
- r".+: malformed string literal \(missing closing quote\):",
- r".+: malformed string literal \(missing opening quote\):",
- r".+: malformed string literal \(missing closing quote\):",
- r".+: malformed string literal \(missing opening quote\):",
- )
- for token, error in zip(tokens, errors):
- try:
- _token_type(token)
- finally:
- raw_warnings = warning.getvalue()
- warnings = [w for w in raw_warnings.split("\n") if w.strip()]
-
- assert len(warnings) == 1
- assert re.compile(error).match(warnings[0])
- warning.truncate(0)
-
- @pytest.mark.parametrize(
- ("name", "expected"),
- [
- ("x, y, z", "x, y, z"),
- ("*args, **kwargs", r"\*args, \*\*kwargs"),
- ("*x, **y", r"\*x, \*\*y"),
- ],
- )
- def test_escape_args_and_kwargs(self, name, expected):
- numpy_docstring = NumpyDocstring("")
- actual = numpy_docstring._escape_args_and_kwargs(name)
-
- assert actual == expected
-
- def test_pep526_annotations(self):
- # test class attributes annotations
- config = Config(
- napoleon_attr_annotations=True,
- )
- actual = str(NumpyDocstring(cleandoc(PEP526NumpyClass.__doc__), config, app=None, what="class",
- obj=PEP526NumpyClass))
- expected = """\
-Sample class with PEP 526 annotations and numpy docstring
-
-.. attribute:: attr1
-
- Attr1 description
-
- :type: int
-
-.. attribute:: attr2
-
- Attr2 description
-
- :type: str
-"""
- print(actual)
- assert expected == actual
-
-
-@pytest.mark.sphinx('text', testroot='ext-napoleon',
- confoverrides={'autodoc_typehints': 'description',
- 'autodoc_typehints_description_target': 'all'})
-def test_napoleon_and_autodoc_typehints_description_all(app, status, warning):
- app.build()
- content = (app.outdir / 'typehints.txt').read_text(encoding='utf-8')
- assert content == (
- 'typehints\n'
- '*********\n'
- '\n'
- 'mypackage.typehints.hello(x, *args, **kwargs)\n'
- '\n'
- ' Parameters:\n'
- ' * **x** (*int*) -- X\n'
- '\n'
- ' * ***args** (*int*) -- Additional arguments.\n'
- '\n'
- ' * ****kwargs** (*int*) -- Extra arguments.\n'
- '\n'
- ' Return type:\n'
- ' None\n'
- )
-
-
-@pytest.mark.sphinx('text', testroot='ext-napoleon',
- confoverrides={'autodoc_typehints': 'description',
- 'autodoc_typehints_description_target': 'documented_params'})
-def test_napoleon_and_autodoc_typehints_description_documented_params(app, status, warning):
- app.build()
- content = (app.outdir / 'typehints.txt').read_text(encoding='utf-8')
- assert content == (
- 'typehints\n'
- '*********\n'
- '\n'
- 'mypackage.typehints.hello(x, *args, **kwargs)\n'
- '\n'
- ' Parameters:\n'
- ' * **x** (*int*) -- X\n'
- '\n'
- ' * ***args** (*int*) -- Additional arguments.\n'
- '\n'
- ' * ****kwargs** (*int*) -- Extra arguments.\n'
- )