Language improvement: Get more from the `for .. else` clause
Victor Savu
victor.nicolae.savu at gmail.com
Sun Jun 26 10:05:47 EDT 2016
tl;dr: 1. Add `StopAsyncIteration.value`, with the same semantic as
`StopIteration.value` (documented in PEP 380).
2. Capture `StopIteration.value` and StopAsyncIteration.value in the
`else` clauses of the `for` and `async for` statements respectively.
Note: I already have a proof-of-concept implementation:
repository: https://github.com/Victor-Savu/cpython
branch: feat/else_capture
Dear members of the Python list,
I am writing to discuss and get the community's opinion on the following two
ideas:
1. Capture the `StopIteration.value` in the `else` clause of the `for ..
else`
statement:
Generators raise StopIteration on the return statement. The exception
captures the return value. The `for` statement catches the
`StopIteration`
exception to know when to jump to the optional `else` statement, but
discards the enclosed return value.
I want to propose an addition to the Python syntax which gives the
option
to capture the return value in the `else` statement of the `for` loop:
```
def holy_grenade():
yield 'One ...'
yield 'Two ...'
yield 'Five!'
return ('Galahad', 'Three')
for count_ in holy_grenade():
print("King Arthur: {count_}")
else knight, correction: # << new capture syntax here
print(f"{knight}: {correction}, Sir!")
print(f"King Arthur: {correction}!")
```
prints:
```
King Arthur: One ...
King Arthur: Two ...
King Arthur: Five!
Galahad: Three, Sir!
King Arthur: Three!
```
Of course, the capture expression is optional, and omitting it preserves
the current behavior, making this proposed change backwards compatible.
Should the iterator end without raising the StopIteration exception,
the value `None` will be implicitly passed to the capture expression. In
the example above, this will result in:
```
TypeError: 'NoneType' object is not iterable
```
because of the attempt to de-structure the result into `knight` and
`correction`.
2. Add a `StopAsyncIteration.value` member which can be used to transfer
information about the end of the asynchronous iteration, in the same way
the `StopIteration.value` member is used (as documented in PEP 380).
Capture this value in the in the else clause of the `async for`
statement
in the same way as proposed for the `StopIteration.value` in the
previous
point.
You can find a working proof-of-concept implementation of the two proposed
changes in my fork of the semi-official cpython repository on GitHub:
repository: https://github.com/Victor-Savu/cpython
branch: feat/else_capture
Disclaimer: My Internet searching skills have failed me and I could not find
any previous discussion on any of the two topics. If you are aware of such
discussion, I would be grateful if you could point it out.
I look forward to your feedback, ideas, and (hopefully constructive)
criticism!
Best regards,
Victor
More information about the Python-list
mailing list