1
0
forked from VimPlug/jedi

fix problems with self attributes - from fake modules

This commit is contained in:
Dave Halter
2014-01-11 18:05:44 +01:00
parent d430ef53a7
commit 1765fadf73
7 changed files with 53 additions and 23 deletions

View File

@@ -24,6 +24,7 @@ enable_notice = False
# callback, interface: level, str # callback, interface: level, str
debug_function = None debug_function = None
ignored_modules = ['jedi.evaluate.builtin', 'jedi.parser'] ignored_modules = ['jedi.evaluate.builtin', 'jedi.parser']
debug_indent = -1
def reset_time(): def reset_time():

View File

@@ -389,7 +389,7 @@ class Evaluator(object):
except stdlib.NotInStdLib: except stdlib.NotInStdLib:
pass pass
if isinstance(obj, compiled.PyObject): if obj.isinstance(compiled.PyObject):
if obj.is_executable_class(): if obj.is_executable_class():
return [er.Instance(self, obj, params)] return [er.Instance(self, obj, params)]
else: else:
@@ -401,9 +401,9 @@ class Evaluator(object):
return obj.iter_content() return obj.iter_content()
else: else:
stmts = [] stmts = []
try: if obj.isinstance(er.Function):
obj.returns # Test if it is a function stmts = er.FunctionExecution(self, obj, params).get_return_types(evaluate_generator)
except AttributeError: else:
if hasattr(obj, 'execute_subscope_by_name'): if hasattr(obj, 'execute_subscope_by_name'):
try: try:
stmts = obj.execute_subscope_by_name('__call__', params) stmts = obj.execute_subscope_by_name('__call__', params)
@@ -411,8 +411,6 @@ class Evaluator(object):
debug.warning("no __call__ func available", obj) debug.warning("no __call__ func available", obj)
else: else:
debug.warning("no execution possible", obj) debug.warning("no execution possible", obj)
else:
stmts = er.FunctionExecution(self, obj, params).get_return_types(evaluate_generator)
debug.dbg('execute result: %s in %s' % (stmts, obj)) debug.dbg('execute result: %s in %s' % (stmts, obj))
return imports.strip_imports(self, stmts) return imports.strip_imports(self, stmts)
@@ -454,8 +452,9 @@ def filter_private_variable(scope, call_scope, var_name):
if isinstance(var_name, (str, unicode)) and isinstance(scope, er.Instance)\ if isinstance(var_name, (str, unicode)) and isinstance(scope, er.Instance)\
and var_name.startswith('__') and not var_name.endswith('__'): and var_name.startswith('__') and not var_name.endswith('__'):
s = call_scope.get_parent_until((pr.Class, er.Instance)) s = call_scope.get_parent_until((pr.Class, er.Instance))
if s != scope and s != scope.base.base: if not isinstance(scope.base, compiled.PyObject):
return True if s != scope and s != scope.base.base:
return True
return False return False

View File

@@ -83,6 +83,8 @@ class PyObject(Base):
return self._cls().obj.__name__ return self._cls().obj.__name__
def execute_function(self, evaluator, params): def execute_function(self, evaluator, params):
if self.type() != 'def':
return
for name in self._parse_function_doc()[1].split(): for name in self._parse_function_doc()[1].split():
try: try:
bltn_obj = _create_from_name(builtin, builtin, name) bltn_obj = _create_from_name(builtin, builtin, name)
@@ -95,6 +97,21 @@ class PyObject(Base):
for result in evaluator.execute(bltn_obj, params): for result in evaluator.execute(bltn_obj, params):
yield result yield result
@property
@underscore_memoization
def subscopes(self):
"""
Returns only the faked scopes - the other ones are not important for
internal analysis.
"""
module = self.get_parent_until()
faked_subscopes = []
for name in dir(self._cls().obj):
f = fake.get_faked(module.obj, self.obj, name)
if f:
faked_subscopes.append(f)
return faked_subscopes
def get_self_attributes(self): def get_self_attributes(self):
return [] # Instance compatibility return [] # Instance compatibility
@@ -236,6 +253,7 @@ magic_function_class = PyObject(type(load_module), parent=builtin)
def _create_from_name(module, parent, name): def _create_from_name(module, parent, name):
faked = fake.get_faked(module.obj, parent.obj, name) faked = fake.get_faked(module.obj, parent.obj, name)
# only functions are necessary.
if faked is not None: if faked is not None:
faked.parent = parent faked.parent = parent
return faked return faked

View File

@@ -10,6 +10,7 @@ import inspect
from jedi._compatibility import is_py3k, builtins from jedi._compatibility import is_py3k, builtins
from jedi.parser import Parser from jedi.parser import Parser
from jedi.parser.representation import Class
modules = {} modules = {}
@@ -63,7 +64,7 @@ def _load_fakes(module_name):
return mixin_dct return mixin_dct
def _load_module(module): def _load_faked_module(module):
module_name = module.__name__ module_name = module.__name__
if module_name == '__builtin__' and not is_py3k: if module_name == '__builtin__' and not is_py3k:
module_name = 'builtins' module_name = 'builtins'
@@ -82,7 +83,7 @@ def _load_module(module):
return module return module
def get_faked(module, obj, name=None): def _faked(module, obj, name=None):
def from_scope(scope, obj_name): def from_scope(scope, obj_name):
for s in scope.subscopes: for s in scope.subscopes:
if str(s.name) == obj_name: if str(s.name) == obj_name:
@@ -104,26 +105,35 @@ def get_faked(module, obj, name=None):
else: else:
module = __import__(imp_plz) module = __import__(imp_plz)
mod = _load_module(module) faked_mod = _load_faked_module(module)
if mod is None: if faked_mod is None:
return return
# Having the module as a `parser.representation.module`, we need to scan # Having the module as a `parser.representation.module`, we need to scan
# for methods. # for methods.
if name is None: if name is None:
if inspect.isbuiltin(obj): if inspect.isbuiltin(obj):
return from_scope(mod, obj.__name__) return from_scope(faked_mod, obj.__name__)
elif not inspect.isclass(obj): elif not inspect.isclass(obj):
# object is a method or descriptor # object is a method or descriptor
cls = from_scope(mod, obj.__objclass__.__name__) cls = from_scope(faked_mod, obj.__objclass__.__name__)
if cls is None: if cls is None:
return return
return from_scope(cls, obj.__name__) return from_scope(cls, obj.__name__)
else: else:
if obj == module: if obj == module:
return from_scope(mod, name) return from_scope(faked_mod, name)
else: else:
return from_scope(mod, name) cls = from_scope(faked_mod, obj.__name__)
if cls is None:
return
return from_scope(cls, name)
def get_faked(*args, **kwargs):
result = _faked(*args, **kwargs)
if not isinstance(result, Class):
return result
def is_class_instance(obj): def is_class_instance(obj):

View File

@@ -1,7 +1,7 @@
def proxy(object, callback=None): def proxy(object, callback=None):
return object return object
class ref(): class weakref():
def __init__(self, object, callback=None): def __init__(self, object, callback=None):
self.__object = object self.__object = object
def __call__(self): def __call__(self):

View File

@@ -87,8 +87,6 @@ class Instance(use_metaclass(CachedMetaClass, Executable)):
n.names = n.names[1:] n.names = n.names[1:]
names.append(InstanceElement(self._evaluator, self, n)) names.append(InstanceElement(self._evaluator, self, n))
if isinstance(self.base, compiled.PyObject):
return []
names = [] names = []
# This loop adds the names of the self object, copies them and removes # This loop adds the names of the self object, copies them and removes
# the self. # the self.
@@ -115,9 +113,10 @@ class Instance(use_metaclass(CachedMetaClass, Executable)):
if n.names[0] == self_name and len(n.names) == 2: if n.names[0] == self_name and len(n.names) == 2:
add_self_dot_name(n) add_self_dot_name(n)
for s in self.base.get_super_classes(): if not isinstance(self.base, compiled.PyObject):
for inst in self._evaluator.execute(s): for s in self.base.get_super_classes():
names += inst.get_self_attributes() for inst in self._evaluator.execute(s):
names += inst.get_self_attributes()
return names return names
def get_subscope_by_name(self, name): def get_subscope_by_name(self, name):

View File

@@ -13,8 +13,11 @@ def test_simple():
objs = list(e.execute(upper[0])) objs = list(e.execute(upper[0]))
assert len(objs) == 1 assert len(objs) == 1
assert objs[0].obj is str assert objs[0].obj is str
assert objs[0].instantiated is True
def test_fake_loading(): def test_fake_loading():
assert isinstance(compiled.create(next), Function) assert isinstance(compiled.create(next), Function)
string = compiled.builtin.get_subscope_by_name('str')
from_name = compiled._create_from_name(compiled.builtin, string, '__init__')
assert isinstance(from_name, Function)