[Python-ideas] revisit pep 377: good use case?

Nick Coghlan ncoghlan at gmail.com
Wed Feb 29 22:11:39 CET 2012


On Thu, Mar 1, 2012 at 6:29 AM, Arnaud Delobelle <arnodel at gmail.com> wrote:
> On 29 February 2012 17:49, Craig Yoshioka <craigyk at me.com> wrote:
>> I've tried classes, decorators, and passing the conditional using 'as', as
>> suggested by Michael,  so I disagree that with is not suitable here since I
>> have yet to find a better alternative.  If you want I can give pretty
>> concrete examples in the ways they aren't as good.  Furthermore, I think it
>> could be argued that it makes more sense to be able to safely skip the with
>> body without the user of the with statement having to manually catch the
>> exception themselves....
>
> From PEP 343:
>
>    But the final blow came when I read Raymond Chen's rant about
>    flow-control macros[1].  Raymond argues convincingly that hiding
>    flow control in macros makes your code inscrutable, and I find
>    that his argument applies to Python as well as to C.
>
> So it is explicitly stated that the with statement should not be
> capable of controlling the flow.

Indeed.

Craig, if you want to pursue this to the extent of writing up a full
PEP, I suggest starting with the idea I briefly wrote up a while ago
[1].

Instead of changing the semantics of __enter__, add a new optional
method __entered__ to the protocol that executes inside the with
statement's implicit try/except block.

That is (glossing over the complexities in the real with statement
expansion), something roughly like:

    _exit = cm.__exit__
    _entered = getattr(cm, "__entered__", None)
    _var = cm.__enter__()
    try:
        if _entered is not None:
            _var = _entered(_var)
        VAR = _var # if 'as' clause is present
        # with statement body
    finally:
        _exit(*sys.exc_info())

Then CM's would be free to skip directly from __entered__ to __exit__
by raising a custom exception. GeneratorContextManagers could
similarly be updated to handle the case where the underlying generator
doesn't yield.

However, that last point highlights why I no longer like the idea: it
makes it *really* easy to accidentally create CM's that, instead of
throwing an exception if you try to reuse them inappropriately, will
instead silently skip the with statement body. The additional
expressiveness provided by such a construct is minimal, but the
additional risk of incorrectly silencing errors is quite high - that's
not a good trade-off for the overall language design.

[1] http://readthedocs.org/docs/ncoghlan_devs-python-notes/en/latest/pep_ideas/skip_with.html

Cheers,
Nick.

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



More information about the Python-ideas mailing list