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

Craig Yoshioka craigyk at me.com
Wed Feb 29 22:47:45 CET 2012

On Feb 29, 2012, at 11:55 AM, Ethan Furman wrote:

> 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.

I read the rant, and I agree in principle, but I think it's also a far stretch to draw a line between a very confusing non-standard example of macros in C, and documentable behavior of a built-in statement.  That is, the only reason you might say with would be hiding flow-control is because people don't currently expect it to.  I also think that when people use non-builtin contextmanagers it's usually within a very specific... context (*dammit*), and so they are likely to look up why they are using an object as a context manager.  That's where you would document the behavior:

with uncached(path):
  # code here only executes if the path does not exist  

> 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())

that is an interesting alternative... do you see that as much better than __enter__ passing some sort of unique value to signal the skip?  I can't say I'm enamored of doing it with a signal value, just thought it would be easier to implement (and not require more exception handling):

   _exit = cm.__exit__
   _var = cm.__enter__()
   if _var == SkipWithBody:
       VAR = _var # if 'as' clause is present
       # with statement body

More information about the Python-ideas mailing list