77 lines
2.1 KiB
Plaintext
77 lines
2.1 KiB
Plaintext
For-in loops, https://docs.python.org/3/whatsnew/3.3.html#pep-380-syntax-for-delegating-to-a-subgenerator[``yield from``] and iterable unpacking only work with https://docs.python.org/3/glossary.html#term-iterable[iterable objects]. In order to be iterable, an object should have either an ``\_\_iter\_\_`` method or a ``\_\_getitem\_\_`` method implementing the https://docs.python.org/3/glossary.html#term-sequence[Sequence] semantic.
|
|
|
|
Note also that iterating over an https://docs.python.org/3/glossary.html#term-asynchronous-iterable[asynchronous iterable], i.e. an object having the ``\_\_aiter\_\_`` method, requires the use of https://docs.python.org/3/reference/compound_stmts.html#the-async-for-statement[``async for ... in``] instead of ``for ... in``.
|
|
|
|
This rule raises an issue when a non iterable object is used in a ``for-in`` loop, in a ``yield from`` or when it is unpacked.
|
|
|
|
== Noncompliant Code Example
|
|
|
|
----
|
|
class Empty:
|
|
pass
|
|
|
|
empty = Empty()
|
|
|
|
for a in empty: # Noncompliant
|
|
print(a)
|
|
|
|
a, b, c = empty # Noncompliant
|
|
|
|
print(*empty) # Noncompliant
|
|
|
|
[1, 2, 3, *empty] # Noncompliant
|
|
|
|
# yield from
|
|
def generator():
|
|
yield from Empty() # Noncompliant
|
|
|
|
# async generators
|
|
async def async_generator():
|
|
yield 1
|
|
|
|
a, *rest = async_generator() # Noncompliant
|
|
for a in async_generator(): # Noncompliant; "async" is missing before "for"
|
|
print(a)
|
|
----
|
|
|
|
== Compliant Solution
|
|
|
|
----
|
|
class MyIterable:
|
|
def __init__(self, values):
|
|
self._values = values
|
|
|
|
def __iter__(self):
|
|
return iter(self._values)
|
|
|
|
my_iterable = MyIterable(range(10))
|
|
|
|
for a in my_iterable:
|
|
print(a)
|
|
|
|
a, b, *c = my_iterable
|
|
|
|
print(*my_iterable)
|
|
|
|
[1, 2, 3, *my_iterable]
|
|
|
|
# yield from
|
|
def generator():
|
|
yield from subgenerator()
|
|
|
|
def subgenerator():
|
|
yield 1
|
|
|
|
# async generators
|
|
async def async_generator():
|
|
yield 1
|
|
|
|
async for a in async_generator():
|
|
print(a)
|
|
----
|
|
|
|
== See
|
|
|
|
* https://www.python.org/dev/peps/pep-0234/#python-api-specification[PEP 234 - Iterators]
|
|
* https://docs.python.org/3/library/stdtypes.html#iterator-types[Python documentation - Iterator Types]
|