mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-08 06:44:46 +08:00
Merge remote-tracking branch 'origin/namedtuple' into dev
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -11,3 +11,4 @@
|
|||||||
/dist/
|
/dist/
|
||||||
jedi.egg-info/
|
jedi.egg-info/
|
||||||
record.json
|
record.json
|
||||||
|
/.cache/
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
"""
|
"""
|
||||||
Implementations of standard library functions, because it's not possible to
|
Implementations of standard library functions, because it's not possible to
|
||||||
understand them with Jedi.
|
understand them with Jedi.
|
||||||
|
|
||||||
|
To add a new implementation, create a function and add it to the
|
||||||
|
``_implemented`` dict at the bottom of this module.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
import collections
|
||||||
from jedi._compatibility import unicode
|
from jedi._compatibility import unicode
|
||||||
from jedi.evaluate import compiled
|
from jedi.evaluate import compiled
|
||||||
from jedi.evaluate import representation as er
|
from jedi.evaluate import representation as er
|
||||||
from jedi.evaluate import iterable
|
from jedi.evaluate import iterable
|
||||||
from jedi.evaluate.helpers import FakeArray, FakeStatement
|
from jedi.evaluate.helpers import FakeArray, FakeStatement
|
||||||
|
from jedi.parser import Parser
|
||||||
from jedi.parser import representation as pr
|
from jedi.parser import representation as pr
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
|
|
||||||
@@ -107,6 +113,49 @@ def builtins_reversed(evaluator, obj, params):
|
|||||||
return [er.Instance(evaluator, obj, objects)]
|
return [er.Instance(evaluator, obj, objects)]
|
||||||
|
|
||||||
|
|
||||||
|
def collections_namedtuple(evaluator, obj, params):
|
||||||
|
"""
|
||||||
|
Implementation of the namedtuple function.
|
||||||
|
|
||||||
|
This has to be done by processing the namedtuple class template and
|
||||||
|
evaluating the result.
|
||||||
|
|
||||||
|
.. note:: |jedi| only supports namedtuples on Python >2.6.
|
||||||
|
|
||||||
|
"""
|
||||||
|
# Namedtuples are not supported on Python 2.6
|
||||||
|
if not hasattr(collections, '_class_template'):
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Process arguments
|
||||||
|
name = _follow_param(evaluator, params, 0)[0].obj
|
||||||
|
_fields = _follow_param(evaluator, params, 1)[0]
|
||||||
|
if isinstance(_fields, compiled.CompiledObject):
|
||||||
|
fields = _fields.obj.replace(',', ' ').split()
|
||||||
|
elif isinstance(_fields, iterable.Array):
|
||||||
|
try:
|
||||||
|
fields = [v.obj for v in _fields.values()]
|
||||||
|
except AttributeError:
|
||||||
|
return []
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Build source
|
||||||
|
source = collections._class_template.format(
|
||||||
|
typename=name,
|
||||||
|
field_names=fields,
|
||||||
|
num_fields=len(fields),
|
||||||
|
arg_list=', '.join(fields),
|
||||||
|
repr_fmt=', '.join(collections._repr_template.format(name=name) for name in fields),
|
||||||
|
field_defs='\n'.join(collections._field_template.format(index=index, name=name)
|
||||||
|
for index, name in enumerate(fields))
|
||||||
|
)
|
||||||
|
|
||||||
|
# Parse source
|
||||||
|
generated_class = Parser(unicode(source)).module.subscopes[0]
|
||||||
|
return [er.Class(evaluator, generated_class)]
|
||||||
|
|
||||||
|
|
||||||
def _return_first_param(evaluator, obj, params):
|
def _return_first_param(evaluator, obj, params):
|
||||||
if len(params) == 1:
|
if len(params) == 1:
|
||||||
return _follow_param(evaluator, params, 0)
|
return _follow_param(evaluator, params, 0)
|
||||||
@@ -128,4 +177,7 @@ _implemented = {
|
|||||||
'load': lambda *args: [],
|
'load': lambda *args: [],
|
||||||
'loads': lambda *args: [],
|
'loads': lambda *args: [],
|
||||||
},
|
},
|
||||||
|
'collections': {
|
||||||
|
'namedtuple': collections_namedtuple,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
37
test/test_integration_stdlib.py
Normal file
37
test/test_integration_stdlib.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
"""
|
||||||
|
Tests of various stdlib related things that could not be tested
|
||||||
|
with "Black Box Tests".
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
from jedi import Script
|
||||||
|
from jedi._compatibility import is_py26
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(['letter', 'expected'], [
|
||||||
|
('n', ['name']),
|
||||||
|
('s', ['smart']),
|
||||||
|
])
|
||||||
|
def test_namedtuple_str(letter, expected):
|
||||||
|
source = "import collections\n" + \
|
||||||
|
"Person = collections.namedtuple('Person', 'name smart')\n" + \
|
||||||
|
"dave = Person('Dave', False)\n" + \
|
||||||
|
"dave.%s" % letter
|
||||||
|
result = Script(source).completions()
|
||||||
|
completions = set(r.name for r in result)
|
||||||
|
if is_py26:
|
||||||
|
assert completions == set()
|
||||||
|
else:
|
||||||
|
assert completions == set(expected)
|
||||||
|
|
||||||
|
|
||||||
|
def test_namedtuple_list():
|
||||||
|
source = "import collections\n" + \
|
||||||
|
"Cat = collections.namedtuple('Person', ['legs', u'length', 'large'])\n" + \
|
||||||
|
"garfield = Cat(4, '85cm', True)\n" + \
|
||||||
|
"garfield.l"
|
||||||
|
result = Script(source).completions()
|
||||||
|
completions = set(r.name for r in result)
|
||||||
|
if is_py26:
|
||||||
|
assert completions == set()
|
||||||
|
else:
|
||||||
|
assert completions == set(['legs', 'length', 'large'])
|
||||||
Reference in New Issue
Block a user