[Python-Dev] Context management patterns

Glenn Linderman v+python at g.nevcal.com
Sat Oct 19 12:47:45 CEST 2013


On 10/18/2013 11:38 PM, Nick Coghlan wrote:
> However, that's a confusion about exception handling in general, not
> about the suppress context manager in particular. The same potential
> for conceptual confusion exists between:
>
>      for name in ("somefile.tmp", "someotherfile.tmp"):
>          try:
>              os.remove(name)
>          except FileNotFoundError:
>              pass
>
> and:
>
>      try:
>          for name in ("somefile.tmp", "someotherfile.tmp"):
>             os.remove(name)
>      except FileNotFoundError:
>          pass
>
> At the syntactic level, when composing compound statements, the order
> of nesting*always*  matters. The with/for and for/with constructs are
> different, just as if/for and for/if are different. If a student makes
> it through an introductory Python course without learning that much,
> I'd have grave doubts about that course

Students that actually take courses might be OK... they might even read 
some of the documentation.

Indeed the problem can be produced with try/except syntax or with 
with/suppress. That has been obvious from the beginning of the 
discussion, and stated repeatedly.  I suppose it is the "context 
management" connotation that with currently has, that makes me think 
that with/suppress is reasonably likely to get misused... in context 
management uses, one puts long blocks of code under with (not always, 
but often).  In this particular case, that is a problem, yet not all the 
control flow examples would be limited to one line of code in the with 
block. So this is still a very special case, for a very small benefit, 
with an unusual limitation.

I have a new color of paint:

with pass_if( FileNotFoundError ): os_remove("somefile.tmp")

One thing about bikeshedding... after trying lots of colors, you might 
actually find one everyone likes. But if they aren't put out there to 
see, no one knows if they like it or not. And if there are a significant 
number of people that don't like the color, it either means the sun is 
in their eyes, or the color isn't the best, and that is sometimes hard 
to discern.

While I already realized that the with construct is really control flow, 
even the names that indicated that that have been suggested so far, even 
by me, didn't really capture the type of control flow. It hit me, 
reading your last message, that the key part is "pass"... it is an 
action (control flow), and it is the action that would be taken if 
written with try/except syntax.  It isn't the exception, or the 
catching, that are the key.... it is the passing... passing over the 
with block because the exception happened. That even implies you don't 
want to pass much, certainly not a whole loop full of stuff, or a long 
string of statements.

Sadly, all the documentation that references "suppressing" an exception, 
is misleading. Misleading enough that you convinced yourself to rename 
from ignore to suppress after reading it, even though the two are nearly 
synonymous.  The exceptions are not ignored, and the exceptions are not 
suppressed. They are handled by passing (which avoids the need for 
surrounding code to handle them, which is sort of like being ignored or 
suppressed, from the outside looking in... but pass describes the 
behavior for both inside and outside viewpoints!).

> I believe your underlying concerns are actually with the non-local
> flow control possibilities that are inherent in a language that offers
> both exceptions and the ability to suppress them.

Are you referring to a different type of "suppress" than the one you 
just implemented? Where the language allows you to suppress an 
exception, and execution proceeds with the next statement? Where it 
would be more of a declarative style of suppression rather than an 
active "catch and pass". If so, it is more proof that "suppress" is the 
wrong term for your new feature.

Thanks again for sharing the big picture: you have before, but I see 
you've evolved it slightly.  Delayed error handling I've had occasion to 
do, but not yet in Python. The constrained jump pattern is interesting, 
but the example is not complex enough to justify the syntax: the with 
solution is actually longer... if you initialized result they'd be the 
same length.  The problem with the for/else construct is that the "not 
found" case falls through to the "found" case, which can be awkward, but 
that awkwardness isn't really demonstrated in the example. "exit_label" 
is an awkward name, too, since there are no labels, and no exit(). (yes, 
I know you meant exit the loop; naming is hard.)

I haven't yet wrapped my mind around all the possibilities of with 
creating an "empty" object, which gets populated by the various 
execution paths taken, but that combination does seem quite a bit more 
powerful than the simple with statement alone, which only sits at the 
front of a block. try/except/finally/else has lots of keywords and lots 
of places to put code :) Which doesn't always make the code clear, so 
abstractions using with may indeed be helpful... but care will have to 
be taken that the requirement for the added object and its manipulation 
doesn't get more cumbersome than straightforward coding of the problem 
without the abstraction.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20131019/f99b29aa/attachment.html>


More information about the Python-Dev mailing list