From 024cc78b2c2cb8097b13ab29ad2d9ef7d54a02ef Mon Sep 17 00:00:00 2001 From: David Halter Date: Wed, 8 Aug 2012 15:56:43 +0200 Subject: [PATCH] implemented __next__ method --- evaluate.py | 11 +++++++++-- test/completion/generators.py | 27 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/evaluate.py b/evaluate.py index 15a860bc..842d02e0 100644 --- a/evaluate.py +++ b/evaluate.py @@ -17,7 +17,7 @@ TODO nonlocal statement TODO __ instance attributes should not be visible outside of the class. TODO getattr / __getattr__ / __getattribute__ ? """ -from _compatibility import next, property, hasattr +from _compatibility import next, property, hasattr, is_py3k import sys import itertools @@ -939,7 +939,7 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False): try: generators += it.execute_subscope_by_name('__iter__') except KeyError: - pass + debug.warning('`for r in x`: x has no __iter__ method') result = [] for gen in generators: @@ -948,6 +948,13 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False): # array, but there's also the list builtin, which is # another thing. in_vars = gen.get_index_types() + elif isinstance(gen, Instance): + # __iter__ returned an instance. + name = '__next__' if is_py3k() else 'next' + try: + in_vars = it.execute_subscope_by_name(name) + except KeyError: + debug.warning('Instance has no __next__ function', gen) else: # is a generator in_vars = gen.get_content() diff --git a/test/completion/generators.py b/test/completion/generators.py index ee157b83..2ae227ae 100644 --- a/test/completion/generators.py +++ b/test/completion/generators.py @@ -62,3 +62,30 @@ next(g) g = iter([1.0]) #? float() next(g) + +# ----------------- +# __next__ +# ----------------- +class Counter: + def __init__(self, low, high): + self.current = low + self.high = high + + def __iter__(self): + return self + + def next(self): + """ need to have both __next__ and next, because of py2/3 testing """ + return self.__next__() + + def __next__(self): + if self.current > self.high: + raise StopIteration + else: + self.current += 1 + return self.current - 1 + + +for c in Counter(3, 8): + #? int() + print c