Skip to content

Commit

Permalink
Improve getting signatures from text
Browse files Browse the repository at this point in the history
- Discard IPython default signatures in case we're able to find others.
- Get signatures written in multiple lines at the beginning of
docstrings.
  • Loading branch information
ccordoba12 committed Oct 17, 2023
1 parent 70cb79e commit cd34799
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
32 changes: 29 additions & 3 deletions spyder_kernels/utils/dochelpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,38 @@ def getsignaturefromtext(text, objname):
# first match.
sig = sigs[0] if objname else sigs[0][1]
else:
# Default signatures returned by IPython.
# Notes:
# * These are not real signatures but only used to provide a
# placeholder.
# * We skip them if we can find other signatures in `text`.
# * This is necessary because we also use this function in Spyder
# to parse the content of inspect replies that come from the
# kernel, which can include these signatures.
default_ipy_sigs = [
'(*args, **kwargs)',
'(self, /, *args, **kwargs)'
]

if objname:
sig = sigs[0]
real_sigs = [s for s in sigs if s not in default_ipy_sigs]

if real_sigs:
sig = real_sigs[0]
else:
sig = sigs[0]
else:
valid_sigs = [s for s in sigs if s[0].isidentifier()]

if valid_sigs:
sig = valid_sigs[0][1]
real_sigs = [
s for s in valid_sigs if s[1] not in default_ipy_sigs
]

if real_sigs:
sig = real_sigs[0][1]
else:
sig = valid_sigs[0][1]

return sig

Expand All @@ -225,7 +251,7 @@ def getargspecfromtext(text):
This will return something like `(x, y, k=1)`.
"""
blocks = text.split("\n\n")
first_block = blocks[0].strip()
first_block = blocks[0].strip().replace('\n', '')
return getsignaturefromtext(first_block, '')


Expand Down
17 changes: 17 additions & 0 deletions spyder_kernels/utils/tests/test_dochelpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,22 @@ def foo():
assert signature == "(x, y)"


def test_multiline_signature():
"""
Test that we can get signatures splitted into multiple lines in a
docstring.
"""
def foo():
"""
foo(x,
y)
This is a docstring.
"""

signature = getargspecfromtext(foo.__doc__)
assert signature.startswith("(x, ")


if __name__ == "__main__":
pytest.main()

0 comments on commit cd34799

Please sign in to comment.