diff --git a/nedoc/docstring.py b/nedoc/docstring.py index 99c67d7..280c8e0 100644 --- a/nedoc/docstring.py +++ b/nedoc/docstring.py @@ -61,6 +61,7 @@ def parse_docstring( if docstring is None: return ParsedDocString(None, None) + orig_docstring = docstring docstring = merge_first_line(docstring.strip()) ds_style = STYLE_MAP.get(style) @@ -74,14 +75,14 @@ def parse_docstring( description = description.lstrip() return ParsedDocString(docline, description) - dstr = docstring_parser.parse(docstring, ds_style) + dstr = docstring_parser.parse(orig_docstring, ds_style) subsections = [ (m.args[0].replace("_", " ").capitalize(), m.description) for m in dstr.meta if len(m.args) == 1 and m.args[0] not in ("param", "returns", "raises") ] return ParsedDocString( - dstr.short_description, + docstring.split("\n", 1)[0], dstr.long_description, dstr.params, dstr.returns, diff --git a/nedoc/markup/md.py b/nedoc/markup/md.py index dfa6f93..a37a3f2 100644 --- a/nedoc/markup/md.py +++ b/nedoc/markup/md.py @@ -70,8 +70,10 @@ def render_link(self, element: Link) -> str: if item is not None: return self.render_intradoc_link(target=item, element=element) - logging.warning(f"Intradoc link `{original_link}` in {render_cname(self.unit.cname)} " - "could not be resolved") + logging.warning( + f"Intradoc link `{original_link}` in {render_cname(self.unit.cname)} " + "could not be resolved" + ) return super().render_link(element) @@ -102,7 +104,7 @@ def get_intradoc_link(element: Link) -> Optional[str]: def convert_markdown_to_html( - ctx: GlobalContext, unit: Unit, text: Optional[str] + ctx: GlobalContext, unit: Unit, text: Optional[str] ) -> str: if text is None: return "" diff --git a/tests/markup/test_markdown.py b/tests/markup/test_markdown.py index fd952f7..14dddce 100644 --- a/tests/markup/test_markdown.py +++ b/tests/markup/test_markdown.py @@ -1,4 +1,5 @@ from nedoc.config import DocstringStyle, Markup + from ..utils.project_builder import ProjectBuilder, render_docline, render_docstring @@ -346,7 +347,9 @@ def test_markdown_link_missing_parent(tmp_path): def test_markdown_in_argument_docstring(tmp_path, snapshot): - rendered = render_docstring(tmp_path, ''' + rendered = render_docstring( + tmp_path, + ''' def target(a: int): """ Documentation. @@ -356,12 +359,17 @@ def target(a: int): def bar(): pass -''', style=DocstringStyle.RST, markup=Markup.MARKDOWN) +''', + style=DocstringStyle.RST, + markup=Markup.MARKDOWN, + ) snapshot.assert_match(rendered, "expected.html") def test_markdown_in_docline(tmp_path, snapshot): - rendered = render_docline(tmp_path, ''' + rendered = render_docline( + tmp_path, + ''' def target(a: int): """ Documentation with **bold text** and a [link](`.bar`). @@ -369,7 +377,9 @@ def target(a: int): def bar(): pass -''', markup=Markup.MARKDOWN) +''', + markup=Markup.MARKDOWN, + ) snapshot.assert_match(rendered, "expected.html") diff --git a/tests/test_docstring.py b/tests/test_docstring.py index 758b641..2d09fe0 100644 --- a/tests/test_docstring.py +++ b/tests/test_docstring.py @@ -3,7 +3,7 @@ from nedoc.config import DocstringStyle from nedoc.docstring import merge_first_line, parse_docstring -from .utils.project_builder import render_docstring +from .utils.project_builder import parse_unit_with_ctx, render_docstring def test_merge_first_list(): @@ -90,3 +90,39 @@ def __init__(self, a: int, b: int): copy_init_docstring=True, ) snapshot.assert_match(rendered, "expected.html") + + +def test_parse_docstring_parameters(tmp_path, snapshot): + ctx, unit = parse_unit_with_ctx( + tmp_path, + ''' +def target(self, a: int, b: int): + """ + Some documentation. + + :param a: first argument + :param b: second argument + """ +''', + ) + docstring = ctx.parsed_docstring(unit) + assert len(docstring.params) == 2 + assert docstring.params[0].arg_name == "a" + assert docstring.params[1].arg_name == "b" + + +def test_parse_docstring_parameters_no_docline(tmp_path, snapshot): + ctx, unit = parse_unit_with_ctx( + tmp_path, + ''' +def target(self, a: int, b: int): + """ + :param a: first argument + :param b: second argument + """ +''', + ) + docstring = ctx.parsed_docstring(unit) + assert len(docstring.params) == 2 + assert docstring.params[0].arg_name == "a" + assert docstring.params[1].arg_name == "b" diff --git a/tests/utils/project_builder.py b/tests/utils/project_builder.py index f999c83..37bbab1 100644 --- a/tests/utils/project_builder.py +++ b/tests/utils/project_builder.py @@ -3,6 +3,7 @@ from nedoc.config import DocstringStyle, Markup, create_config_file, parse_config from nedoc.core import Core, GlobalContext +from nedoc.docstring import ParsedDocString from nedoc.markup.md import convert_markdown_to_html from nedoc.render import RenderContext, Renderer from nedoc.unit import Unit @@ -14,6 +15,7 @@ class ProjectBuilder: It puts all files within a `src` directory and then points nedoc to it. """ + def __init__(self, path: Path, name="project"): self.name = name self.root_dir = path.joinpath(name) @@ -79,13 +81,24 @@ def markdown(self, path: str) -> str: unit = self.get(path) return render_markdown(self.core.gctx, unit) + def parsed_docstring(self, unit: Unit) -> ParsedDocString: + """ + Gets the parsed docstring of the given unit. + """ + render_ctx = RenderContext(unit, self.core.gctx) + return render_ctx.get_parsed_docstring(unit) + -def parse_unit(tmpdir: Path, code: str, name="target", file_name="foo", **config_args) -> Unit: - return parse_unit_inner(tmpdir, code, name, file_name=file_name, **config_args)[1] +def parse_unit( + tmpdir: Path, code: str, name="target", file_name="foo", **config_args +) -> Unit: + return parse_unit_with_ctx(tmpdir, code, name, file_name=file_name, **config_args)[ + 1 + ] -def parse_unit_inner( - tmpdir: Path, code: str, name: str, file_name="foo", **config_args +def parse_unit_with_ctx( + tmpdir: Path, code: str, name="target", file_name="foo", **config_args ) -> Tuple[BuiltProject, Unit]: pb = ProjectBuilder(tmpdir) pb.file(f"{file_name}.py", code) @@ -100,12 +113,12 @@ def render_markdown(gctx: GlobalContext, unit: Unit) -> str: def render_docstring(tmpdir: Path, code: str, name="target", **config_args) -> str: - built, unit = parse_unit_inner(tmpdir, code, name=name, **config_args) + built, unit = parse_unit_with_ctx(tmpdir, code, name=name, **config_args) return render_template(built, unit, "docstring.mako", "render_docstring") def render_docline(tmpdir: Path, code: str, name="target", **config_args) -> str: - built, unit = parse_unit_inner(tmpdir, code, name=name, **config_args) + built, unit = parse_unit_with_ctx(tmpdir, code, name=name, **config_args) return render_template(built, unit, "docstring.mako", "render_docline")