New submission from Antony Lee <anntzer....@gmail.com>:

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?

----------
components: Library (Lib)
messages: 348878
nosy: Antony.Lee
priority: normal
severity: normal
status: open
title: How should contextmanager/ContextDecorator work with generators?
versions: Python 3.8

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue37743>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to