diff --git a/jedi/api/classes.py b/jedi/api/classes.py index 38c96761..791fc6f6 100644 --- a/jedi/api/classes.py +++ b/jedi/api/classes.py @@ -143,12 +143,12 @@ class BaseDefinition(object): """ # generate the type stripped = self._definition - if isinstance(stripped, compiled.CompiledObject): - return stripped.type() if isinstance(stripped, er.InstanceElement): stripped = stripped.var if isinstance(stripped, (pr.Name, pr.NamePart)): stripped = stripped.get_definition() + if isinstance(stripped, compiled.CompiledObject): + return stripped.type() if isinstance(stripped, iterable.Array): return 'instance' string = type(stripped).__name__.lower().replace('wrapper', '') @@ -246,10 +246,13 @@ class BaseDefinition(object): Document for function f. """ + definition = self._definition + if isinstance(definition, pr.NamePart): + definition = definition.parent.parent if raw: - return _Help(self._definition).raw() + return _Help(definition).raw() else: - return _Help(self._definition).full() + return _Help(definition).full() @property def doc(self): @@ -504,9 +507,8 @@ class Completion(BaseDefinition): the ``foo.docstring(fast=False)`` on every object, because it parses all libraries starting with ``a``. """ - definition = self._definition - if isinstance(self._definition, pr.Import): - i = imports.ImportWrapper(self._evaluator, self._definition) + if isinstance(definition, pr.Import): + i = imports.ImportWrapper(self._evaluator, definition) if len(i.import_path) > 1 or not fast: followed = self._follow_statements_imports() if followed: diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index bf0c8d78..5c194d27 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -326,6 +326,12 @@ class Wrapper(pr.Base): def is_class(self): return False + @property + @underscore_memoization + def name(self): + name = self.base.name + return helpers.FakeName(unicode(name), self, name.start_pos) + class Class(use_metaclass(CachedMetaClass, Wrapper)): """ @@ -406,10 +412,6 @@ class Class(use_metaclass(CachedMetaClass, Wrapper)): return sub raise KeyError("Couldn't find subscope.") - @common.safe_property - def name(self): - return self.base.name - def __getattr__(self, name): if name not in ['start_pos', 'end_pos', 'parent', 'asserts', 'raw_doc', 'doc', 'get_imports', 'get_parent_until', 'get_code', @@ -428,7 +430,7 @@ class Function(use_metaclass(CachedMetaClass, Wrapper)): def __init__(self, evaluator, func, is_decorated=False): """ This should not be called directly """ self._evaluator = evaluator - self.base_func = func + self.base = self.base_func = func self.is_decorated = is_decorated @memoize_default() @@ -635,7 +637,7 @@ class FunctionExecution(Executed): class ModuleWrapper(use_metaclass(CachedMetaClass, pr.Module, Wrapper)): def __init__(self, evaluator, module): self._evaluator = evaluator - self._module = module + self.base = self._module = module def scope_names_generator(self, position=None): yield self, pr.filter_after_position(self._module.get_defined_names(), position) diff --git a/test/test_evaluate/test_representation.py b/test/test_evaluate/test_representation.py index 80b4771e..5779b255 100644 --- a/test/test_evaluate/test_representation.py +++ b/test/test_evaluate/test_representation.py @@ -5,7 +5,7 @@ from jedi import Script def get_definition_and_evaluator(source): d = Script(dedent(source)).goto_definitions()[0] - return d._definition, d._evaluator + return d._definition.parent.parent, d._evaluator def test_function_execution(): diff --git a/test/test_parser/test_tokenize.py b/test/test_parser/test_tokenize.py index 9c93a70d..5d714dc1 100644 --- a/test/test_parser/test_tokenize.py +++ b/test/test_parser/test_tokenize.py @@ -26,4 +26,4 @@ asdfasdf""" + "h" def test_tokenizer_with_string_literal_backslash(): import jedi c = jedi.Script("statement = u'foo\\\n'; statement").goto_definitions() - assert c[0]._definition.obj == 'foo' + assert c[0]._definition.parent.parent.obj == 'foo'