[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