diff --git a/jedi/api/classes.py b/jedi/api/classes.py index 341882f2..6328808a 100644 --- a/jedi/api/classes.py +++ b/jedi/api/classes.py @@ -14,6 +14,7 @@ from jedi import cache from jedi.evaluate import representation as er from jedi.evaluate import iterable from jedi.evaluate import imports +from jedi.evaluate import compiled from jedi import keywords @@ -70,8 +71,11 @@ class BaseDefinition(object): # generate a path to the definition self._module = definition.get_parent_until() - self.module_path = self._module.path - """Shows the file path of a module. e.g. ``/usr/lib/python2.7/os.py``""" + if self.in_builtin_module(): + self.module_path = None + else: + self.module_path = self._module.path + """Shows the file path of a module. e.g. ``/usr/lib/python2.7/os.py``""" @property def start_pos(self): @@ -177,8 +181,7 @@ class BaseDefinition(object): def in_builtin_module(self): """Whether this is a builtin module.""" - return not (self.module_path is None or - self.module_path.endswith('.py')) + return isinstance(self._module, compiled.PyObject) @property def line_nr(self): @@ -518,12 +521,7 @@ class Definition(BaseDefinition): .. todo:: Add full path. This function is should return a `module.class.function` path. """ - if self.module_path.endswith('.py') \ - and not isinstance(self._definition, pr.Module): - position = '@%s' % (self.line) - else: - # is a builtin or module - position = '' + position = '' if self.in_builtin_module else '@%s' % (self.line) return "%s:%s%s" % (self.module_name, self.description, position) def defined_names(self): diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index cde7e4ca..3b2fe815 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -174,8 +174,7 @@ class Evaluator(object): # Add builtins to the global scope. if include_builtin: - builtin_scope = builtin.Builtin.scope - yield builtin_scope, builtin_scope.get_defined_names() + yield compiled.builtin, compiled.builtin.get_defined_names() def find_types(self, scope, name_str, position=None, search_global=False, is_goto=False, resolve_decorator=True): diff --git a/jedi/evaluate/compiled.py b/jedi/evaluate/compiled.py index 5da33cd2..6c0b876a 100644 --- a/jedi/evaluate/compiled.py +++ b/jedi/evaluate/compiled.py @@ -6,6 +6,7 @@ import re from jedi._compatibility import builtins as _builtins, is_py3k from jedi import debug +from jedi.parser.representation import Base from jedi.cache import underscore_memoization @@ -13,13 +14,17 @@ from jedi.cache import underscore_memoization # unbound methods such as pyqtSignals have no __name__ # if not hasattr(func, "__name__"): -class PyObject(object): +class PyObject(Base): def __init__(self, obj, parent=None, instantiated=False): self.obj = obj self.parent = parent self.instantiated = instantiated self.doc = inspect.getdoc(obj) + # comply with the parser + self.get_parent_until = lambda: parent + self.start_pos = 0, 0 + def __repr__(self): return '<%s: %s>' % (type(self).__name__, self.obj) @@ -30,19 +35,25 @@ class PyObject(object): return _parse_function_doc(self.doc) + def type(self): + if inspect.isclass(self.obj): + return 'class' + elif inspect.ismodule(self.obj): + return 'module' + elif inspect.isbuiltin(self.obj) or inspect.ismethod(self.obj) \ + or inspect.ismethoddescriptor(self.obj): + return 'def' + def get_defined_names(self): # We don't want to execute properties, therefore we have to try to get # the class cls = self - if not (inspect.isclass(self.obj) or inspect.ismodule(self.obj)): + if not inspect.isclass(self.obj): cls = PyObject(self.obj.__class__, self.parent) for name in dir(cls.obj): yield PyName(cls, name) - def isinstance(self, *obj): - return isinstance(self, obj) - @property def name(self): # might not exist sometimes (raises AttributeError) @@ -64,7 +75,6 @@ class PyName(object): def __init__(self, obj, name): self._obj = obj self._name = name - self.start_pos = 0, 0 # an illegal start_pos, to make sorting easy. @property