structure saas with tools
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Tests for docstring parser."""
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,22 @@
|
||||
"""Private pydoctor customization code in order to exclude the package
|
||||
docstring_parser.tests from the API documentation. Based on Twisted code.
|
||||
"""
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
|
||||
try:
|
||||
from pydoctor.model import Documentable, PrivacyClass, System
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
|
||||
class HidesTestsPydoctorSystem(System):
|
||||
"""A PyDoctor "system" used to generate the docs."""
|
||||
|
||||
def privacyClass(self, documentable: Documentable) -> PrivacyClass:
|
||||
"""Report the privacy level for an object. Hide the module
|
||||
'docstring_parser.tests'.
|
||||
"""
|
||||
if documentable.fullName().startswith("docstring_parser.tests"):
|
||||
return PrivacyClass.HIDDEN
|
||||
return super().privacyClass(documentable)
|
||||
@@ -0,0 +1,723 @@
|
||||
"""Tests for epydoc-style docstring routines."""
|
||||
import typing as T
|
||||
|
||||
import pytest
|
||||
from docstring_parser.common import ParseError, RenderingStyle
|
||||
from docstring_parser.epydoc import compose, parse
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected",
|
||||
[
|
||||
("", None),
|
||||
("\n", None),
|
||||
("Short description", "Short description"),
|
||||
("\nShort description\n", "Short description"),
|
||||
("\n Short description\n", "Short description"),
|
||||
],
|
||||
)
|
||||
def test_short_description(source: str, expected: str) -> None:
|
||||
"""Test parsing short description."""
|
||||
docstring = parse(source)
|
||||
assert docstring.short_description == expected
|
||||
assert docstring.long_description is None
|
||||
assert not docstring.meta
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected_short_desc, expected_long_desc, expected_blank",
|
||||
[
|
||||
(
|
||||
"Short description\n\nLong description",
|
||||
"Short description",
|
||||
"Long description",
|
||||
True,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Long description
|
||||
""",
|
||||
"Short description",
|
||||
"Long description",
|
||||
True,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Long description
|
||||
Second line
|
||||
""",
|
||||
"Short description",
|
||||
"Long description\nSecond line",
|
||||
True,
|
||||
),
|
||||
(
|
||||
"Short description\nLong description",
|
||||
"Short description",
|
||||
"Long description",
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
""",
|
||||
"Short description",
|
||||
"Long description",
|
||||
False,
|
||||
),
|
||||
(
|
||||
"\nShort description\nLong description\n",
|
||||
"Short description",
|
||||
"Long description",
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
Second line
|
||||
""",
|
||||
"Short description",
|
||||
"Long description\nSecond line",
|
||||
False,
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_long_description(
|
||||
source: str,
|
||||
expected_short_desc: str,
|
||||
expected_long_desc: str,
|
||||
expected_blank: bool,
|
||||
) -> None:
|
||||
"""Test parsing long description."""
|
||||
docstring = parse(source)
|
||||
assert docstring.short_description == expected_short_desc
|
||||
assert docstring.long_description == expected_long_desc
|
||||
assert docstring.blank_after_short_description == expected_blank
|
||||
assert not docstring.meta
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected_short_desc, expected_long_desc, "
|
||||
"expected_blank_short_desc, expected_blank_long_desc",
|
||||
[
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
@meta: asd
|
||||
""",
|
||||
"Short description",
|
||||
None,
|
||||
False,
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
@meta: asd
|
||||
""",
|
||||
"Short description",
|
||||
"Long description",
|
||||
False,
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
First line
|
||||
Second line
|
||||
@meta: asd
|
||||
""",
|
||||
"Short description",
|
||||
"First line\n Second line",
|
||||
False,
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
First line
|
||||
Second line
|
||||
@meta: asd
|
||||
""",
|
||||
"Short description",
|
||||
"First line\n Second line",
|
||||
True,
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
First line
|
||||
Second line
|
||||
|
||||
@meta: asd
|
||||
""",
|
||||
"Short description",
|
||||
"First line\n Second line",
|
||||
True,
|
||||
True,
|
||||
),
|
||||
(
|
||||
"""
|
||||
@meta: asd
|
||||
""",
|
||||
None,
|
||||
None,
|
||||
False,
|
||||
False,
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_meta_newlines(
|
||||
source: str,
|
||||
expected_short_desc: T.Optional[str],
|
||||
expected_long_desc: T.Optional[str],
|
||||
expected_blank_short_desc: bool,
|
||||
expected_blank_long_desc: bool,
|
||||
) -> None:
|
||||
"""Test parsing newlines around description sections."""
|
||||
docstring = parse(source)
|
||||
assert docstring.short_description == expected_short_desc
|
||||
assert docstring.long_description == expected_long_desc
|
||||
assert docstring.blank_after_short_description == expected_blank_short_desc
|
||||
assert docstring.blank_after_long_description == expected_blank_long_desc
|
||||
assert len(docstring.meta) == 1
|
||||
|
||||
|
||||
def test_meta_with_multiline_description() -> None:
|
||||
"""Test parsing multiline meta documentation."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
@meta: asd
|
||||
1
|
||||
2
|
||||
3
|
||||
"""
|
||||
)
|
||||
assert docstring.short_description == "Short description"
|
||||
assert len(docstring.meta) == 1
|
||||
assert docstring.meta[0].args == ["meta"]
|
||||
assert docstring.meta[0].description == "asd\n1\n 2\n3"
|
||||
|
||||
|
||||
def test_multiple_meta() -> None:
|
||||
"""Test parsing multiple meta."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
@meta1: asd
|
||||
1
|
||||
2
|
||||
3
|
||||
@meta2: herp
|
||||
@meta3: derp
|
||||
"""
|
||||
)
|
||||
assert docstring.short_description == "Short description"
|
||||
assert len(docstring.meta) == 3
|
||||
assert docstring.meta[0].args == ["meta1"]
|
||||
assert docstring.meta[0].description == "asd\n1\n 2\n3"
|
||||
assert docstring.meta[1].args == ["meta2"]
|
||||
assert docstring.meta[1].description == "herp"
|
||||
assert docstring.meta[2].args == ["meta3"]
|
||||
assert docstring.meta[2].description == "derp"
|
||||
|
||||
|
||||
def test_meta_with_args() -> None:
|
||||
"""Test parsing meta with additional arguments."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
@meta ene due rabe: asd
|
||||
"""
|
||||
)
|
||||
assert docstring.short_description == "Short description"
|
||||
assert len(docstring.meta) == 1
|
||||
assert docstring.meta[0].args == ["meta", "ene", "due", "rabe"]
|
||||
assert docstring.meta[0].description == "asd"
|
||||
|
||||
|
||||
def test_params() -> None:
|
||||
"""Test parsing params."""
|
||||
docstring = parse("Short description")
|
||||
assert len(docstring.params) == 0
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
@param name: description 1
|
||||
@param priority: description 2
|
||||
@type priority: int
|
||||
@param sender: description 3
|
||||
@type sender: str?
|
||||
@param message: description 4, defaults to 'hello'
|
||||
@type message: str?
|
||||
@param multiline: long description 5,
|
||||
defaults to 'bye'
|
||||
@type multiline: str?
|
||||
"""
|
||||
)
|
||||
assert len(docstring.params) == 5
|
||||
assert docstring.params[0].arg_name == "name"
|
||||
assert docstring.params[0].type_name is None
|
||||
assert docstring.params[0].description == "description 1"
|
||||
assert docstring.params[0].default is None
|
||||
assert not docstring.params[0].is_optional
|
||||
assert docstring.params[1].arg_name == "priority"
|
||||
assert docstring.params[1].type_name == "int"
|
||||
assert docstring.params[1].description == "description 2"
|
||||
assert not docstring.params[1].is_optional
|
||||
assert docstring.params[1].default is None
|
||||
assert docstring.params[2].arg_name == "sender"
|
||||
assert docstring.params[2].type_name == "str"
|
||||
assert docstring.params[2].description == "description 3"
|
||||
assert docstring.params[2].is_optional
|
||||
assert docstring.params[2].default is None
|
||||
assert docstring.params[3].arg_name == "message"
|
||||
assert docstring.params[3].type_name == "str"
|
||||
assert (
|
||||
docstring.params[3].description == "description 4, defaults to 'hello'"
|
||||
)
|
||||
assert docstring.params[3].is_optional
|
||||
assert docstring.params[3].default == "'hello'"
|
||||
assert docstring.params[4].arg_name == "multiline"
|
||||
assert docstring.params[4].type_name == "str"
|
||||
assert (
|
||||
docstring.params[4].description
|
||||
== "long description 5,\ndefaults to 'bye'"
|
||||
)
|
||||
assert docstring.params[4].is_optional
|
||||
assert docstring.params[4].default == "'bye'"
|
||||
|
||||
|
||||
def test_returns() -> None:
|
||||
"""Test parsing returns."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is None
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
@return: description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name is None
|
||||
assert docstring.returns.description == "description"
|
||||
assert not docstring.returns.is_generator
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
@return: description
|
||||
@rtype: int
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name == "int"
|
||||
assert docstring.returns.description == "description"
|
||||
assert not docstring.returns.is_generator
|
||||
|
||||
|
||||
def test_yields() -> None:
|
||||
"""Test parsing yields."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is None
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
@yield: description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name is None
|
||||
assert docstring.returns.description == "description"
|
||||
assert docstring.returns.is_generator
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
@yield: description
|
||||
@ytype: int
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name == "int"
|
||||
assert docstring.returns.description == "description"
|
||||
assert docstring.returns.is_generator
|
||||
|
||||
|
||||
def test_raises() -> None:
|
||||
"""Test parsing raises."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
"""
|
||||
)
|
||||
assert len(docstring.raises) == 0
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
@raise: description
|
||||
"""
|
||||
)
|
||||
assert len(docstring.raises) == 1
|
||||
assert docstring.raises[0].type_name is None
|
||||
assert docstring.raises[0].description == "description"
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
@raise ValueError: description
|
||||
"""
|
||||
)
|
||||
assert len(docstring.raises) == 1
|
||||
assert docstring.raises[0].type_name == "ValueError"
|
||||
assert docstring.raises[0].description == "description"
|
||||
|
||||
|
||||
def test_broken_meta() -> None:
|
||||
"""Test parsing broken meta."""
|
||||
with pytest.raises(ParseError):
|
||||
parse("@")
|
||||
|
||||
with pytest.raises(ParseError):
|
||||
parse("@param herp derp")
|
||||
|
||||
with pytest.raises(ParseError):
|
||||
parse("@param: invalid")
|
||||
|
||||
with pytest.raises(ParseError):
|
||||
parse("@param with too many args: desc")
|
||||
|
||||
# these should not raise any errors
|
||||
parse("@sthstrange: desc")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected",
|
||||
[
|
||||
("", ""),
|
||||
("\n", ""),
|
||||
("Short description", "Short description"),
|
||||
("\nShort description\n", "Short description"),
|
||||
("\n Short description\n", "Short description"),
|
||||
(
|
||||
"Short description\n\nLong description",
|
||||
"Short description\n\nLong description",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Long description
|
||||
""",
|
||||
"Short description\n\nLong description",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Long description
|
||||
Second line
|
||||
""",
|
||||
"Short description\n\nLong description\nSecond line",
|
||||
),
|
||||
(
|
||||
"Short description\nLong description",
|
||||
"Short description\nLong description",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
""",
|
||||
"Short description\nLong description",
|
||||
),
|
||||
(
|
||||
"\nShort description\nLong description\n",
|
||||
"Short description\nLong description",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
Second line
|
||||
""",
|
||||
"Short description\nLong description\nSecond line",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
@meta: asd
|
||||
""",
|
||||
"Short description\n@meta: asd",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
@meta: asd
|
||||
""",
|
||||
"Short description\nLong description\n@meta: asd",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
First line
|
||||
Second line
|
||||
@meta: asd
|
||||
""",
|
||||
"Short description\nFirst line\n Second line\n@meta: asd",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
First line
|
||||
Second line
|
||||
@meta: asd
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n"
|
||||
"First line\n"
|
||||
" Second line\n"
|
||||
"@meta: asd",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
First line
|
||||
Second line
|
||||
|
||||
@meta: asd
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n"
|
||||
"First line\n"
|
||||
" Second line\n"
|
||||
"\n"
|
||||
"@meta: asd",
|
||||
),
|
||||
(
|
||||
"""
|
||||
@meta: asd
|
||||
""",
|
||||
"@meta: asd",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
@meta: asd
|
||||
1
|
||||
2
|
||||
3
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n"
|
||||
"@meta: asd\n"
|
||||
" 1\n"
|
||||
" 2\n"
|
||||
" 3",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
@meta1: asd
|
||||
1
|
||||
2
|
||||
3
|
||||
@meta2: herp
|
||||
@meta3: derp
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n@meta1: asd\n"
|
||||
" 1\n"
|
||||
" 2\n"
|
||||
" 3\n@meta2: herp\n"
|
||||
"@meta3: derp",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
@meta ene due rabe: asd
|
||||
""",
|
||||
"Short description\n\n@meta ene due rabe: asd",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
@param name: description 1
|
||||
@param priority: description 2
|
||||
@type priority: int
|
||||
@param sender: description 3
|
||||
@type sender: str?
|
||||
@type message: str?
|
||||
@param message: description 4, defaults to 'hello'
|
||||
@type multiline: str?
|
||||
@param multiline: long description 5,
|
||||
defaults to 'bye'
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n"
|
||||
"@param name: description 1\n"
|
||||
"@type priority: int\n"
|
||||
"@param priority: description 2\n"
|
||||
"@type sender: str?\n"
|
||||
"@param sender: description 3\n"
|
||||
"@type message: str?\n"
|
||||
"@param message: description 4, defaults to 'hello'\n"
|
||||
"@type multiline: str?\n"
|
||||
"@param multiline: long description 5,\n"
|
||||
" defaults to 'bye'",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
@raise: description
|
||||
""",
|
||||
"Short description\n@raise: description",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
@raise ValueError: description
|
||||
""",
|
||||
"Short description\n@raise ValueError: description",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_compose(source: str, expected: str) -> None:
|
||||
"""Test compose in default mode."""
|
||||
assert compose(parse(source)) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected",
|
||||
[
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
@param name: description 1
|
||||
@param priority: description 2
|
||||
@type priority: int
|
||||
@param sender: description 3
|
||||
@type sender: str?
|
||||
@type message: str?
|
||||
@param message: description 4, defaults to 'hello'
|
||||
@type multiline: str?
|
||||
@param multiline: long description 5,
|
||||
defaults to 'bye'
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n"
|
||||
"@param name:\n"
|
||||
" description 1\n"
|
||||
"@type priority: int\n"
|
||||
"@param priority:\n"
|
||||
" description 2\n"
|
||||
"@type sender: str?\n"
|
||||
"@param sender:\n"
|
||||
" description 3\n"
|
||||
"@type message: str?\n"
|
||||
"@param message:\n"
|
||||
" description 4, defaults to 'hello'\n"
|
||||
"@type multiline: str?\n"
|
||||
"@param multiline:\n"
|
||||
" long description 5,\n"
|
||||
" defaults to 'bye'",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_compose_clean(source: str, expected: str) -> None:
|
||||
"""Test compose in clean mode."""
|
||||
assert (
|
||||
compose(parse(source), rendering_style=RenderingStyle.CLEAN)
|
||||
== expected
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected",
|
||||
[
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
@param name: description 1
|
||||
@param priority: description 2
|
||||
@type priority: int
|
||||
@param sender: description 3
|
||||
@type sender: str?
|
||||
@type message: str?
|
||||
@param message: description 4, defaults to 'hello'
|
||||
@type multiline: str?
|
||||
@param multiline: long description 5,
|
||||
defaults to 'bye'
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n"
|
||||
"@param name:\n"
|
||||
" description 1\n"
|
||||
"@type priority:\n"
|
||||
" int\n"
|
||||
"@param priority:\n"
|
||||
" description 2\n"
|
||||
"@type sender:\n"
|
||||
" str?\n"
|
||||
"@param sender:\n"
|
||||
" description 3\n"
|
||||
"@type message:\n"
|
||||
" str?\n"
|
||||
"@param message:\n"
|
||||
" description 4, defaults to 'hello'\n"
|
||||
"@type multiline:\n"
|
||||
" str?\n"
|
||||
"@param multiline:\n"
|
||||
" long description 5,\n"
|
||||
" defaults to 'bye'",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_compose_expanded(source: str, expected: str) -> None:
|
||||
"""Test compose in expanded mode."""
|
||||
assert (
|
||||
compose(parse(source), rendering_style=RenderingStyle.EXPANDED)
|
||||
== expected
|
||||
)
|
||||
|
||||
|
||||
def test_short_rtype() -> None:
|
||||
"""Test abbreviated docstring with only return type information."""
|
||||
string = "Short description.\n\n@rtype: float"
|
||||
docstring = parse(string)
|
||||
assert compose(docstring) == string
|
||||
@@ -0,0 +1,977 @@
|
||||
"""Tests for Google-style docstring routines."""
|
||||
import typing as T
|
||||
|
||||
import pytest
|
||||
from docstring_parser.common import ParseError, RenderingStyle
|
||||
from docstring_parser.google import (
|
||||
GoogleParser,
|
||||
Section,
|
||||
SectionType,
|
||||
compose,
|
||||
parse,
|
||||
)
|
||||
|
||||
|
||||
def test_google_parser_unknown_section() -> None:
|
||||
"""Test parsing an unknown section with default GoogleParser
|
||||
configuration.
|
||||
"""
|
||||
parser = GoogleParser()
|
||||
docstring = parser.parse(
|
||||
"""
|
||||
Unknown:
|
||||
spam: a
|
||||
"""
|
||||
)
|
||||
assert docstring.short_description == "Unknown:"
|
||||
assert docstring.long_description == "spam: a"
|
||||
assert len(docstring.meta) == 0
|
||||
|
||||
|
||||
def test_google_parser_custom_sections() -> None:
|
||||
"""Test parsing an unknown section with custom GoogleParser
|
||||
configuration.
|
||||
"""
|
||||
parser = GoogleParser(
|
||||
[
|
||||
Section("DESCRIPTION", "desc", SectionType.SINGULAR),
|
||||
Section("ARGUMENTS", "param", SectionType.MULTIPLE),
|
||||
Section("ATTRIBUTES", "attribute", SectionType.MULTIPLE),
|
||||
Section("EXAMPLES", "examples", SectionType.SINGULAR),
|
||||
],
|
||||
title_colon=False,
|
||||
)
|
||||
docstring = parser.parse(
|
||||
"""
|
||||
DESCRIPTION
|
||||
This is the description.
|
||||
|
||||
ARGUMENTS
|
||||
arg1: first arg
|
||||
arg2: second arg
|
||||
|
||||
ATTRIBUTES
|
||||
attr1: first attribute
|
||||
attr2: second attribute
|
||||
|
||||
EXAMPLES
|
||||
Many examples
|
||||
More examples
|
||||
"""
|
||||
)
|
||||
|
||||
assert docstring.short_description is None
|
||||
assert docstring.long_description is None
|
||||
assert len(docstring.meta) == 6
|
||||
assert docstring.meta[0].args == ["desc"]
|
||||
assert docstring.meta[0].description == "This is the description."
|
||||
assert docstring.meta[1].args == ["param", "arg1"]
|
||||
assert docstring.meta[1].description == "first arg"
|
||||
assert docstring.meta[2].args == ["param", "arg2"]
|
||||
assert docstring.meta[2].description == "second arg"
|
||||
assert docstring.meta[3].args == ["attribute", "attr1"]
|
||||
assert docstring.meta[3].description == "first attribute"
|
||||
assert docstring.meta[4].args == ["attribute", "attr2"]
|
||||
assert docstring.meta[4].description == "second attribute"
|
||||
assert docstring.meta[5].args == ["examples"]
|
||||
assert docstring.meta[5].description == "Many examples\nMore examples"
|
||||
|
||||
|
||||
def test_google_parser_custom_sections_after() -> None:
|
||||
"""Test parsing an unknown section with custom GoogleParser configuration
|
||||
that was set at a runtime.
|
||||
"""
|
||||
parser = GoogleParser(title_colon=False)
|
||||
parser.add_section(Section("Note", "note", SectionType.SINGULAR))
|
||||
docstring = parser.parse(
|
||||
"""
|
||||
short description
|
||||
|
||||
Note:
|
||||
a note
|
||||
"""
|
||||
)
|
||||
assert docstring.short_description == "short description"
|
||||
assert docstring.long_description == "Note:\n a note"
|
||||
|
||||
docstring = parser.parse(
|
||||
"""
|
||||
short description
|
||||
|
||||
Note a note
|
||||
"""
|
||||
)
|
||||
assert docstring.short_description == "short description"
|
||||
assert docstring.long_description == "Note a note"
|
||||
|
||||
docstring = parser.parse(
|
||||
"""
|
||||
short description
|
||||
|
||||
Note
|
||||
a note
|
||||
"""
|
||||
)
|
||||
assert len(docstring.meta) == 1
|
||||
assert docstring.meta[0].args == ["note"]
|
||||
assert docstring.meta[0].description == "a note"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected",
|
||||
[
|
||||
("", None),
|
||||
("\n", None),
|
||||
("Short description", "Short description"),
|
||||
("\nShort description\n", "Short description"),
|
||||
("\n Short description\n", "Short description"),
|
||||
],
|
||||
)
|
||||
def test_short_description(source: str, expected: str) -> None:
|
||||
"""Test parsing short description."""
|
||||
docstring = parse(source)
|
||||
assert docstring.short_description == expected
|
||||
assert docstring.long_description is None
|
||||
assert not docstring.meta
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected_short_desc, expected_long_desc, expected_blank",
|
||||
[
|
||||
(
|
||||
"Short description\n\nLong description",
|
||||
"Short description",
|
||||
"Long description",
|
||||
True,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Long description
|
||||
""",
|
||||
"Short description",
|
||||
"Long description",
|
||||
True,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Long description
|
||||
Second line
|
||||
""",
|
||||
"Short description",
|
||||
"Long description\nSecond line",
|
||||
True,
|
||||
),
|
||||
(
|
||||
"Short description\nLong description",
|
||||
"Short description",
|
||||
"Long description",
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
""",
|
||||
"Short description",
|
||||
"Long description",
|
||||
False,
|
||||
),
|
||||
(
|
||||
"\nShort description\nLong description\n",
|
||||
"Short description",
|
||||
"Long description",
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
Second line
|
||||
""",
|
||||
"Short description",
|
||||
"Long description\nSecond line",
|
||||
False,
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_long_description(
|
||||
source: str,
|
||||
expected_short_desc: str,
|
||||
expected_long_desc: str,
|
||||
expected_blank: bool,
|
||||
) -> None:
|
||||
"""Test parsing long description."""
|
||||
docstring = parse(source)
|
||||
assert docstring.short_description == expected_short_desc
|
||||
assert docstring.long_description == expected_long_desc
|
||||
assert docstring.blank_after_short_description == expected_blank
|
||||
assert not docstring.meta
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected_short_desc, expected_long_desc, "
|
||||
"expected_blank_short_desc, expected_blank_long_desc",
|
||||
[
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Args:
|
||||
asd:
|
||||
""",
|
||||
"Short description",
|
||||
None,
|
||||
False,
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
Args:
|
||||
asd:
|
||||
""",
|
||||
"Short description",
|
||||
"Long description",
|
||||
False,
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
First line
|
||||
Second line
|
||||
Args:
|
||||
asd:
|
||||
""",
|
||||
"Short description",
|
||||
"First line\n Second line",
|
||||
False,
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
First line
|
||||
Second line
|
||||
Args:
|
||||
asd:
|
||||
""",
|
||||
"Short description",
|
||||
"First line\n Second line",
|
||||
True,
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
First line
|
||||
Second line
|
||||
|
||||
Args:
|
||||
asd:
|
||||
""",
|
||||
"Short description",
|
||||
"First line\n Second line",
|
||||
True,
|
||||
True,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Args:
|
||||
asd:
|
||||
""",
|
||||
None,
|
||||
None,
|
||||
False,
|
||||
False,
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_meta_newlines(
|
||||
source: str,
|
||||
expected_short_desc: T.Optional[str],
|
||||
expected_long_desc: T.Optional[str],
|
||||
expected_blank_short_desc: bool,
|
||||
expected_blank_long_desc: bool,
|
||||
) -> None:
|
||||
"""Test parsing newlines around description sections."""
|
||||
docstring = parse(source)
|
||||
assert docstring.short_description == expected_short_desc
|
||||
assert docstring.long_description == expected_long_desc
|
||||
assert docstring.blank_after_short_description == expected_blank_short_desc
|
||||
assert docstring.blank_after_long_description == expected_blank_long_desc
|
||||
assert len(docstring.meta) == 1
|
||||
|
||||
|
||||
def test_meta_with_multiline_description() -> None:
|
||||
"""Test parsing multiline meta documentation."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Args:
|
||||
spam: asd
|
||||
1
|
||||
2
|
||||
3
|
||||
"""
|
||||
)
|
||||
assert docstring.short_description == "Short description"
|
||||
assert len(docstring.meta) == 1
|
||||
assert docstring.meta[0].args == ["param", "spam"]
|
||||
assert docstring.meta[0].arg_name == "spam"
|
||||
assert docstring.meta[0].description == "asd\n1\n 2\n3"
|
||||
|
||||
|
||||
def test_default_args() -> None:
|
||||
"""Test parsing default arguments."""
|
||||
docstring = parse(
|
||||
"""A sample function
|
||||
|
||||
A function the demonstrates docstrings
|
||||
|
||||
Args:
|
||||
arg1 (int): The firsty arg
|
||||
arg2 (str): The second arg
|
||||
arg3 (float, optional): The third arg. Defaults to 1.0.
|
||||
arg4 (Optional[Dict[str, Any]], optional): The last arg. Defaults to None.
|
||||
arg5 (str, optional): The fifth arg. Defaults to DEFAULT_ARG5.
|
||||
|
||||
Returns:
|
||||
Mapping[str, Any]: The args packed in a mapping
|
||||
"""
|
||||
)
|
||||
assert docstring is not None
|
||||
assert len(docstring.params) == 5
|
||||
|
||||
arg4 = docstring.params[3]
|
||||
assert arg4.arg_name == "arg4"
|
||||
assert arg4.is_optional
|
||||
assert arg4.type_name == "Optional[Dict[str, Any]]"
|
||||
assert arg4.default == "None"
|
||||
assert arg4.description == "The last arg. Defaults to None."
|
||||
|
||||
|
||||
def test_multiple_meta() -> None:
|
||||
"""Test parsing multiple meta."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Args:
|
||||
spam: asd
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
Raises:
|
||||
bla: herp
|
||||
yay: derp
|
||||
"""
|
||||
)
|
||||
assert docstring.short_description == "Short description"
|
||||
assert len(docstring.meta) == 3
|
||||
assert docstring.meta[0].args == ["param", "spam"]
|
||||
assert docstring.meta[0].arg_name == "spam"
|
||||
assert docstring.meta[0].description == "asd\n1\n 2\n3"
|
||||
assert docstring.meta[1].args == ["raises", "bla"]
|
||||
assert docstring.meta[1].type_name == "bla"
|
||||
assert docstring.meta[1].description == "herp"
|
||||
assert docstring.meta[2].args == ["raises", "yay"]
|
||||
assert docstring.meta[2].type_name == "yay"
|
||||
assert docstring.meta[2].description == "derp"
|
||||
|
||||
|
||||
def test_params() -> None:
|
||||
"""Test parsing params."""
|
||||
docstring = parse("Short description")
|
||||
assert len(docstring.params) == 0
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Args:
|
||||
name: description 1
|
||||
priority (int): description 2
|
||||
sender (str?): description 3
|
||||
ratio (Optional[float], optional): description 4
|
||||
"""
|
||||
)
|
||||
assert len(docstring.params) == 4
|
||||
assert docstring.params[0].arg_name == "name"
|
||||
assert docstring.params[0].type_name is None
|
||||
assert docstring.params[0].description == "description 1"
|
||||
assert not docstring.params[0].is_optional
|
||||
assert docstring.params[1].arg_name == "priority"
|
||||
assert docstring.params[1].type_name == "int"
|
||||
assert docstring.params[1].description == "description 2"
|
||||
assert not docstring.params[1].is_optional
|
||||
assert docstring.params[2].arg_name == "sender"
|
||||
assert docstring.params[2].type_name == "str"
|
||||
assert docstring.params[2].description == "description 3"
|
||||
assert docstring.params[2].is_optional
|
||||
assert docstring.params[3].arg_name == "ratio"
|
||||
assert docstring.params[3].type_name == "Optional[float]"
|
||||
assert docstring.params[3].description == "description 4"
|
||||
assert docstring.params[3].is_optional
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Args:
|
||||
name: description 1
|
||||
with multi-line text
|
||||
priority (int): description 2
|
||||
"""
|
||||
)
|
||||
assert len(docstring.params) == 2
|
||||
assert docstring.params[0].arg_name == "name"
|
||||
assert docstring.params[0].type_name is None
|
||||
assert docstring.params[0].description == (
|
||||
"description 1\nwith multi-line text"
|
||||
)
|
||||
assert docstring.params[1].arg_name == "priority"
|
||||
assert docstring.params[1].type_name == "int"
|
||||
assert docstring.params[1].description == "description 2"
|
||||
|
||||
|
||||
def test_attributes() -> None:
|
||||
"""Test parsing attributes."""
|
||||
docstring = parse("Short description")
|
||||
assert len(docstring.params) == 0
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Attributes:
|
||||
name: description 1
|
||||
priority (int): description 2
|
||||
sender (str?): description 3
|
||||
ratio (Optional[float], optional): description 4
|
||||
"""
|
||||
)
|
||||
assert len(docstring.params) == 4
|
||||
assert docstring.params[0].arg_name == "name"
|
||||
assert docstring.params[0].type_name is None
|
||||
assert docstring.params[0].description == "description 1"
|
||||
assert not docstring.params[0].is_optional
|
||||
assert docstring.params[1].arg_name == "priority"
|
||||
assert docstring.params[1].type_name == "int"
|
||||
assert docstring.params[1].description == "description 2"
|
||||
assert not docstring.params[1].is_optional
|
||||
assert docstring.params[2].arg_name == "sender"
|
||||
assert docstring.params[2].type_name == "str"
|
||||
assert docstring.params[2].description == "description 3"
|
||||
assert docstring.params[2].is_optional
|
||||
assert docstring.params[3].arg_name == "ratio"
|
||||
assert docstring.params[3].type_name == "Optional[float]"
|
||||
assert docstring.params[3].description == "description 4"
|
||||
assert docstring.params[3].is_optional
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Attributes:
|
||||
name: description 1
|
||||
with multi-line text
|
||||
priority (int): description 2
|
||||
"""
|
||||
)
|
||||
assert len(docstring.params) == 2
|
||||
assert docstring.params[0].arg_name == "name"
|
||||
assert docstring.params[0].type_name is None
|
||||
assert docstring.params[0].description == (
|
||||
"description 1\nwith multi-line text"
|
||||
)
|
||||
assert docstring.params[1].arg_name == "priority"
|
||||
assert docstring.params[1].type_name == "int"
|
||||
assert docstring.params[1].description == "description 2"
|
||||
|
||||
|
||||
def test_returns() -> None:
|
||||
"""Test parsing returns."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is None
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 0
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
Returns:
|
||||
description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name is None
|
||||
assert docstring.returns.description == "description"
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 1
|
||||
assert docstring.many_returns[0] == docstring.returns
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
Returns:
|
||||
description with: a colon!
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name is None
|
||||
assert docstring.returns.description == "description with: a colon!"
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 1
|
||||
assert docstring.many_returns[0] == docstring.returns
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
Returns:
|
||||
int: description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name == "int"
|
||||
assert docstring.returns.description == "description"
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 1
|
||||
assert docstring.many_returns[0] == docstring.returns
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Returns:
|
||||
Optional[Mapping[str, List[int]]]: A description: with a colon
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name == "Optional[Mapping[str, List[int]]]"
|
||||
assert docstring.returns.description == "A description: with a colon"
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 1
|
||||
assert docstring.many_returns[0] == docstring.returns
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
Yields:
|
||||
int: description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name == "int"
|
||||
assert docstring.returns.description == "description"
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 1
|
||||
assert docstring.many_returns[0] == docstring.returns
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
Returns:
|
||||
int: description
|
||||
with much text
|
||||
|
||||
even some spacing
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name == "int"
|
||||
assert docstring.returns.description == (
|
||||
"description\nwith much text\n\neven some spacing"
|
||||
)
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 1
|
||||
assert docstring.many_returns[0] == docstring.returns
|
||||
|
||||
|
||||
def test_raises() -> None:
|
||||
"""Test parsing raises."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
"""
|
||||
)
|
||||
assert len(docstring.raises) == 0
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
Raises:
|
||||
ValueError: description
|
||||
"""
|
||||
)
|
||||
assert len(docstring.raises) == 1
|
||||
assert docstring.raises[0].type_name == "ValueError"
|
||||
assert docstring.raises[0].description == "description"
|
||||
|
||||
|
||||
def test_examples() -> None:
|
||||
"""Test parsing examples."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
Example:
|
||||
example: 1
|
||||
Examples:
|
||||
long example
|
||||
|
||||
more here
|
||||
"""
|
||||
)
|
||||
assert len(docstring.examples) == 2
|
||||
assert docstring.examples[0].description == "example: 1"
|
||||
assert docstring.examples[1].description == "long example\n\nmore here"
|
||||
|
||||
|
||||
def test_broken_meta() -> None:
|
||||
"""Test parsing broken meta."""
|
||||
with pytest.raises(ParseError):
|
||||
parse("Args:")
|
||||
|
||||
with pytest.raises(ParseError):
|
||||
parse("Args:\n herp derp")
|
||||
|
||||
|
||||
def test_unknown_meta() -> None:
|
||||
"""Test parsing unknown meta."""
|
||||
docstring = parse(
|
||||
"""Short desc
|
||||
|
||||
Unknown 0:
|
||||
title0: content0
|
||||
|
||||
Args:
|
||||
arg0: desc0
|
||||
arg1: desc1
|
||||
|
||||
Unknown1:
|
||||
title1: content1
|
||||
|
||||
Unknown2:
|
||||
title2: content2
|
||||
"""
|
||||
)
|
||||
|
||||
assert docstring.params[0].arg_name == "arg0"
|
||||
assert docstring.params[0].description == "desc0"
|
||||
assert docstring.params[1].arg_name == "arg1"
|
||||
assert docstring.params[1].description == "desc1"
|
||||
|
||||
|
||||
def test_broken_arguments() -> None:
|
||||
"""Test parsing broken arguments."""
|
||||
with pytest.raises(ParseError):
|
||||
parse(
|
||||
"""This is a test
|
||||
|
||||
Args:
|
||||
param - poorly formatted
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def test_empty_example() -> None:
|
||||
"""Test parsing empty examples section."""
|
||||
docstring = parse(
|
||||
"""Short description
|
||||
|
||||
Example:
|
||||
|
||||
Raises:
|
||||
IOError: some error
|
||||
"""
|
||||
)
|
||||
|
||||
assert len(docstring.examples) == 1
|
||||
assert docstring.examples[0].args == ["examples"]
|
||||
assert docstring.examples[0].description == ""
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected",
|
||||
[
|
||||
("", ""),
|
||||
("\n", ""),
|
||||
("Short description", "Short description"),
|
||||
("\nShort description\n", "Short description"),
|
||||
("\n Short description\n", "Short description"),
|
||||
(
|
||||
"Short description\n\nLong description",
|
||||
"Short description\n\nLong description",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Long description
|
||||
""",
|
||||
"Short description\n\nLong description",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Long description
|
||||
Second line
|
||||
""",
|
||||
"Short description\n\nLong description\nSecond line",
|
||||
),
|
||||
(
|
||||
"Short description\nLong description",
|
||||
"Short description\nLong description",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
""",
|
||||
"Short description\nLong description",
|
||||
),
|
||||
(
|
||||
"\nShort description\nLong description\n",
|
||||
"Short description\nLong description",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
Second line
|
||||
""",
|
||||
"Short description\nLong description\nSecond line",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Meta:
|
||||
asd
|
||||
""",
|
||||
"Short description\nMeta:\n asd",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
Meta:
|
||||
asd
|
||||
""",
|
||||
"Short description\nLong description\nMeta:\n asd",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
First line
|
||||
Second line
|
||||
Meta:
|
||||
asd
|
||||
""",
|
||||
"Short description\n"
|
||||
"First line\n"
|
||||
" Second line\n"
|
||||
"Meta:\n"
|
||||
" asd",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
First line
|
||||
Second line
|
||||
Meta:
|
||||
asd
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n"
|
||||
"First line\n"
|
||||
" Second line\n"
|
||||
"Meta:\n"
|
||||
" asd",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
First line
|
||||
Second line
|
||||
|
||||
Meta:
|
||||
asd
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n"
|
||||
"First line\n"
|
||||
" Second line\n"
|
||||
"\n"
|
||||
"Meta:\n"
|
||||
" asd",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Meta:
|
||||
asd
|
||||
1
|
||||
2
|
||||
3
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n"
|
||||
"Meta:\n"
|
||||
" asd\n"
|
||||
" 1\n"
|
||||
" 2\n"
|
||||
" 3",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Meta1:
|
||||
asd
|
||||
1
|
||||
2
|
||||
3
|
||||
Meta2:
|
||||
herp
|
||||
Meta3:
|
||||
derp
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n"
|
||||
"Meta1:\n"
|
||||
" asd\n"
|
||||
" 1\n"
|
||||
" 2\n"
|
||||
" 3\n"
|
||||
"Meta2:\n"
|
||||
" herp\n"
|
||||
"Meta3:\n"
|
||||
" derp",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Args:
|
||||
name: description 1
|
||||
priority (int): description 2
|
||||
sender (str, optional): description 3
|
||||
message (str, optional): description 4, defaults to 'hello'
|
||||
multiline (str?):
|
||||
long description 5,
|
||||
defaults to 'bye'
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n"
|
||||
"Args:\n"
|
||||
" name: description 1\n"
|
||||
" priority (int): description 2\n"
|
||||
" sender (str?): description 3\n"
|
||||
" message (str?): description 4, defaults to 'hello'\n"
|
||||
" multiline (str?): long description 5,\n"
|
||||
" defaults to 'bye'",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Raises:
|
||||
ValueError: description
|
||||
""",
|
||||
"Short description\nRaises:\n ValueError: description",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_compose(source: str, expected: str) -> None:
|
||||
"""Test compose in default mode."""
|
||||
assert compose(parse(source)) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected",
|
||||
[
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Args:
|
||||
name: description 1
|
||||
priority (int): description 2
|
||||
sender (str, optional): description 3
|
||||
message (str, optional): description 4, defaults to 'hello'
|
||||
multiline (str?):
|
||||
long description 5,
|
||||
defaults to 'bye'
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n"
|
||||
"Args:\n"
|
||||
" name: description 1\n"
|
||||
" priority (int): description 2\n"
|
||||
" sender (str, optional): description 3\n"
|
||||
" message (str, optional): description 4, defaults to 'hello'\n"
|
||||
" multiline (str, optional): long description 5,\n"
|
||||
" defaults to 'bye'",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_compose_clean(source: str, expected: str) -> None:
|
||||
"""Test compose in clean mode."""
|
||||
assert (
|
||||
compose(parse(source), rendering_style=RenderingStyle.CLEAN)
|
||||
== expected
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected",
|
||||
[
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Args:
|
||||
name: description 1
|
||||
priority (int): description 2
|
||||
sender (str, optional): description 3
|
||||
message (str, optional): description 4, defaults to 'hello'
|
||||
multiline (str?):
|
||||
long description 5,
|
||||
defaults to 'bye'
|
||||
""",
|
||||
"Short description\n"
|
||||
"\n"
|
||||
"Args:\n"
|
||||
" name:\n"
|
||||
" description 1\n"
|
||||
" priority (int):\n"
|
||||
" description 2\n"
|
||||
" sender (str, optional):\n"
|
||||
" description 3\n"
|
||||
" message (str, optional):\n"
|
||||
" description 4, defaults to 'hello'\n"
|
||||
" multiline (str, optional):\n"
|
||||
" long description 5,\n"
|
||||
" defaults to 'bye'",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_compose_expanded(source: str, expected: str) -> None:
|
||||
"""Test compose in expanded mode."""
|
||||
assert (
|
||||
compose(parse(source), rendering_style=RenderingStyle.EXPANDED)
|
||||
== expected
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,109 @@
|
||||
"""Tests for parse_from_object function and attribute docstrings."""
|
||||
from unittest.mock import patch
|
||||
|
||||
from docstring_parser import parse_from_object
|
||||
|
||||
module_attr: int = 1
|
||||
"""Description for module_attr"""
|
||||
|
||||
|
||||
def test_from_module_attribute_docstrings() -> None:
|
||||
"""Test the parse of attribute docstrings from a module."""
|
||||
from . import test_parse_from_object # pylint: disable=C0415,W0406
|
||||
|
||||
docstring = parse_from_object(test_parse_from_object)
|
||||
|
||||
assert "parse_from_object" in docstring.short_description
|
||||
assert len(docstring.params) == 1
|
||||
assert docstring.params[0].arg_name == "module_attr"
|
||||
assert docstring.params[0].type_name == "int"
|
||||
assert docstring.params[0].description == "Description for module_attr"
|
||||
|
||||
|
||||
def test_from_class_attribute_docstrings() -> None:
|
||||
"""Test the parse of attribute docstrings from a class."""
|
||||
|
||||
class StandardCase:
|
||||
"""Short description
|
||||
Long description
|
||||
"""
|
||||
|
||||
attr_one: str
|
||||
"""Description for attr_one"""
|
||||
attr_two: bool = False
|
||||
"""Description for attr_two"""
|
||||
|
||||
docstring = parse_from_object(StandardCase)
|
||||
|
||||
assert docstring.short_description == "Short description"
|
||||
assert docstring.long_description == "Long description"
|
||||
assert docstring.description == "Short description\nLong description"
|
||||
assert len(docstring.params) == 2
|
||||
assert docstring.params[0].arg_name == "attr_one"
|
||||
assert docstring.params[0].type_name == "str"
|
||||
assert docstring.params[0].description == "Description for attr_one"
|
||||
assert docstring.params[1].arg_name == "attr_two"
|
||||
assert docstring.params[1].type_name == "bool"
|
||||
assert docstring.params[1].description == "Description for attr_two"
|
||||
|
||||
|
||||
def test_from_class_attribute_docstrings_without_type() -> None:
|
||||
"""Test the parse of untyped attribute docstrings."""
|
||||
|
||||
class WithoutType: # pylint: disable=missing-class-docstring
|
||||
attr_one = "value"
|
||||
"""Description for attr_one"""
|
||||
|
||||
docstring = parse_from_object(WithoutType)
|
||||
|
||||
assert docstring.short_description is None
|
||||
assert docstring.long_description is None
|
||||
assert docstring.description is None
|
||||
assert len(docstring.params) == 1
|
||||
assert docstring.params[0].arg_name == "attr_one"
|
||||
assert docstring.params[0].type_name is None
|
||||
assert docstring.params[0].description == "Description for attr_one"
|
||||
|
||||
|
||||
def test_from_class_without_source() -> None:
|
||||
"""Test the parse of class when source is unavailable."""
|
||||
|
||||
class WithoutSource:
|
||||
"""Short description"""
|
||||
|
||||
attr_one: str
|
||||
"""Description for attr_one"""
|
||||
|
||||
with patch(
|
||||
"inspect.getsource", side_effect=OSError("could not get source code")
|
||||
):
|
||||
docstring = parse_from_object(WithoutSource)
|
||||
|
||||
assert docstring.short_description == "Short description"
|
||||
assert docstring.long_description is None
|
||||
assert docstring.description == "Short description"
|
||||
assert len(docstring.params) == 0
|
||||
|
||||
|
||||
def test_from_function() -> None:
|
||||
"""Test the parse of a function docstring."""
|
||||
|
||||
def a_function(param1: str, param2: int = 2):
|
||||
"""Short description
|
||||
Args:
|
||||
param1: Description for param1
|
||||
param2: Description for param2
|
||||
"""
|
||||
return f"{param1} {param2}"
|
||||
|
||||
docstring = parse_from_object(a_function)
|
||||
|
||||
assert docstring.short_description == "Short description"
|
||||
assert docstring.description == "Short description"
|
||||
assert len(docstring.params) == 2
|
||||
assert docstring.params[0].arg_name == "param1"
|
||||
assert docstring.params[0].type_name is None
|
||||
assert docstring.params[0].description == "Description for param1"
|
||||
assert docstring.params[1].arg_name == "param2"
|
||||
assert docstring.params[1].type_name is None
|
||||
assert docstring.params[1].description == "Description for param2"
|
||||
@@ -0,0 +1,222 @@
|
||||
"""Tests for generic docstring routines."""
|
||||
import pytest
|
||||
from docstring_parser.common import DocstringStyle, ParseError
|
||||
from docstring_parser.parser import parse
|
||||
|
||||
|
||||
def test_rest() -> None:
|
||||
"""Test ReST-style parser autodetection."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Long description
|
||||
|
||||
Causing people to indent:
|
||||
|
||||
A lot sometimes
|
||||
|
||||
:param spam: spam desc
|
||||
:param int bla: bla desc
|
||||
:param str yay:
|
||||
:raises ValueError: exc desc
|
||||
:returns tuple: ret desc
|
||||
"""
|
||||
)
|
||||
|
||||
assert docstring.style == DocstringStyle.REST
|
||||
assert docstring.short_description == "Short description"
|
||||
assert docstring.long_description == (
|
||||
"Long description\n\n"
|
||||
"Causing people to indent:\n\n"
|
||||
" A lot sometimes"
|
||||
)
|
||||
assert docstring.description == (
|
||||
"Short description\n\n"
|
||||
"Long description\n\n"
|
||||
"Causing people to indent:\n\n"
|
||||
" A lot sometimes"
|
||||
)
|
||||
assert len(docstring.params) == 3
|
||||
assert docstring.params[0].arg_name == "spam"
|
||||
assert docstring.params[0].type_name is None
|
||||
assert docstring.params[0].description == "spam desc"
|
||||
assert docstring.params[1].arg_name == "bla"
|
||||
assert docstring.params[1].type_name == "int"
|
||||
assert docstring.params[1].description == "bla desc"
|
||||
assert docstring.params[2].arg_name == "yay"
|
||||
assert docstring.params[2].type_name == "str"
|
||||
assert docstring.params[2].description == ""
|
||||
assert len(docstring.raises) == 1
|
||||
assert docstring.raises[0].type_name == "ValueError"
|
||||
assert docstring.raises[0].description == "exc desc"
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name == "tuple"
|
||||
assert docstring.returns.description == "ret desc"
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 1
|
||||
assert docstring.many_returns[0] == docstring.returns
|
||||
|
||||
|
||||
def test_google() -> None:
|
||||
"""Test Google-style parser autodetection."""
|
||||
docstring = parse(
|
||||
"""Short description
|
||||
|
||||
Long description
|
||||
|
||||
Causing people to indent:
|
||||
|
||||
A lot sometimes
|
||||
|
||||
Args:
|
||||
spam: spam desc
|
||||
bla (int): bla desc
|
||||
yay (str):
|
||||
|
||||
Raises:
|
||||
ValueError: exc desc
|
||||
|
||||
Returns:
|
||||
tuple: ret desc
|
||||
"""
|
||||
)
|
||||
|
||||
assert docstring.style == DocstringStyle.GOOGLE
|
||||
assert docstring.short_description == "Short description"
|
||||
assert docstring.long_description == (
|
||||
"Long description\n\n"
|
||||
"Causing people to indent:\n\n"
|
||||
" A lot sometimes"
|
||||
)
|
||||
assert docstring.description == (
|
||||
"Short description\n\n"
|
||||
"Long description\n\n"
|
||||
"Causing people to indent:\n\n"
|
||||
" A lot sometimes"
|
||||
)
|
||||
assert len(docstring.params) == 3
|
||||
assert docstring.params[0].arg_name == "spam"
|
||||
assert docstring.params[0].type_name is None
|
||||
assert docstring.params[0].description == "spam desc"
|
||||
assert docstring.params[1].arg_name == "bla"
|
||||
assert docstring.params[1].type_name == "int"
|
||||
assert docstring.params[1].description == "bla desc"
|
||||
assert docstring.params[2].arg_name == "yay"
|
||||
assert docstring.params[2].type_name == "str"
|
||||
assert docstring.params[2].description == ""
|
||||
assert len(docstring.raises) == 1
|
||||
assert docstring.raises[0].type_name == "ValueError"
|
||||
assert docstring.raises[0].description == "exc desc"
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name == "tuple"
|
||||
assert docstring.returns.description == "ret desc"
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 1
|
||||
assert docstring.many_returns[0] == docstring.returns
|
||||
|
||||
|
||||
def test_numpydoc() -> None:
|
||||
"""Test numpydoc-style parser autodetection."""
|
||||
docstring = parse(
|
||||
"""Short description
|
||||
|
||||
Long description
|
||||
|
||||
Causing people to indent:
|
||||
|
||||
A lot sometimes
|
||||
|
||||
Parameters
|
||||
----------
|
||||
spam
|
||||
spam desc
|
||||
bla : int
|
||||
bla desc
|
||||
yay : str
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
exc desc
|
||||
|
||||
Other Parameters
|
||||
----------------
|
||||
this_guy : int, optional
|
||||
you know him
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple
|
||||
ret desc
|
||||
|
||||
See Also
|
||||
--------
|
||||
multiple lines...
|
||||
something else?
|
||||
|
||||
Warnings
|
||||
--------
|
||||
multiple lines...
|
||||
none of this is real!
|
||||
"""
|
||||
)
|
||||
|
||||
assert docstring.style == DocstringStyle.NUMPYDOC
|
||||
assert docstring.short_description == "Short description"
|
||||
assert docstring.long_description == (
|
||||
"Long description\n\n"
|
||||
"Causing people to indent:\n\n"
|
||||
" A lot sometimes"
|
||||
)
|
||||
assert docstring.description == (
|
||||
"Short description\n\n"
|
||||
"Long description\n\n"
|
||||
"Causing people to indent:\n\n"
|
||||
" A lot sometimes"
|
||||
)
|
||||
assert len(docstring.params) == 4
|
||||
assert docstring.params[0].arg_name == "spam"
|
||||
assert docstring.params[0].type_name is None
|
||||
assert docstring.params[0].description == "spam desc"
|
||||
assert docstring.params[1].arg_name == "bla"
|
||||
assert docstring.params[1].type_name == "int"
|
||||
assert docstring.params[1].description == "bla desc"
|
||||
assert docstring.params[2].arg_name == "yay"
|
||||
assert docstring.params[2].type_name == "str"
|
||||
assert docstring.params[2].description is None
|
||||
assert docstring.params[3].arg_name == "this_guy"
|
||||
assert docstring.params[3].type_name == "int"
|
||||
assert docstring.params[3].is_optional
|
||||
assert docstring.params[3].description == "you know him"
|
||||
|
||||
assert len(docstring.raises) == 1
|
||||
assert docstring.raises[0].type_name == "ValueError"
|
||||
assert docstring.raises[0].description == "exc desc"
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name == "tuple"
|
||||
assert docstring.returns.description == "ret desc"
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 1
|
||||
assert docstring.many_returns[0] == docstring.returns
|
||||
|
||||
|
||||
def test_autodetection_error_detection() -> None:
|
||||
"""Test autodection for the case where one of the parsers throws an error
|
||||
and another one succeeds.
|
||||
"""
|
||||
source = """
|
||||
Does something useless
|
||||
|
||||
:param 3 + 3 a: a param
|
||||
"""
|
||||
|
||||
with pytest.raises(ParseError):
|
||||
# assert that one of the parsers does raise
|
||||
parse(source, DocstringStyle.REST)
|
||||
|
||||
# assert that autodetection still works
|
||||
docstring = parse(source)
|
||||
|
||||
assert docstring
|
||||
assert docstring.style == DocstringStyle.GOOGLE
|
||||
@@ -0,0 +1,541 @@
|
||||
"""Tests for ReST-style docstring routines."""
|
||||
import typing as T
|
||||
|
||||
import pytest
|
||||
from docstring_parser.common import ParseError, RenderingStyle
|
||||
from docstring_parser.rest import compose, parse
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected",
|
||||
[
|
||||
("", None),
|
||||
("\n", None),
|
||||
("Short description", "Short description"),
|
||||
("\nShort description\n", "Short description"),
|
||||
("\n Short description\n", "Short description"),
|
||||
],
|
||||
)
|
||||
def test_short_description(source: str, expected: str) -> None:
|
||||
"""Test parsing short description."""
|
||||
docstring = parse(source)
|
||||
assert docstring.short_description == expected
|
||||
assert docstring.description == expected
|
||||
assert docstring.long_description is None
|
||||
assert not docstring.meta
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected_short_desc, expected_long_desc, expected_blank",
|
||||
[
|
||||
(
|
||||
"Short description\n\nLong description",
|
||||
"Short description",
|
||||
"Long description",
|
||||
True,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Long description
|
||||
""",
|
||||
"Short description",
|
||||
"Long description",
|
||||
True,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
Long description
|
||||
Second line
|
||||
""",
|
||||
"Short description",
|
||||
"Long description\nSecond line",
|
||||
True,
|
||||
),
|
||||
(
|
||||
"Short description\nLong description",
|
||||
"Short description",
|
||||
"Long description",
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
""",
|
||||
"Short description",
|
||||
"Long description",
|
||||
False,
|
||||
),
|
||||
(
|
||||
"\nShort description\nLong description\n",
|
||||
"Short description",
|
||||
"Long description",
|
||||
False,
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
Second line
|
||||
""",
|
||||
"Short description",
|
||||
"Long description\nSecond line",
|
||||
False,
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_long_description(
|
||||
source: str,
|
||||
expected_short_desc: str,
|
||||
expected_long_desc: str,
|
||||
expected_blank: bool,
|
||||
) -> None:
|
||||
"""Test parsing long description."""
|
||||
docstring = parse(source)
|
||||
assert docstring.short_description == expected_short_desc
|
||||
assert docstring.long_description == expected_long_desc
|
||||
assert docstring.blank_after_short_description == expected_blank
|
||||
assert not docstring.meta
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"source, expected_short_desc, expected_long_desc, "
|
||||
"expected_blank_short_desc, expected_blank_long_desc, "
|
||||
"expected_full_desc",
|
||||
[
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
:meta: asd
|
||||
""",
|
||||
"Short description",
|
||||
None,
|
||||
False,
|
||||
False,
|
||||
"Short description",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
Long description
|
||||
:meta: asd
|
||||
""",
|
||||
"Short description",
|
||||
"Long description",
|
||||
False,
|
||||
False,
|
||||
"Short description\nLong description",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
First line
|
||||
Second line
|
||||
:meta: asd
|
||||
""",
|
||||
"Short description",
|
||||
"First line\n Second line",
|
||||
False,
|
||||
False,
|
||||
"Short description\nFirst line\n Second line",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
First line
|
||||
Second line
|
||||
:meta: asd
|
||||
""",
|
||||
"Short description",
|
||||
"First line\n Second line",
|
||||
True,
|
||||
False,
|
||||
"Short description\n\nFirst line\n Second line",
|
||||
),
|
||||
(
|
||||
"""
|
||||
Short description
|
||||
|
||||
First line
|
||||
Second line
|
||||
|
||||
:meta: asd
|
||||
""",
|
||||
"Short description",
|
||||
"First line\n Second line",
|
||||
True,
|
||||
True,
|
||||
"Short description\n\nFirst line\n Second line",
|
||||
),
|
||||
(
|
||||
"""
|
||||
:meta: asd
|
||||
""",
|
||||
None,
|
||||
None,
|
||||
False,
|
||||
False,
|
||||
None,
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_meta_newlines(
|
||||
source: str,
|
||||
expected_short_desc: T.Optional[str],
|
||||
expected_long_desc: T.Optional[str],
|
||||
expected_blank_short_desc: bool,
|
||||
expected_blank_long_desc: bool,
|
||||
expected_full_desc: T.Optional[str],
|
||||
) -> None:
|
||||
"""Test parsing newlines around description sections."""
|
||||
docstring = parse(source)
|
||||
assert docstring.short_description == expected_short_desc
|
||||
assert docstring.long_description == expected_long_desc
|
||||
assert docstring.blank_after_short_description == expected_blank_short_desc
|
||||
assert docstring.blank_after_long_description == expected_blank_long_desc
|
||||
assert docstring.description == expected_full_desc
|
||||
assert len(docstring.meta) == 1
|
||||
|
||||
|
||||
def test_meta_with_multiline_description() -> None:
|
||||
"""Test parsing multiline meta documentation."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
:meta: asd
|
||||
1
|
||||
2
|
||||
3
|
||||
"""
|
||||
)
|
||||
assert docstring.short_description == "Short description"
|
||||
assert len(docstring.meta) == 1
|
||||
assert docstring.meta[0].args == ["meta"]
|
||||
assert docstring.meta[0].description == "asd\n1\n 2\n3"
|
||||
|
||||
|
||||
def test_multiple_meta() -> None:
|
||||
"""Test parsing multiple meta."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
:meta1: asd
|
||||
1
|
||||
2
|
||||
3
|
||||
:meta2: herp
|
||||
:meta3: derp
|
||||
"""
|
||||
)
|
||||
assert docstring.short_description == "Short description"
|
||||
assert len(docstring.meta) == 3
|
||||
assert docstring.meta[0].args == ["meta1"]
|
||||
assert docstring.meta[0].description == "asd\n1\n 2\n3"
|
||||
assert docstring.meta[1].args == ["meta2"]
|
||||
assert docstring.meta[1].description == "herp"
|
||||
assert docstring.meta[2].args == ["meta3"]
|
||||
assert docstring.meta[2].description == "derp"
|
||||
|
||||
|
||||
def test_meta_with_args() -> None:
|
||||
"""Test parsing meta with additional arguments."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
:meta ene due rabe: asd
|
||||
"""
|
||||
)
|
||||
assert docstring.short_description == "Short description"
|
||||
assert len(docstring.meta) == 1
|
||||
assert docstring.meta[0].args == ["meta", "ene", "due", "rabe"]
|
||||
assert docstring.meta[0].description == "asd"
|
||||
|
||||
|
||||
def test_params() -> None:
|
||||
"""Test parsing params."""
|
||||
docstring = parse("Short description")
|
||||
assert len(docstring.params) == 0
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
:param name: description 1
|
||||
:param int priority: description 2
|
||||
:param str? sender: description 3
|
||||
:param str? message: description 4, defaults to 'hello'
|
||||
:param str? multiline: long description 5,
|
||||
defaults to 'bye'
|
||||
"""
|
||||
)
|
||||
assert len(docstring.params) == 5
|
||||
assert docstring.params[0].arg_name == "name"
|
||||
assert docstring.params[0].type_name is None
|
||||
assert docstring.params[0].description == "description 1"
|
||||
assert docstring.params[0].default is None
|
||||
assert not docstring.params[0].is_optional
|
||||
assert docstring.params[1].arg_name == "priority"
|
||||
assert docstring.params[1].type_name == "int"
|
||||
assert docstring.params[1].description == "description 2"
|
||||
assert not docstring.params[1].is_optional
|
||||
assert docstring.params[1].default is None
|
||||
assert docstring.params[2].arg_name == "sender"
|
||||
assert docstring.params[2].type_name == "str"
|
||||
assert docstring.params[2].description == "description 3"
|
||||
assert docstring.params[2].is_optional
|
||||
assert docstring.params[2].default is None
|
||||
assert docstring.params[3].arg_name == "message"
|
||||
assert docstring.params[3].type_name == "str"
|
||||
assert (
|
||||
docstring.params[3].description == "description 4, defaults to 'hello'"
|
||||
)
|
||||
assert docstring.params[3].is_optional
|
||||
assert docstring.params[3].default == "'hello'"
|
||||
assert docstring.params[4].arg_name == "multiline"
|
||||
assert docstring.params[4].type_name == "str"
|
||||
assert (
|
||||
docstring.params[4].description
|
||||
== "long description 5,\ndefaults to 'bye'"
|
||||
)
|
||||
assert docstring.params[4].is_optional
|
||||
assert docstring.params[4].default == "'bye'"
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
|
||||
:param a: description a
|
||||
:type a: int
|
||||
:param int b: description b
|
||||
"""
|
||||
)
|
||||
assert len(docstring.params) == 2
|
||||
assert docstring.params[0].arg_name == "a"
|
||||
assert docstring.params[0].type_name == "int"
|
||||
assert docstring.params[0].description == "description a"
|
||||
assert docstring.params[0].default is None
|
||||
assert not docstring.params[0].is_optional
|
||||
|
||||
|
||||
def test_returns() -> None:
|
||||
"""Test parsing returns."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is None
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 0
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
:returns: description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name is None
|
||||
assert docstring.returns.description == "description"
|
||||
assert not docstring.returns.is_generator
|
||||
assert docstring.many_returns == [docstring.returns]
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
:returns int: description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name == "int"
|
||||
assert docstring.returns.description == "description"
|
||||
assert not docstring.returns.is_generator
|
||||
assert docstring.many_returns == [docstring.returns]
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
:returns: description
|
||||
:rtype: int
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name == "int"
|
||||
assert docstring.returns.description == "description"
|
||||
assert not docstring.returns.is_generator
|
||||
assert docstring.many_returns == [docstring.returns]
|
||||
|
||||
|
||||
def test_yields() -> None:
|
||||
"""Test parsing yields."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is None
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 0
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
:yields: description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name is None
|
||||
assert docstring.returns.description == "description"
|
||||
assert docstring.returns.is_generator
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 1
|
||||
assert docstring.many_returns[0] == docstring.returns
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
:yields int: description
|
||||
"""
|
||||
)
|
||||
assert docstring.returns is not None
|
||||
assert docstring.returns.type_name == "int"
|
||||
assert docstring.returns.description == "description"
|
||||
assert docstring.returns.is_generator
|
||||
assert docstring.many_returns is not None
|
||||
assert len(docstring.many_returns) == 1
|
||||
assert docstring.many_returns[0] == docstring.returns
|
||||
|
||||
|
||||
def test_raises() -> None:
|
||||
"""Test parsing raises."""
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
"""
|
||||
)
|
||||
assert len(docstring.raises) == 0
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
:raises: description
|
||||
"""
|
||||
)
|
||||
assert len(docstring.raises) == 1
|
||||
assert docstring.raises[0].type_name is None
|
||||
assert docstring.raises[0].description == "description"
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description
|
||||
:raises ValueError: description
|
||||
"""
|
||||
)
|
||||
assert len(docstring.raises) == 1
|
||||
assert docstring.raises[0].type_name == "ValueError"
|
||||
assert docstring.raises[0].description == "description"
|
||||
|
||||
|
||||
def test_broken_meta() -> None:
|
||||
"""Test parsing broken meta."""
|
||||
with pytest.raises(ParseError):
|
||||
parse(":")
|
||||
|
||||
with pytest.raises(ParseError):
|
||||
parse(":param herp derp")
|
||||
|
||||
with pytest.raises(ParseError):
|
||||
parse(":param: invalid")
|
||||
|
||||
with pytest.raises(ParseError):
|
||||
parse(":param with too many args: desc")
|
||||
|
||||
# these should not raise any errors
|
||||
parse(":sthstrange: desc")
|
||||
|
||||
|
||||
def test_deprecation() -> None:
|
||||
"""Test parsing deprecation notes."""
|
||||
docstring = parse(":deprecation: 1.1.0 this function will be removed")
|
||||
assert docstring.deprecation is not None
|
||||
assert docstring.deprecation.version == "1.1.0"
|
||||
assert docstring.deprecation.description == "this function will be removed"
|
||||
|
||||
docstring = parse(":deprecation: this function will be removed")
|
||||
assert docstring.deprecation is not None
|
||||
assert docstring.deprecation.version is None
|
||||
assert docstring.deprecation.description == "this function will be removed"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"rendering_style, expected",
|
||||
[
|
||||
(
|
||||
RenderingStyle.COMPACT,
|
||||
"Short description.\n"
|
||||
"\n"
|
||||
"Long description.\n"
|
||||
"\n"
|
||||
":param int foo: a description\n"
|
||||
":param int bar: another description\n"
|
||||
":returns float: a return",
|
||||
),
|
||||
(
|
||||
RenderingStyle.CLEAN,
|
||||
"Short description.\n"
|
||||
"\n"
|
||||
"Long description.\n"
|
||||
"\n"
|
||||
":param int foo: a description\n"
|
||||
":param int bar: another description\n"
|
||||
":returns float: a return",
|
||||
),
|
||||
(
|
||||
RenderingStyle.EXPANDED,
|
||||
"Short description.\n"
|
||||
"\n"
|
||||
"Long description.\n"
|
||||
"\n"
|
||||
":param foo:\n"
|
||||
" a description\n"
|
||||
":type foo: int\n"
|
||||
":param bar:\n"
|
||||
" another description\n"
|
||||
":type bar: int\n"
|
||||
":returns:\n"
|
||||
" a return\n"
|
||||
":rtype: float",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_compose(rendering_style: RenderingStyle, expected: str) -> None:
|
||||
"""Test compose"""
|
||||
|
||||
docstring = parse(
|
||||
"""
|
||||
Short description.
|
||||
|
||||
Long description.
|
||||
|
||||
:param int foo: a description
|
||||
:param int bar: another description
|
||||
:return float: a return
|
||||
"""
|
||||
)
|
||||
assert compose(docstring, rendering_style=rendering_style) == expected
|
||||
|
||||
|
||||
def test_short_rtype() -> None:
|
||||
"""Test abbreviated docstring with only return type information."""
|
||||
string = "Short description.\n\n:rtype: float"
|
||||
docstring = parse(string)
|
||||
rendering_style = RenderingStyle.EXPANDED
|
||||
assert compose(docstring, rendering_style=rendering_style) == string
|
||||
@@ -0,0 +1,64 @@
|
||||
"""Test for utility functions."""
|
||||
|
||||
from docstring_parser.common import DocstringReturns
|
||||
from docstring_parser.util import combine_docstrings
|
||||
|
||||
|
||||
def test_combine_docstrings() -> None:
|
||||
"""Test combine_docstrings wrapper."""
|
||||
|
||||
def fun1(arg_a, arg_b, arg_c, arg_d):
|
||||
"""short_description: fun1
|
||||
|
||||
:param arg_a: fun1
|
||||
:param arg_b: fun1
|
||||
:return: fun1
|
||||
"""
|
||||
assert arg_a and arg_b and arg_c and arg_d
|
||||
|
||||
def fun2(arg_b, arg_c, arg_d, arg_e):
|
||||
"""short_description: fun2
|
||||
|
||||
long_description: fun2
|
||||
|
||||
:param arg_b: fun2
|
||||
:param arg_c: fun2
|
||||
:param arg_e: fun2
|
||||
"""
|
||||
assert arg_b and arg_c and arg_d and arg_e
|
||||
|
||||
@combine_docstrings(fun1, fun2)
|
||||
def decorated1(arg_a, arg_b, arg_c, arg_d, arg_e, arg_f):
|
||||
"""
|
||||
:param arg_e: decorated
|
||||
:param arg_f: decorated
|
||||
"""
|
||||
assert arg_a and arg_b and arg_c and arg_d and arg_e and arg_f
|
||||
|
||||
assert decorated1.__doc__ == (
|
||||
"short_description: fun2\n"
|
||||
"\n"
|
||||
"long_description: fun2\n"
|
||||
"\n"
|
||||
":param arg_a: fun1\n"
|
||||
":param arg_b: fun1\n"
|
||||
":param arg_c: fun2\n"
|
||||
":param arg_e: fun2\n"
|
||||
":param arg_f: decorated\n"
|
||||
":returns: fun1"
|
||||
)
|
||||
|
||||
@combine_docstrings(fun1, fun2, exclude=[DocstringReturns])
|
||||
def decorated2(arg_a, arg_b, arg_c, arg_d, arg_e, arg_f):
|
||||
assert arg_a and arg_b and arg_c and arg_d and arg_e and arg_f
|
||||
|
||||
assert decorated2.__doc__ == (
|
||||
"short_description: fun2\n"
|
||||
"\n"
|
||||
"long_description: fun2\n"
|
||||
"\n"
|
||||
":param arg_a: fun1\n"
|
||||
":param arg_b: fun1\n"
|
||||
":param arg_c: fun2\n"
|
||||
":param arg_e: fun2"
|
||||
)
|
||||
Reference in New Issue
Block a user