[Python-Dev] PEP 479 and asyncio (original) (raw)

Nick Coghlan ncoghlan at gmail.com
Fri Nov 28 03:49:47 CET 2014


On 28 November 2014 at 08:09, Victor Stinner <victor.stinner at gmail.com> wrote:

2014-11-27 22:54 GMT+01:00 Victor Stinner <victor.stinner at gmail.com>:

I don't see how it would work. If it cannot be fixed, would it make sense to allow trollius to continue to work as it currently works with something like "from past import generatordontstop"?

I think between contextlib and Trollius, the case is starting to be made for raising an UnhandledStopIteration subclass of RuntimeError, rather than a generic RuntimeError. We have at least two known cases now where code that works with generators-as-coroutines has a valid reason for wanting to distinguish "arbitrary runtime error" from "unhandled StopIteration exception". While catching RuntimeError and looking for StopIteration in cause works, it feels messier and harder to explain than just naming the concept by giving it a dedicated exception type.

Trollius would still need an adapter to be called from asyncio, though. Something like:

def implicit_stop(g):
    try:
        yield from g
    except UnhandledStopIteration as exc:
        return exc.__cause__.value

Then Victor's example would become:

class Return(StopIteration):
    pass

def return_value(value):
    if 0:
        yield
    raise Return(value)

def add_one(gen):
    value = (yield from gen)
    return value + 1

def consume_generator(gen):
    while True:
        try:
            next(gen)
        except StopIteration as exc:
            return exc.value

gen1 = return_value(3)
if PEP479:
    gen1 = implicit_stop(gen1)
gen2 = add_one(gen1)
print(consume_generator(gen2))

When I talked with a friend about the transition from Python 2 to Python 3, he asked me why there was not "from past import division". He wants to add this to his code to not have to worry that a division may fail "somewhere" in his code.

Maybe it would ease upgrades to newer versions of Python if we consider keeping the old behaviour for people who don't have time to port their old code (for no immediate benefit), but need to upgrade because newer OS only provide newer version of Python. (What is the cost of keeping the old behaviour: maintain the code and runtime overhead?)

The main problem with never deprecating anything is an ever-increasing cognitive burden in learning the language, as well as losing the ability to read code in isolation without knowing what flags are in effect.

Currently, folks that only work in Python 3 don't need to know how division worked in Python 2, or that print was ever a statement, etc. If those old behaviours could be selectively turned back on, then everyone would still need to learn them, and you couldn't review code in isolation any more: there may be a past import at the top of the module making it do something different.

If organisations really want to let their code bitrot (and stay on the treadmill of big expensive high risk updates every decade or so), they can, but they have to do it by running on old versions of Python as well - that gives maintainers a clear understanding that if they want to understand the code, they have to know how Python X.Y worked, rather than being able to assume modern Python.

Regards, Nick.

-- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia



More information about the Python-Dev mailing list