diff --git a/jedi/evaluate/compiled/fake/builtins.pym b/jedi/evaluate/compiled/fake/builtins.pym index 692c8f8b..2fc50ce1 100644 --- a/jedi/evaluate/compiled/fake/builtins.pym +++ b/jedi/evaluate/compiled/fake/builtins.pym @@ -6,6 +6,17 @@ possible for the auto completion. """ +def next(iterator, default=None): + if random.choice([0, 1]): + if hasattr("next"): + return iterator.next() + else: + return iterator.__next__() + else: + if default is not None: + return default + + def iter(collection, sentinel=None): if sentinel: yield collection() diff --git a/jedi/evaluate/instance.py b/jedi/evaluate/instance.py index 5190c63f..ee4753a9 100644 --- a/jedi/evaluate/instance.py +++ b/jedi/evaluate/instance.py @@ -213,14 +213,18 @@ class CompiledInstanceName(compiled.CompiledName): self._instance = instance def infer(self): - for v in super(CompiledInstanceName, self).infer(): - if isinstance(v, er.FunctionContext): + for result_context in super(CompiledInstanceName, self).infer(): + if isinstance(result_context, er.FunctionContext): + parent_context = result_context.parent_context + while parent_context.is_class(): + parent_context = parent_context.parent_context + yield BoundMethod( - v.evaluator, self._instance, self.parent_context, - v.parent_context, v.funcdef + result_context.evaluator, self._instance, self.parent_context, + parent_context, result_context.funcdef ) else: - yield v + yield result_context class CompiledInstanceClassFilter(compiled.CompiledObjectFilter): @@ -282,7 +286,7 @@ class LazyInstanceClassName(LazyInstanceName): # functions. Only other functions and modules will resolve # those things. parent_context = result_context.parent_context - while isinstance(parent_context, er.ClassContext): + while parent_context.is_class(): parent_context = parent_context.parent_context yield BoundMethod( diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index 568dd4e1..6fb52d06 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -123,7 +123,7 @@ def has_builtin_methods(cls): def register_builtin_method(method_name, python_version_match=None): def wrapper(func): - if python_version_match and python_version_match == 2 + int(is_py3): + if python_version_match and python_version_match != 2 + int(is_py3): # Some functions do only apply to certain versions. return func dct = func.__dict__.setdefault('registered_builtin_methods', {}) diff --git a/jedi/evaluate/stdlib.py b/jedi/evaluate/stdlib.py index eb220fa4..cfe8dee9 100644 --- a/jedi/evaluate/stdlib.py +++ b/jedi/evaluate/stdlib.py @@ -17,7 +17,7 @@ from jedi.common import unite from jedi.evaluate import compiled from jedi.evaluate import representation as er from jedi.evaluate.instance import InstanceFunctionExecution, \ - AbstractInstanceContext, CompiledInstance + AbstractInstanceContext, CompiledInstance, BoundMethod from jedi.evaluate import iterable from jedi.parser import ParserWithRecovery from jedi import debug @@ -31,6 +31,9 @@ class NotInStdLib(LookupError): def execute(evaluator, obj, arguments): + if isinstance(obj, BoundMethod): + raise NotInStdLib() + try: obj_name = obj.name.string_name except AttributeError: @@ -108,6 +111,10 @@ def argument_clinic(string, want_obj=False, want_context=False, want_arguments=F @argument_clinic('iterator[, default], /') def builtins_next(evaluator, iterators, defaults): + """ + TODO this function is currently not used. It's a stab at implementing next + in a different way than fake objects. This would be a bit more flexible. + """ if evaluator.python_version[0] == 2: name = 'next' else: @@ -268,7 +275,6 @@ def _return_first_param(evaluator, firsts): _implemented = { 'builtins': { - 'next': builtins_next, 'getattr': builtins_getattr, 'type': builtins_type, 'super': builtins_super,