From 67c2edc7ce13124c8db591940bcc1f430d9b5599 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Fri, 17 Jul 2020 18:18:33 -0700 Subject: [PATCH 1/5] Fix param parsing. Closes #285 This fixes two tings: - When first sentence of the docstring is onteh first line, Parameters is not properly parse, which for example mis parsed numpy.array docstring. - many project have paremeters description list with ` :` afer the name, even if no type is present. If there is no space after the `:` the parameter name includes the ` :` which is most likely wrong. --- numpydoc/docscrape.py | 6 ++++-- numpydoc/tests/test_docscrape.py | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/numpydoc/docscrape.py b/numpydoc/docscrape.py index d79992cb..2b992d8a 100644 --- a/numpydoc/docscrape.py +++ b/numpydoc/docscrape.py @@ -219,12 +219,14 @@ def _read_sections(self): yield name, self._strip(data[2:]) def _parse_param_list(self, content, single_element_is_type=False): + content = dedent_lines(content) r = Reader(content) params = [] while not r.eof(): header = r.read().strip() - if ' : ' in header: - arg_name, arg_type = header.split(' : ', maxsplit=1) + if ' :' in header: + arg_name, arg_type = header.split(' :', maxsplit=1) + arg_name, arg_type = arg_name.strip(), arg_type.strip() else: if single_element_is_type: arg_name, arg_type = '', header diff --git a/numpydoc/tests/test_docscrape.py b/numpydoc/tests/test_docscrape.py index 2ab0218a..d71e0105 100644 --- a/numpydoc/tests/test_docscrape.py +++ b/numpydoc/tests/test_docscrape.py @@ -183,7 +183,12 @@ def test_extended_summary(): assert doc['Extended Summary'][0].startswith('The multivariate normal') -def test_parameters(): +@pytest.mark.parametrize('sig_on_first_line', (True, False)) +def test_parameters(sig_on_first_line): + if sig_on_first_line: + doc = NumpyDocString(doc_txt.lstrip()) + else: + doc = NumpyDocString(doc_txt) assert len(doc['Parameters']) == 4 names = [n for n, _, _ in doc['Parameters']] assert all(a == b for a, b in zip(names, ['mean', 'cov', 'shape'])) @@ -921,6 +926,20 @@ class BadSection: def test_empty_first_line(): assert doc7['Summary'][0].startswith('Doc starts') +doc8 = NumpyDocString(""" + + Parameters wit colon and no types: + + Parameters + ---------- + + data : + some stuff, technically invalid + """) + + +def test_trailing_colon(): + assert doc8['Parameters'][0].name == 'data' def test_no_summary(): str(SphinxDocString(""" From c76c3cf2cc2f7d57dbce484ba73c1d66bbce6eba Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Thu, 23 Jul 2020 20:51:28 -0700 Subject: [PATCH 2/5] test fixture --- numpydoc/tests/test_docscrape.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/numpydoc/tests/test_docscrape.py b/numpydoc/tests/test_docscrape.py index d71e0105..71374d5b 100644 --- a/numpydoc/tests/test_docscrape.py +++ b/numpydoc/tests/test_docscrape.py @@ -133,7 +133,13 @@ :refguide: random;distributions, random;gauss ''' -doc = NumpyDocString(doc_txt) + +@pytest.fixture(params=['',''], ids=["flush", "newline_indented"]) +def doc(request): + return NumpyDocString(doc_txt) + + +doc_firstline = NumpyDocString(doc_txt.lstrip()) doc_yields_txt = """ Test generator @@ -169,7 +175,7 @@ doc_sent = NumpyDocString(doc_sent_txt) -def test_signature(): +def test_signature(doc): assert doc['Signature'].startswith('numpy.multivariate_normal(') assert doc['Signature'].endswith('spam=None)') @@ -183,12 +189,7 @@ def test_extended_summary(): assert doc['Extended Summary'][0].startswith('The multivariate normal') -@pytest.mark.parametrize('sig_on_first_line', (True, False)) -def test_parameters(sig_on_first_line): - if sig_on_first_line: - doc = NumpyDocString(doc_txt.lstrip()) - else: - doc = NumpyDocString(doc_txt) +def test_parameters(doc): assert len(doc['Parameters']) == 4 names = [n for n, _, _ in doc['Parameters']] assert all(a == b for a, b in zip(names, ['mean', 'cov', 'shape'])) @@ -210,7 +211,7 @@ def test_parameters(sig_on_first_line): assert desc[0].startswith('The type and size') -def test_other_parameters(): +def test_other_parameters(doc): assert len(doc['Other Parameters']) == 1 assert [n for n, _, _ in doc['Other Parameters']] == ['spam'] arg, arg_type, desc = doc['Other Parameters'][0] @@ -218,7 +219,8 @@ def test_other_parameters(): assert desc[0].startswith('A parrot off its mortal coil') -def test_returns(): + +def test_returns(doc): assert len(doc['Returns']) == 3 arg, arg_type, desc = doc['Returns'][0] assert arg == 'out' From f8b424afd2425a0adbcbf6eba4d2085aa2d43562 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Thu, 23 Jul 2020 20:56:14 -0700 Subject: [PATCH 3/5] make doc a fixture --- numpydoc/tests/test_docscrape.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/numpydoc/tests/test_docscrape.py b/numpydoc/tests/test_docscrape.py index 71374d5b..0398e65d 100644 --- a/numpydoc/tests/test_docscrape.py +++ b/numpydoc/tests/test_docscrape.py @@ -134,13 +134,11 @@ ''' -@pytest.fixture(params=['',''], ids=["flush", "newline_indented"]) +@pytest.fixture(params=['','\n '], ids=["flush", "newline_indented"]) def doc(request): - return NumpyDocString(doc_txt) + return NumpyDocString(request.param+doc_txt) -doc_firstline = NumpyDocString(doc_txt.lstrip()) - doc_yields_txt = """ Test generator @@ -180,12 +178,12 @@ def test_signature(doc): assert doc['Signature'].endswith('spam=None)') -def test_summary(): +def test_summary(doc): assert doc['Summary'][0].startswith('Draw values') assert doc['Summary'][-1].endswith('covariance.') -def test_extended_summary(): +def test_extended_summary(doc): assert doc['Extended Summary'][0].startswith('The multivariate normal') @@ -349,23 +347,23 @@ def dummy_func(arg): or 'function dummy_func' in str(e)) -def test_notes(): +def test_notes(doc): assert doc['Notes'][0].startswith('Instead') assert doc['Notes'][-1].endswith('definite.') assert len(doc['Notes']) == 17 -def test_references(): +def test_references(doc): assert doc['References'][0].startswith('..') assert doc['References'][-1].endswith('2001.') -def test_examples(): +def test_examples(doc): assert doc['Examples'][0].startswith('>>>') assert doc['Examples'][-1].endswith('True]') -def test_index(): +def test_index(doc): assert doc['index']['default'] == 'random' assert len(doc['index']) == 2 assert len(doc['index']['refguide']) == 2 @@ -389,7 +387,7 @@ def line_by_line_compare(a, b, n_lines=None): assert aa == bb -def test_str(): +def test_str(doc): # doc_txt has the order of Notes and See Also sections flipped. # This should be handled automatically, and so, one thing this test does # is to make sure that See Also precedes Notes in the output. From 083aebf512e7d783e5ee894298762693bdb15b30 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Mon, 10 Aug 2020 09:02:22 -0700 Subject: [PATCH 4/5] Update numpydoc/tests/test_docscrape.py Co-authored-by: Eric Larson --- numpydoc/tests/test_docscrape.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numpydoc/tests/test_docscrape.py b/numpydoc/tests/test_docscrape.py index 0398e65d..ecfd2629 100644 --- a/numpydoc/tests/test_docscrape.py +++ b/numpydoc/tests/test_docscrape.py @@ -928,7 +928,7 @@ def test_empty_first_line(): doc8 = NumpyDocString(""" - Parameters wit colon and no types: + Parameters with colon and no types: Parameters ---------- From c39088665e722092a6519b99f0e5b3caf3377cf1 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Mon, 10 Aug 2020 09:02:31 -0700 Subject: [PATCH 5/5] Update numpydoc/tests/test_docscrape.py Co-authored-by: Eric Larson --- numpydoc/tests/test_docscrape.py | 1 + 1 file changed, 1 insertion(+) diff --git a/numpydoc/tests/test_docscrape.py b/numpydoc/tests/test_docscrape.py index ecfd2629..a0b6d2e3 100644 --- a/numpydoc/tests/test_docscrape.py +++ b/numpydoc/tests/test_docscrape.py @@ -941,6 +941,7 @@ def test_empty_first_line(): def test_trailing_colon(): assert doc8['Parameters'][0].name == 'data' + def test_no_summary(): str(SphinxDocString(""" Parameters