Why use contextlib.suppress as opposed to try/except with pass?

python, python-3.x

Solution

It is two lines less code without sacrificing readability.

It might be especially convenient for nested or consecutive code blocks. Compare:

try:
    a()
    try:
        b()
    except B:
        pass
except A:
    pass

vs.:

with suppress(A):
    a()
    with suppress(B):
        b()

It also allows to express the intent:

- `with suppress(SpecificError): do_something()` says don't propagate the error if it is raised while doing something

- `try: do_something() except SpecificError: pass` says do something and don't propagate the error if it is raised

It is less important because most people won't notice the difference.

Problem

Why would one use `contextlib.suppress` to suppress an exception, instead of `try`/`except` with a `pass`? There is no difference in the amount of characters between these two methods (if anything, `suppress` has more characters), and even though code is often counted in LOC instead of characters, `suppress` also seems to be much slower than `try`/`except` in both cases, when an error is raised and when it's not: ``` Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 bit (AMD64)] on win32 Type "copyright", "credits" or "license()" for more information. >>> from timeit import timeit >>> # With an error >>> timeit("""with suppress(ValueError): x = int('a')""", setup="from contextlib import suppress") 1.9571568971892543 >>> timeit("""try: x = int('a') except ValueError: pass""") 1.0758466499161656 >>> # With no error >>> timeit("""with suppress(ValueError): x = int(3)""", setup="from contextlib import suppress") 0.7513525708063895 >>> timeit("""try: x = int(3) except ValueError: pass""") 0.10141028937128027 >>> ```

Original source