diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index 394d8526..8c2c0326 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -179,7 +179,9 @@ class Script(object): comps = [] comp_dct = {} for c, s in set(completions): - n = str(c.names[-1]) + # TODO Remove this line. c should be a namepart even before that. + c = c.names[-1] + n = str(c) if settings.case_insensitive_completion \ and n.lower().startswith(like.lower()) \ or n.startswith(like): diff --git a/jedi/api/classes.py b/jedi/api/classes.py index 8c209cc6..8adc7627 100644 --- a/jedi/api/classes.py +++ b/jedi/api/classes.py @@ -430,7 +430,7 @@ class Completion(BaseDefinition): if isinstance(self._base, pr.Param): append += '=' - name = str(self._name.names[-1]) + name = str(self._name) if like_name: name = name[self._like_name_length:] return dot + name + append @@ -457,7 +457,7 @@ class Completion(BaseDefinition): would return `isinstance`. """ - return unicode(self._name.names[-1]) + return unicode(self._name) @property def name_with_symbols(self): @@ -575,8 +575,6 @@ class Definition(use_metaclass(CachedMetaClass, BaseDefinition)): """ def __init__(self, evaluator, definition): super(Definition, self).__init__(evaluator, definition, definition.start_pos) - if not isinstance(definition, pr.NamePart): - raise NotImplementedError(definition) @property @underscore_memoization diff --git a/jedi/api/keywords.py b/jedi/api/keywords.py index 6309e802..2875ff0d 100644 --- a/jedi/api/keywords.py +++ b/jedi/api/keywords.py @@ -1,9 +1,11 @@ import pydoc import keyword +from jedi.parser.representation import NamePart from jedi._compatibility import is_py3 from jedi import common from jedi.evaluate import compiled +from jedi.evaluate.helpers import FakeSubModule try: from pydoc_data import topics as pydoc_topics @@ -40,7 +42,7 @@ def get_operator(string, pos): class KeywordName(object): def __init__(self, parent, name, start_pos): self.parent = parent - self.names = [name] + self.names = [NamePart(FakeSubModule, name, self, (0, 0))] self.start_pos = start_pos def get_definition(self): diff --git a/jedi/evaluate/imports.py b/jedi/evaluate/imports.py index 640a5746..78841a7e 100644 --- a/jedi/evaluate/imports.py +++ b/jedi/evaluate/imports.py @@ -29,6 +29,7 @@ from jedi.common import source_to_unicode from jedi.evaluate import compiled from jedi.evaluate import analysis from jedi.evaluate.cache import memoize_default, NO_DEFAULT +from jedi.evaluate.helpers import FakeSubModule class ModuleNotFound(Exception): @@ -368,12 +369,12 @@ class _Importer(object): pos = (part._line, part._column) try: self.import_path = ( - pr.NamePart('flask_' + str(part), part.parent, pos), + pr.NamePart(FakeSubModule, 'flask_' + str(part), part.parent, pos), ) + orig_path[3:] return self._real_follow_file_system() except ModuleNotFound as e: self.import_path = ( - pr.NamePart('flaskext', part.parent, pos), + pr.NamePart(FakeSubModule, 'flaskext', part.parent, pos), ) + orig_path[2:] return self._real_follow_file_system() return self._real_follow_file_system() diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index c6b9f39d..15b4c972 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -237,7 +237,8 @@ class ArrayMethod(IterableWrapper): @property @underscore_memoization def names(self): - return [pr.NamePart(unicode(n), self, n.start_pos) for n in self.name.names] + # TODO remove this method, we need the ArrayMethod input to be a NamePart. + return [pr.NamePart(self.name._sub_module, unicode(n), self, n.start_pos) for n in self.name.names] def __getattr__(self, name): # Set access privileges: diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index c31827aa..14d19b27 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -294,7 +294,8 @@ class InstanceElement(use_metaclass(CachedMetaClass, pr.Base)): @property @underscore_memoization def names(self): - return [pr.NamePart(unicode(n), self, n.start_pos) for n in self.var.names] + return [pr.NamePart(helpers.FakeSubModule, unicode(n), self, n.start_pos) + for n in self.var.names] @property @underscore_memoization diff --git a/jedi/parser/representation.py b/jedi/parser/representation.py index 2e10fad0..85a10a8d 100644 --- a/jedi/parser/representation.py +++ b/jedi/parser/representation.py @@ -1458,11 +1458,12 @@ class NamePart(object): # Unfortunately there's no way to use slots for str (non-zero __itemsize__) # -> http://utcc.utoronto.ca/~cks/space/blog/python/IntSlotsPython3k # Therefore don't subclass `str`. - __slots__ = ('parent', '_string', '_line', '_column') + __slots__ = ('_sub_module', 'parent', '_string', '_line', '_column') - def __init__(self, string, parent, start_pos): + def __init__(self, sub_module, string, parent, start_pos): self._string = string self.parent = parent + self._sub_module = sub_module self._line = start_pos[0] self._column = start_pos[1] @@ -1489,7 +1490,7 @@ class NamePart(object): @property def start_pos(self): - offset = self.parent._sub_module.line_offset + offset = self._sub_module.line_offset return offset + self._line, self._column @property @@ -1512,7 +1513,7 @@ class Name(Simple): # (seen by using the profiler). self._get_code = ".".join(n[0] for n in names) - names = tuple(NamePart(n[0], self, n[1]) for n in names) + names = tuple(NamePart(module, n[0], self, n[1]) for n in names) self.names = names def get_code(self):