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 -- https://mail.python.org/mailman/listinfo/python-list