[Python-Dev] cpython: Rename contextlib.ignored() to contextlib.ignore().

PJ Eby pje at telecommunity.com
Sun Oct 13 21:16:54 CEST 2013


On Sun, Oct 13, 2013 at 1:58 PM, Alexander Belopolsky
<alexander.belopolsky at gmail.com> wrote:
> People who write code using contextlib
> are expected to know

People who *read* that code while learning Python cannot be expected
to know that it is not really possible to ignore errors in Python.

If this feature is used under any name that implies such, it will
within a few years become a FAQ and well-known wart, not to mention a
meme that "contextlib.ignore() is buggy, it only works if the error is
thrown from a single operation performed in C".

I say this latter phrasing because now that I've had time to think
about it, it is not at all merely a question of whether you wrap a
single line or single operation.

Quick, is this a safe use, or not:

    with ignore(OSError):
         delete_widget_files(spam)

It sort of depends on the implementation of delete_widget_files, doesn't it?

In contrast:

   with abort_on(OSError):
         delete_widget_files(spam)

it's immediately clear that the error isn't going to be ignored; the
operation will be aborted.  Very different concept.


> that it is not a good idea to keep resources
> multiple unrelated statements within the
> with block will raise a mental red flag.

How will someone know this when they are reading code they found on
the internet?

It's one thing to have an operation whose name implies, "you need to
do more research to understand this".  But it's an entirely different
(and dangerous) thing to have an operation whose name implies you
already know everything you need to know, no need to think or study
further...  especially if what you know is actually wrong!


> It is also easy for
> lint-like tools to warn about abuse of ignore().

Since it's not sufficient to require a single operation, how will a
lint-like tool check this?

For example:

    with ignore(AnError, OtherError):
         ping.pongy(foo, bar.spam(), fizzy())

Is this valid code, or not?  If you can't tell, how will a non-human
lint tool tell?


> Let's not try to improve readability of bad code

Actually, I want the good code to be "readable" in the sense of
understanding what the operation does, so that people copying it don't
end up with a serious misunderstanding of how the context manager
actually works.

There is no way that naive users aren't going to read it as ignoring
errors, and use it with something like:

    with ignore(OSError):
        for f in myfiles: os.unlink(f)

But this version is obviously *wrong*:

    with abort_on(OSError):
        for f in myfiles: os.unlink(f)

Upon looking at this code, you will quickly realize that you don't
intend to abort the loop, only the unlink, and will therefore rewrite
it to put the loop on the outside.

So, I am only trying to "improve readability of bad code" in the sense
of making it *obvious* that the code is in fact bad.  ;-)

(To put it another way, "ignore()" improves the readability of bad
code in the above example, because it makes the bad code look like
it's good.)


More information about the Python-Dev mailing list