mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 14:34:31 +08:00
Merge branch 'add-numpydoc-support' of git://github.com/immerrr/jedi into dev
This commit is contained in:
@@ -6,7 +6,7 @@ Changelog
|
|||||||
0.8.1 (2014-07-23)
|
0.8.1 (2014-07-23)
|
||||||
+++++++++++++++++++
|
+++++++++++++++++++
|
||||||
|
|
||||||
* Bugfix release, the last release forgot to include files that improve
|
- Bugfix release, the last release forgot to include files that improve
|
||||||
autocompletion for builtin libraries. Fixed.
|
autocompletion for builtin libraries. Fixed.
|
||||||
|
|
||||||
0.8.0 (2014-05-05)
|
0.8.0 (2014-05-05)
|
||||||
@@ -16,26 +16,27 @@ Changelog
|
|||||||
drastically. Loading times are down as well (it takes basically as long as an
|
drastically. Loading times are down as well (it takes basically as long as an
|
||||||
import).
|
import).
|
||||||
- REPL completion is starting to become usable.
|
- REPL completion is starting to become usable.
|
||||||
- Various small API changes. Generally this released focuses on stability and
|
- Various small API changes. Generally this release focuses on stability and
|
||||||
refactoring of internal APIs.
|
refactoring of internal APIs.
|
||||||
- Introducing operator precedence, which makes calculating correct Array indices
|
- Introducing operator precedence, which makes calculating correct Array
|
||||||
and ``__getattr__`` strings possible.
|
indices and ``__getattr__`` strings possible.
|
||||||
|
|
||||||
0.7.0 (2013-08-09)
|
0.7.0 (2013-08-09)
|
||||||
++++++++++++++++++
|
++++++++++++++++++
|
||||||
|
|
||||||
- Switched from LGPL to MIT license
|
- Switched from LGPL to MIT license.
|
||||||
- Added an Interpreter class to the API to make autocompletion in REPL possible.
|
- Added an Interpreter class to the API to make autocompletion in REPL
|
||||||
- Added autocompletion support for namespace packages
|
possible.
|
||||||
- Add sith.py, a new random testing method
|
- Added autocompletion support for namespace packages.
|
||||||
|
- Add sith.py, a new random testing method.
|
||||||
|
|
||||||
0.6.0 (2013-05-14)
|
0.6.0 (2013-05-14)
|
||||||
++++++++++++++++++
|
++++++++++++++++++
|
||||||
|
|
||||||
- Much faster parser with builtin part caching
|
- Much faster parser with builtin part caching.
|
||||||
- A test suite, thanks @tkf
|
- A test suite, thanks @tkf.
|
||||||
|
|
||||||
0.5 versions (2012)
|
0.5 versions (2012)
|
||||||
+++++++++++++++++++
|
+++++++++++++++++++
|
||||||
|
|
||||||
- Initial development
|
- Initial development.
|
||||||
|
|||||||
@@ -119,10 +119,11 @@ http://sphinx-doc.org/domains.html#info-field-lists
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
def myfunction(node):
|
def myfunction(node, foo):
|
||||||
"""Do something with a ``node``.
|
"""Do something with a ``node``.
|
||||||
|
|
||||||
:type node: ProgramNode
|
:type node: ProgramNode
|
||||||
|
:param str foo: foo parameter description
|
||||||
|
|
||||||
"""
|
"""
|
||||||
node.| # complete here
|
node.| # complete here
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ As an addition to parameter searching, this module also provides return
|
|||||||
annotations.
|
annotations.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from ast import literal_eval
|
||||||
import re
|
import re
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
@@ -24,6 +25,7 @@ from jedi.common import indent_block
|
|||||||
|
|
||||||
DOCSTRING_PARAM_PATTERNS = [
|
DOCSTRING_PARAM_PATTERNS = [
|
||||||
r'\s*:type\s+%s:\s*([^\n]+)', # Sphinx
|
r'\s*:type\s+%s:\s*([^\n]+)', # Sphinx
|
||||||
|
r'\s*:param\s+(\w+)\s+%s:[^\n]+', # Sphinx param with type
|
||||||
r'\s*@type\s+%s:\s*([^\n]+)', # Epydoc
|
r'\s*@type\s+%s:\s*([^\n]+)', # Epydoc
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -35,26 +37,44 @@ DOCSTRING_RETURN_PATTERNS = [
|
|||||||
REST_ROLE_PATTERN = re.compile(r':[^`]+:`([^`]+)`')
|
REST_ROLE_PATTERN = re.compile(r':[^`]+:`([^`]+)`')
|
||||||
|
|
||||||
|
|
||||||
@memoize_default(None, evaluator_is_first_arg=True)
|
try:
|
||||||
def follow_param(evaluator, param):
|
from numpydoc.docscrape import NumpyDocString
|
||||||
func = param.parent_function
|
except ImportError:
|
||||||
param_str = _search_param_in_docstr(func.raw_doc, str(param.get_name()))
|
def _search_param_in_numpydocstr(docstr, param_str):
|
||||||
return _evaluate_for_statement_string(evaluator, param_str, param.get_parent_until())
|
return []
|
||||||
|
else:
|
||||||
|
def _search_param_in_numpydocstr(docstr, param_str):
|
||||||
|
"""Search `docstr` (in numpydoc format) for type(-s) of `param_str`."""
|
||||||
|
params = NumpyDocString(docstr)._parsed_data['Parameters']
|
||||||
|
for p_name, p_type, p_descr in params:
|
||||||
|
if p_name == param_str:
|
||||||
|
m = re.match('([^,]+(,[^,]+)*?)(,[ ]*optional)?$', p_type)
|
||||||
|
if m:
|
||||||
|
p_type = m.group(1)
|
||||||
|
|
||||||
|
if p_type.startswith('{'):
|
||||||
|
types = set(type(x).__name__ for x in literal_eval(p_type))
|
||||||
|
return list(types)
|
||||||
|
else:
|
||||||
|
return [p_type]
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
def _search_param_in_docstr(docstr, param_str):
|
def _search_param_in_docstr(docstr, param_str):
|
||||||
"""
|
"""
|
||||||
Search `docstr` for a type of `param_str`.
|
Search `docstr` for type(-s) of `param_str`.
|
||||||
|
|
||||||
>>> _search_param_in_docstr(':type param: int', 'param')
|
>>> _search_param_in_docstr(':type param: int', 'param')
|
||||||
'int'
|
['int']
|
||||||
>>> _search_param_in_docstr('@type param: int', 'param')
|
>>> _search_param_in_docstr('@type param: int', 'param')
|
||||||
'int'
|
['int']
|
||||||
>>> _search_param_in_docstr(
|
>>> _search_param_in_docstr(
|
||||||
... ':type param: :class:`threading.Thread`', 'param')
|
... ':type param: :class:`threading.Thread`', 'param')
|
||||||
'threading.Thread'
|
['threading.Thread']
|
||||||
>>> _search_param_in_docstr('no document', 'param') is None
|
>>> bool(_search_param_in_docstr('no document', 'param'))
|
||||||
True
|
False
|
||||||
|
>>> _search_param_in_docstr(':param int param: some description', 'param')
|
||||||
|
['int']
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# look at #40 to see definitions of those params
|
# look at #40 to see definitions of those params
|
||||||
@@ -63,9 +83,10 @@ def _search_param_in_docstr(docstr, param_str):
|
|||||||
for pattern in patterns:
|
for pattern in patterns:
|
||||||
match = pattern.search(docstr)
|
match = pattern.search(docstr)
|
||||||
if match:
|
if match:
|
||||||
return _strip_rst_role(match.group(1))
|
return [_strip_rst_role(match.group(1))]
|
||||||
|
|
||||||
return None
|
return (_search_param_in_numpydocstr(docstr, param_str) or
|
||||||
|
[])
|
||||||
|
|
||||||
|
|
||||||
def _strip_rst_role(type_str):
|
def _strip_rst_role(type_str):
|
||||||
@@ -126,6 +147,17 @@ def _evaluate_for_statement_string(evaluator, string, module):
|
|||||||
return list(chain.from_iterable(it)) or definitions
|
return list(chain.from_iterable(it)) or definitions
|
||||||
|
|
||||||
|
|
||||||
|
@memoize_default(None, evaluator_is_first_arg=True)
|
||||||
|
def follow_param(evaluator, param):
|
||||||
|
func = param.parent_function
|
||||||
|
|
||||||
|
return [p
|
||||||
|
for param_str in _search_param_in_docstr(func.raw_doc,
|
||||||
|
str(param.get_name()))
|
||||||
|
for p in _evaluate_for_statement_string(evaluator, param_str,
|
||||||
|
param.get_parent_until())]
|
||||||
|
|
||||||
|
|
||||||
@memoize_default(None, evaluator_is_first_arg=True)
|
@memoize_default(None, evaluator_is_first_arg=True)
|
||||||
def find_return_types(evaluator, func):
|
def find_return_types(evaluator, func):
|
||||||
def search_return_in_docstr(code):
|
def search_return_in_docstr(code):
|
||||||
|
|||||||
@@ -3,13 +3,14 @@
|
|||||||
# -----------------
|
# -----------------
|
||||||
# sphinx style
|
# sphinx style
|
||||||
# -----------------
|
# -----------------
|
||||||
def f(a, b, c, d):
|
def f(a, b, c, d, x):
|
||||||
""" asdfasdf
|
""" asdfasdf
|
||||||
:param a: blablabla
|
:param a: blablabla
|
||||||
:type a: str
|
:type a: str
|
||||||
:type b: (str, int)
|
:type b: (str, int)
|
||||||
:type c: threading.Thread
|
:type c: threading.Thread
|
||||||
:type d: :class:`threading.Thread`
|
:type d: :class:`threading.Thread`
|
||||||
|
:param str x: blablabla
|
||||||
:rtype: dict
|
:rtype: dict
|
||||||
"""
|
"""
|
||||||
#? str()
|
#? str()
|
||||||
@@ -22,23 +23,28 @@ def f(a, b, c, d):
|
|||||||
c.join
|
c.join
|
||||||
#? ['join']
|
#? ['join']
|
||||||
d.join
|
d.join
|
||||||
|
#? ['lower']
|
||||||
|
x.lower
|
||||||
|
|
||||||
#? dict()
|
#? dict()
|
||||||
f()
|
f()
|
||||||
|
|
||||||
# wrong declarations
|
# wrong declarations
|
||||||
def f(a, b):
|
def f(a, b, x):
|
||||||
"""
|
"""
|
||||||
:param a: Forgot type declaration
|
:param a: Forgot type declaration
|
||||||
:type a:
|
:type a:
|
||||||
:param b: Just something
|
:param b: Just something
|
||||||
:type b: ``
|
:type b: ``
|
||||||
|
:param x: Just something without type
|
||||||
:rtype:
|
:rtype:
|
||||||
"""
|
"""
|
||||||
#?
|
#?
|
||||||
a
|
a
|
||||||
#?
|
#?
|
||||||
b
|
b
|
||||||
|
#?
|
||||||
|
x
|
||||||
|
|
||||||
#?
|
#?
|
||||||
f()
|
f()
|
||||||
|
|||||||
@@ -6,6 +6,13 @@ from textwrap import dedent
|
|||||||
import jedi
|
import jedi
|
||||||
from ..helpers import unittest
|
from ..helpers import unittest
|
||||||
|
|
||||||
|
try:
|
||||||
|
import numpydoc
|
||||||
|
except ImportError:
|
||||||
|
numpydoc_unavailable = True
|
||||||
|
else:
|
||||||
|
numpydoc_unavailable = False
|
||||||
|
|
||||||
|
|
||||||
class TestDocstring(unittest.TestCase):
|
class TestDocstring(unittest.TestCase):
|
||||||
def test_function_doc(self):
|
def test_function_doc(self):
|
||||||
@@ -50,6 +57,16 @@ class TestDocstring(unittest.TestCase):
|
|||||||
names = [c.name for c in jedi.Script(s).completions()]
|
names = [c.name for c in jedi.Script(s).completions()]
|
||||||
assert 'start' in names
|
assert 'start' in names
|
||||||
|
|
||||||
|
def test_docstrings_param_type(self):
|
||||||
|
s = """
|
||||||
|
def func(arg):
|
||||||
|
'''
|
||||||
|
:param str arg: some description
|
||||||
|
'''
|
||||||
|
arg."""
|
||||||
|
names = [c.name for c in jedi.Script(s).completions()]
|
||||||
|
assert 'join' in names
|
||||||
|
|
||||||
def test_docstrings_type_str(self):
|
def test_docstrings_type_str(self):
|
||||||
s = """
|
s = """
|
||||||
def func(arg):
|
def func(arg):
|
||||||
@@ -87,3 +104,49 @@ class TestDocstring(unittest.TestCase):
|
|||||||
assert 'a' in names
|
assert 'a' in names
|
||||||
assert '__init__' in names
|
assert '__init__' in names
|
||||||
assert 'mro' not in names # Exists only for types.
|
assert 'mro' not in names # Exists only for types.
|
||||||
|
|
||||||
|
@unittest.skipIf(numpydoc_unavailable, 'numpydoc module is unavailable')
|
||||||
|
def test_numpydoc_docstring(self):
|
||||||
|
s = dedent('''
|
||||||
|
def foobar(x, y):
|
||||||
|
"""
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
x : int
|
||||||
|
y : str
|
||||||
|
"""
|
||||||
|
y.''')
|
||||||
|
names = [c.name for c in jedi.Script(s).completions()]
|
||||||
|
assert 'isupper' in names
|
||||||
|
assert 'capitalize' in names
|
||||||
|
|
||||||
|
@unittest.skipIf(numpydoc_unavailable, 'numpydoc module is unavailable')
|
||||||
|
def test_numpydoc_docstring_set_of_values(self):
|
||||||
|
s = dedent('''
|
||||||
|
def foobar(x, y):
|
||||||
|
"""
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
x : {'foo', 'bar', 100500}, optional
|
||||||
|
"""
|
||||||
|
x.''')
|
||||||
|
names = [c.name for c in jedi.Script(s).completions()]
|
||||||
|
assert 'isupper' in names
|
||||||
|
assert 'capitalize' in names
|
||||||
|
assert 'numerator' in names
|
||||||
|
|
||||||
|
@unittest.skipIf(numpydoc_unavailable, 'numpydoc module is unavailable')
|
||||||
|
def test_numpydoc_alternative_types(self):
|
||||||
|
s = dedent('''
|
||||||
|
def foobar(x, y):
|
||||||
|
"""
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
x : int or str or list
|
||||||
|
"""
|
||||||
|
x.''')
|
||||||
|
names = [c.name for c in jedi.Script(s).completions()]
|
||||||
|
assert 'isupper' in names
|
||||||
|
assert 'capitalize' in names
|
||||||
|
assert 'numerator' in names
|
||||||
|
assert 'append' in names
|
||||||
|
|||||||
Reference in New Issue
Block a user