This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Antony.Lee
Recipients Antony.Lee
Date 2019-08-01.23:33:04
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1564702384.75.0.948740630584.issue37743@roundup.psfhosted.org>
In-reply-to
Content
The docs for ContextDecorator (of which contextmanager is a case) describe its semantics as:

    ... for any construct of the following form:

    def f():
        with cm():
            # Do stuff

    ContextDecorator lets you instead write:

    @cm()
    def f():
        # Do stuff

However, when decorating a generator, the equivalence is broken:

    from contextlib import contextmanager

    @contextmanager
    def cm():
        print("start")
        yield
        print("stop")

    def gen_using_with():
        with cm():
            yield from map(print, range(2))

    @cm()
    def gen_using_decorator():
        yield from map(print, range(2))

    print("using with")
    list(gen_using_with())
    print("==========")
    print("using decorator")
    list(gen_using_decorator())

results in

    using with
    start
    0
    1
    stop
    ==========
    using decorator
    start
    stop
    0
    1

i.e., when used as a decorator, the entire contextmanager is executed first before iterating over the generator (which is unsurprising given the implementation of ContextDecorator: ContextDecorator returns a function that executes the context manager and returns the generator, which is only iterated over later).

Should this be considered as a bug in ContextDecorator, and should ContextDecorator instead detect when it is used to decorate a generator (e.g. with inspect.isgeneratorfunction), and switch its implementation accordingly in that case?
History
Date User Action Args
2019-08-01 23:33:04Antony.Leesetrecipients: + Antony.Lee
2019-08-01 23:33:04Antony.Leesetmessageid: <1564702384.75.0.948740630584.issue37743@roundup.psfhosted.org>
2019-08-01 23:33:04Antony.Leelinkissue37743 messages
2019-08-01 23:33:04Antony.Leecreate