diff options
Diffstat (limited to 'tests/test_ext_napoleon_docstring.py')
-rw-r--r-- | tests/test_ext_napoleon_docstring.py | 2660 |
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' - ) |