[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:
_exit(None,None,None)
try:
VAR = _var # if 'as' clause is present
# with statement body
finally:
_exit(*sys.exc_info())
More information about the Python-ideas
mailing list