diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 0c67c28f..bee22970 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -411,7 +411,6 @@ class Evaluator(object): debug.warning("no __call__ func available", obj) else: debug.warning("no execution possible", obj) - raise NotImplementedError() else: stmts = er.FunctionExecution(self, obj, params).get_return_types(evaluate_generator) diff --git a/jedi/evaluate/compiled/__init__.py b/jedi/evaluate/compiled/__init__.py index 3c7e0fcf..990cacd9 100644 --- a/jedi/evaluate/compiled/__init__.py +++ b/jedi/evaluate/compiled/__init__.py @@ -23,10 +23,9 @@ class PyObject(Base): start_pos = 0, 0 asserts = [] - def __init__(self, obj, parent=None, instantiated=False): + def __init__(self, obj, parent=None): self.obj = obj self.parent = parent - self.instantiated = instantiated self.doc = inspect.getdoc(obj) def __repr__(self): @@ -74,7 +73,6 @@ class PyObject(Base): def get_subscope_by_name(self, name): if name in dir(self._cls().obj): - print PyName(self._cls(), name).parent return PyName(self._cls(), name).parent else: raise KeyError("CompiledObject doesn't have an attribute '%s'." % name) @@ -87,7 +85,7 @@ class PyObject(Base): def execute_function(self, evaluator, params): for name in self._parse_function_doc()[1].split(): try: - bltn_obj = create(getattr(_builtins, name), builtin, module=builtin) + bltn_obj = _create_from_name(builtin, builtin, name) except AttributeError: continue else: @@ -116,15 +114,8 @@ class PyName(object): @property @underscore_memoization def parent(self): - try: - o = getattr(self._obj.obj, self._name) - except AttributeError: - # happens e.g. in properties of - # PyQt4.QtGui.QStyleOptionComboBox.currentText - # -> just set it to None - return PyObject(None, builtin) - else: - return create(o, self._obj, module=self._obj.get_parent_until()) + module = self._obj.get_parent_until() + return _create_from_name(module, self._obj, self._name) @property def names(self): @@ -236,23 +227,31 @@ builtin = PyObject(_builtins) magic_function_class = PyObject(type(load_module), parent=builtin) -def create(obj, parent=builtin, instantiated=False, module=None): - if not inspect.ismodule(obj): - if module is None: - module = obj.__class__ if fake.is_class_instance(obj) else obj - if not (inspect.isbuiltin(module) or inspect.isclass(module)): - module = obj.__objclass__ - try: - imp_plz = obj.__module__ - except AttributeError: - # Unfortunately in some cases like `int` there's no __module__ - module = builtin - else: - module = PyObject(__import__(imp_plz)) +def _create_from_name(module, parent, name): + faked = fake.get_faked(module.obj, parent, name) + if faked is not None: + faked.parent = parent + return faked - faked = fake.get_faked(module.obj, obj) + try: + obj = getattr(parent, name) + except AttributeError: + # happens e.g. in properties of + # PyQt4.QtGui.QStyleOptionComboBox.currentText + # -> just set it to None + obj = None + return PyObject(obj, parent) + + +def create(obj, parent=builtin, module=None): + """ + A very weird interface class to this module. The more options provided the + more acurate loading compiled objects is. + """ + if not inspect.ismodule(parent): + faked = fake.get_faked(module and module.obj, obj) if faked is not None: faked.parent = parent return faked - return PyObject(obj, parent, instantiated) + return PyObject(obj, parent) diff --git a/jedi/evaluate/compiled/fake.py b/jedi/evaluate/compiled/fake.py index 2956d2f9..7b464487 100644 --- a/jedi/evaluate/compiled/fake.py +++ b/jedi/evaluate/compiled/fake.py @@ -8,7 +8,7 @@ import re import os import inspect -from jedi._compatibility import is_py3k +from jedi._compatibility import is_py3k, builtins from jedi.parser import Parser modules = {} @@ -67,6 +67,7 @@ def _load_module(module): module_name = module.__name__ if module_name == '__builtin__' and not is_py3k: module_name = 'builtins' + try: return modules[module_name] except KeyError: @@ -81,28 +82,48 @@ def _load_module(module): return module -def get_faked(module, obj): - def from_scope(scope, obj): +def get_faked(module, obj, name=None): + def from_scope(scope, obj_name): for s in scope.subscopes: - if str(s.name) == obj.__name__: + if str(s.name) == obj_name: return s + # Crazy underscore actions to try to escape all the internal madness. + obj = obj.__class__ if is_class_instance(obj) else obj + if module is None: + try: + module = obj.__objclass__ + except AttributeError: + pass + + try: + imp_plz = obj.__module__ + except AttributeError: + # Unfortunately in some cases like `int` there's no __module__ + module = builtins + else: + module = __import__(imp_plz) + mod = _load_module(module) if mod is None: return # Having the module as a `parser.representation.module`, we need to scan # for methods. - if is_class_instance(obj): - obj = obj.__class__ - if inspect.isbuiltin(obj): - return from_scope(mod, obj) - elif not inspect.isclass(obj): - # object is a method or descriptor - cls = from_scope(mod, obj.__objclass__) - if cls is None: - return - return from_scope(cls, obj) + if name is None: + if inspect.isbuiltin(obj): + return from_scope(mod, obj.__name__) + elif not inspect.isclass(obj): + # object is a method or descriptor + cls = from_scope(mod, obj.__objclass__.__name__) + if cls is None: + return + return from_scope(cls, obj.__name__) + else: + if obj == module: + return from_scope(mod, name) + else: + return from_scope(mod, name) def is_class_instance(obj): diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 1c60a97d..960c211d 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -122,7 +122,6 @@ class Instance(use_metaclass(CachedMetaClass, Executable)): def get_subscope_by_name(self, name): sub = self.base.get_subscope_by_name(name) - print sub return InstanceElement(self._evaluator, self, sub, True) def execute_subscope_by_name(self, name, args=()): @@ -204,9 +203,7 @@ class InstanceElement(use_metaclass(CachedMetaClass, pr.Base)): and par == self.instance.base.base: par = self.instance elif not isinstance(par, (pr.Module, compiled.PyObject)): - print 'HA', par, self.var par = InstanceElement(self.instance._evaluator, self.instance, par, self.is_class_var) - print 'H2A', par return par def get_parent_until(self, *args, **kwargs):