diff --git a/jedi/evaluate/compiled/__init__.py b/jedi/evaluate/compiled/__init__.py index 1f567efa..2b0f3e90 100644 --- a/jedi/evaluate/compiled/__init__.py +++ b/jedi/evaluate/compiled/__init__.py @@ -67,6 +67,13 @@ class CompiledObject(Context): @CheckAttribute def py__call__(self, params): + if self.tree_node is not None and self.tree_node.type == 'funcdef': + from jedi.evaluate.context.function import FunctionContext + return FunctionContext( + self.evaluator, + parent_context=self.parent_context, + funcdef=self.tree_node + ).py__call__(params) if self.access.is_class(): from jedi.evaluate.context import CompiledInstance return ContextSet(CompiledInstance(self.evaluator, self.parent_context, self, params)) @@ -480,9 +487,6 @@ def _create_from_name(evaluator, compiled_object, name): faked = None try: faked = fake.get_faked_with_parent_context(compiled_object, name) - if faked.type == 'funcdef': - from jedi.evaluate.context.function import FunctionContext - return FunctionContext(evaluator, compiled_object, faked) except fake.FakeDoesNotExist: pass @@ -559,12 +563,6 @@ def _create(evaluator, access, parent_context=None, faked=None): else: for access2, tree_node in zip(accesses, tree_nodes): parent_context = create(evaluator, access2, parent_context, faked=tree_node) - - # TODO this if is ugly. Please remove, it may make certain - # properties of that function unusable. - if tree_node.type == 'function': - from jedi.evaluate.context.function import FunctionContext - return FunctionContext(evaluator, parent_context.parent_context, tree_node) return parent_context # TODO wow this is a mess.... if parent_context is None and not faked: diff --git a/jedi/evaluate/context/instance.py b/jedi/evaluate/context/instance.py index f01ae099..6bf8069a 100644 --- a/jedi/evaluate/context/instance.py +++ b/jedi/evaluate/context/instance.py @@ -253,7 +253,8 @@ class CompiledInstanceName(compiled.CompiledName): @iterator_to_context_set def infer(self): for result_context in super(CompiledInstanceName, self).infer(): - if isinstance(result_context, FunctionContext): + is_function = result_context.api_type == 'function' + if result_context.tree_node is not None and is_function: parent_context = result_context.parent_context while parent_context.is_class(): parent_context = parent_context.parent_context @@ -263,7 +264,7 @@ class CompiledInstanceName(compiled.CompiledName): parent_context, result_context.tree_node ) else: - if result_context.api_type == 'function': + if is_function: yield CompiledBoundMethod(result_context) else: yield result_context diff --git a/test/test_api/test_call_signatures.py b/test/test_api/test_call_signatures.py index c0fc9767..006b9510 100644 --- a/test/test_api/test_call_signatures.py +++ b/test/test_api/test_call_signatures.py @@ -324,8 +324,8 @@ def test_keyword_argument_index(): def get(source, column=None): return Script(source, column=column).call_signatures()[0] - assert get('sorted([], key=a').index == 2 - assert get('sorted([], key=').index == 2 + assert get('sorted([], key=a').index == 1 + assert get('sorted([], key=').index == 1 assert get('sorted([], no_key=a').index is None kw_func = 'def foo(a, b): pass\nfoo(b=3, a=4)' diff --git a/test/test_evaluate/test_compiled.py b/test/test_evaluate/test_compiled.py index 5191c7fc..ed865bdd 100644 --- a/test/test_evaluate/test_compiled.py +++ b/test/test_evaluate/test_compiled.py @@ -21,17 +21,17 @@ def test_simple(evaluator): def test_fake_loading(evaluator): - assert isinstance(compiled.create(evaluator, next), FunctionContext) - builtin = compiled.get_special_object(evaluator, 'BUILTINS') string, = builtin.py__getattribute__('str') - from_name = compiled._create_from_name(evaluator, builtin, string, '__init__') - assert isinstance(from_name, FunctionContext) + from_name = compiled._create_from_name(evaluator, string, '__init__') + assert from_name.tree_node def test_fake_docstr(evaluator): - node = compiled.create(evaluator, next).tree_node - assert clean_scope_docstring(node) == next.__doc__ + next_ = compiled.create(evaluator, next) + assert next_.py__doc__() + assert next_.tree_node is not None + assert next_.py__doc__() == next.__doc__ def test_parse_function_doc_illegal_docstr():