Editor

Suppress and Count Errors

#346 · Classes · Advanced · 115 XP · about 22 min

contextlib.suppress(KeyError) lets a with block swallow an error quietly. Quiet can hide trouble, though, so you would like to know how often it happens. Build a class Suppress that swallows errors and keeps count.

  • Suppress(*exception_types) takes the exception classes to swallow. Giving none is allowed, and then it swallows nothing.
  • with s: runs a block. If the block raises an exception that is an instance of one of the classes, the exception is swallowed and the program carries on after the block. Any other exception passes through unchanged. with Suppress(...) as s: gives the object itself.
  • @s used as a decorator on a function makes every call of that function behave as if its body ran inside with s:. A call whose exception is swallowed returns None; otherwise the call returns the function's result.
  • count() returns how many exceptions the object has swallowed so far, across all its blocks and calls.
  • counts() returns a dict mapping the class name of each swallowed exception to how many times it was swallowed, in the order the names were first swallowed.
  • last() returns the most recently swallowed exception object, or None if there is none yet.

The same object can be used for any number of blocks, one after another or nested.

Examples

s = Suppress(KeyError, ZeroDivisionError)
with s:
    {}['missing']
with s:
    1 / 0
with s:
    {}['other']
s.count()        # returns 3
s.counts()       # returns {'KeyError': 2, 'ZeroDivisionError': 1}
repr(s.last())   # returns "KeyError('other')"

@s
def ratio(a, b):
    return a / b

ratio(6, 3)      # returns 2.0
ratio(1, 0)      # returns None, and s.count() is now 4

Constraints

  • Up to 100,000 swallowed exceptions on one object
  • The exception classes are ordinary exception classes, and a subclass of a listed class is swallowed too (under its own name)

Fastest solvers

Leaderboard

First solves only, ranked by stars and then time.