diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index 9b1f1c1f..06bcf215 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -143,7 +143,7 @@ class Script(object): @cache.memoize_method def _get_module(self): module = er.ModuleContext(self._evaluator, self._get_module_node()) - imports.add_module(self._evaluator, unicode(module.name), module) + imports.add_module(self._evaluator, module.name.string_name, module) return module @property @@ -437,17 +437,18 @@ def names(source=None, path=None, encoding='utf-8', all_scopes=False, is_def = _def._name.tree_name.is_definition() return definitions and is_def or references and not is_def + def get_definitions(): + for tree_name in get_module_names(script._get_module_node(), all_scopes): + name = TreeNameDefinition( + module_context.create_context(tree_name), + tree_name + ) + yield classes.Definition(script._evaluator, name) + # Set line/column to a random position, because they don't matter. script = Script(source, line=1, column=0, path=path, encoding=encoding) module_context = script._get_module() defs = [ - classes.Definition( - script._evaluator, - TreeNameDefinition( - module_context.create_context(name), - name - ) - ) for name in get_module_names(script._get_module_node(), all_scopes) ] return sorted(filter(def_ref_filter, defs), key=lambda x: (x.line, x.column)) diff --git a/jedi/api/classes.py b/jedi/api/classes.py index 7fcaa31f..caef6c94 100644 --- a/jedi/api/classes.py +++ b/jedi/api/classes.py @@ -164,28 +164,31 @@ class BaseDefinition(object): def _path(self): """The path to a module/class/function definition.""" - path = [] - par = self._definition - while par is not None: - if isinstance(par, tree.Import): - # Not self._name.infer()? - raise DeprecationWarning - path += imports.ImportWrapper(self._name.context, self._name).import_path - break - try: - name = par.name - except AttributeError: - pass - else: - if isinstance(par, er.ModuleWrapper): - # TODO just make the path dotted from the beginning, we - # shouldn't really split here. - path[0:0] = par.py__name__().split('.') - break + def to_reverse(): + name = self._name + if name.api_type == 'module': + try: + name = list(name.infer())[0].name + except IndexError: + pass + yield name.string_name + name.api_type + parent_context = name.parent_context + print(parent_context) + while parent_context is not None: + try: + method = parent_context.py__name__ + except AttributeError: + try: + yield parent_context.name.string_name + except AttributeError: + pass else: - path.insert(0, unicode(name)) - par = par.parent - return path + # TODO this main clause seems strange. + for name in (method() or '__main__').split('.'): + yield name + parent_context = parent_context.parent_context + return reversed(list(to_reverse())) @property def module_name(self): @@ -299,11 +302,12 @@ class BaseDefinition(object): >>> print(script.goto_definitions()[0].full_name) os.path.join - Notice that it correctly returns ``'os.path.join'`` instead of - (for example) ``'posixpath.join'``. - + Notice that it returns ``'os.path.join'`` instead of (for example) + ``'posixpath.join'``. This is not correct, since the modules name would + be `````. However most users find the latter + more practical. """ - path = [unicode(p) for p in self._path()] + path = list(self._path()) # TODO add further checks, the mapping should only occur on stdlib. if not path: return None # for keywords the path is empty @@ -476,7 +480,7 @@ class Completion(BaseDefinition): if t == 'statement' or t == 'import': desc = self._definition.get_code() else: - desc = '.'.join(unicode(p) for p in self._path()) + desc = '.'.join(self._path()) line = '' if self.in_builtin_module else '@%s' % self.line return '%s: %s%s' % (t, desc, line) diff --git a/jedi/evaluate/compiled/__init__.py b/jedi/evaluate/compiled/__init__.py index c86c095f..ab79bfc4 100644 --- a/jedi/evaluate/compiled/__init__.py +++ b/jedi/evaluate/compiled/__init__.py @@ -12,7 +12,8 @@ from jedi import debug from jedi.cache import underscore_memoization, memoize_method from jedi.parser.tree import Param, Operator from jedi.evaluate.helpers import FakeName -from jedi.evaluate.filters import AbstractFilter, AbstractNameDefinition +from jedi.evaluate.filters import AbstractFilter, AbstractNameDefinition, \ + ContextNameMixin from jedi.evaluate.context import Context, LazyKnownContext from . import fake @@ -300,13 +301,11 @@ class UnresolvableParamName(AbstractNameDefinition): return set() -class CompiledContextName(AbstractNameDefinition): - def __init__(self, parent_context, name): +class CompiledContextName(ContextNameMixin, AbstractNameDefinition): + def __init__(self, context, name): self.string_name = name - self.parent_context = parent_context - - def infer(self): - return [self.parent_context] + self._context = context + self.parent_context = context.parent_context class LazyNamesDict(object): diff --git a/jedi/evaluate/filters.py b/jedi/evaluate/filters.py index ff87c5ac..499bfcd4 100644 --- a/jedi/evaluate/filters.py +++ b/jedi/evaluate/filters.py @@ -52,24 +52,26 @@ class AbstractTreeName(AbstractNameDefinition): return self.tree_name.start_pos -class ContextName(AbstractTreeName): - def __init__(self, context, tree_name): - super(ContextName, self).__init__(context.parent_context, tree_name) - self._context = context - +class ContextNameMixin(object): def infer(self): - return [self._context] + return set([self._context]) def get_root_context(self): if self.parent_context is None: return self._context - return super(ContextName, self).get_root_context() + return super(ContextNameMixin, self).get_root_context() @property def api_type(self): return self._context.api_type +class ContextName(ContextNameMixin, AbstractTreeName): + def __init__(self, context, tree_name): + super(ContextName, self).__init__(context.parent_context, tree_name) + self._context = context + + class TreeNameDefinition(AbstractTreeName): def get_parent_flow_context(self): return self.parent_context diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index ec844f0e..c1446652 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -216,7 +216,7 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext)): except AttributeError: pass else: - return method()[:-1] + return list(method())[1:] return [] @property diff --git a/test/test_api/test_full_name.py b/test/test_api/test_full_name.py index b96c5481..71ce7ab8 100644 --- a/test/test_api/test_full_name.py +++ b/test/test_api/test_full_name.py @@ -69,7 +69,7 @@ class TestFullDefinedName(TestCase): self.check(""" def f(): pass class C: pass - """, ['f', 'C']) + """, ['__main__.f', '__main__.C']) def test_imports(self): self.check("""