1
0
forked from VimPlug/jedi

trying to fix the getattr mess with compiled

This commit is contained in:
Dave Halter
2014-01-10 13:36:29 +01:00
parent b1409c8f74
commit f868668f0e
6 changed files with 30 additions and 18 deletions

View File

@@ -258,7 +258,10 @@ class Evaluator(object):
call.stmt.parent = loop call.stmt.parent = loop
result += self.eval_statement(call.stmt) result += self.eval_statement(call.stmt)
else: else:
if isinstance(call, pr.Lambda): if isinstance(call, compiled.PyName):
print call, call.parent
result.append(call.parent)
elif isinstance(call, pr.Lambda):
result.append(er.Function(self, call)) result.append(er.Function(self, call))
# With things like params, these can also be functions... # With things like params, these can also be functions...
elif isinstance(call, pr.Base) and call.isinstance( elif isinstance(call, pr.Base) and call.isinstance(

View File

@@ -51,7 +51,9 @@ class PyObject(Base):
@underscore_memoization @underscore_memoization
def _cls(self): def _cls(self):
# Ensures that a PyObject is returned that is not an instance (like list) # Ensures that a PyObject is returned that is not an instance (like list)
if not (inspect.isclass(self.obj) or inspect.ismodule(self.obj)): if not (inspect.isclass(self.obj) or inspect.ismodule(self.obj)
or inspect.isbuiltin(self.obj) or inspect.ismethod(self.obj)
or inspect.ismethoddescriptor(self.obj)):
return PyObject(self.obj.__class__, self.parent, True) return PyObject(self.obj.__class__, self.parent, True)
return self return self
@@ -89,9 +91,12 @@ class PyName(object):
self._obj = obj self._obj = obj
self._name = name self._name = name
self.start_pos = 0, 0 # an illegal start_pos, to make sorting easy. self.start_pos = 0, 0 # an illegal start_pos, to make sorting easy.
#if not type(name) is str:
# print obj, name
# raise NotImplementedError()
def __repr__(self): def __repr__(self):
return '<%s: %s.%s>' % (type(self).__name__, self._obj.obj, self._name) return '<%s: (%s).%s>' % (type(self).__name__, repr(self._obj.obj), self._name)
@property @property
@underscore_memoization @underscore_memoization
@@ -218,3 +223,7 @@ magic_function_class = PyObject(type(load_module), parent=builtin)
def create(obj): def create(obj):
return PyObject(obj, builtin) return PyObject(obj, builtin)
def name_from_string(string):
return PyName(create(string), string)

View File

@@ -71,6 +71,7 @@ class NameFinder(object):
if not result and isinstance(self.scope, er.Instance): if not result and isinstance(self.scope, er.Instance):
# __getattr__ / __getattribute__ # __getattr__ / __getattribute__
for r in self._check_getattr(self.scope): for r in self._check_getattr(self.scope):
if not isinstance(r, compiled.PyObject):
new_name = copy.copy(r.name) new_name = copy.copy(r.name)
new_name.parent = r new_name.parent = r
result.append(new_name) result.append(new_name)
@@ -82,9 +83,8 @@ class NameFinder(object):
def _check_getattr(self, inst): def _check_getattr(self, inst):
"""Checks for both __getattr__ and __getattribute__ methods""" """Checks for both __getattr__ and __getattribute__ methods"""
result = [] result = []
module = compiled.builtin
# str is important to lose the NamePart! # str is important to lose the NamePart!
name = pr.String(module, "'%s'" % self.name_str, (0, 0), (0, 0), inst) name = compiled.name_from_string(self.name_str)
with common.ignored(KeyError): with common.ignored(KeyError):
result = inst.execute_subscope_by_name('__getattr__', [name]) result = inst.execute_subscope_by_name('__getattr__', [name])
if not result: if not result:

View File

@@ -2,7 +2,6 @@ import copy
from jedi.parser import representation as pr from jedi.parser import representation as pr
from jedi.evaluate import iterable from jedi.evaluate import iterable
from jedi.evaluate import compiled
from jedi.evaluate import common from jedi.evaluate import common
@@ -140,7 +139,7 @@ def _var_args_iterator(evaluator, var_args):
continue continue
old = stmt old = stmt
# generate a statement if it's not already one. # generate a statement if it's not already one.
stmt = pr.Statement(compiled.builtin, [], (0, 0), None) stmt = pr.Statement(_FakeSubModule, [], (0, 0), None)
stmt._expression_list = [old] stmt._expression_list = [old]
# *args # *args

View File

@@ -3,6 +3,7 @@ Implementations of standard library functions, because it's not possible to
understand them with Jedi. understand them with Jedi.
""" """
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
@@ -44,18 +45,18 @@ def builtins_getattr(evaluator, obj, params):
objects = _follow_param(evaluator, params, 0) objects = _follow_param(evaluator, params, 0)
names = _follow_param(evaluator, params, 1) names = _follow_param(evaluator, params, 1)
for obj in objects: for obj in objects:
if not isinstance(obj, (er.Instance, er.Class, pr.Module)): if not isinstance(obj, (er.Instance, er.Class, pr.Module, compiled.PyObject)):
debug.warning('getattr called without instance') debug.warning('getattr called without instance')
continue continue
for arr_name in names: for name in names:
if not isinstance(arr_name, er.Instance): s = unicode, str
print name
if isinstance(name, compiled.PyObject) and isinstance(name.obj, s):
stmts += evaluator.follow_path(iter([name.obj]), [obj], obj)
else:
debug.warning('getattr called without str') debug.warning('getattr called without str')
continue continue
if len(arr_name.var_args) != 1:
debug.warning('jedi getattr is too simple')
key = arr_name.var_args[0]
stmts += evaluator.follow_path(iter([key]), [obj], obj)
return stmts return stmts

View File

@@ -339,7 +339,7 @@ class Wrapper2():
return getattr(Base(), name) return getattr(Base(), name)
#? int() #? int()
Wrapper(Base()).ret(3) Wrapper(Base()).ret
#? int() #? int()
Wrapper2(Base()).ret(3) Wrapper2(Base()).ret(3)