Chaining & Context Managers — Series 2

Preview — 3 of 10 questions

What is the output of the following code?

javascript
class AppError(Exception):
    pass

class NetworkError(AppError):
    pass

class ValidationError(AppError):
    pass

def process(kind):
    if kind == "network":
        raise NetworkError("connection failed")
    elif kind == "validation":
        raise ValidationError("bad input")
    return "ok"

for kind in ["network", "validation", "other"]:
    try:
        print(process(kind))
    except AppError as e:
        print(f"caught {type(e).__name__}: {e}")
Acaught AppError: connection failed, caught AppError: bad input, ok — type(e).__name__ always reports the class the except clause was written for, not the actual raised class.
Bcaught NetworkError: connection failed, caught NetworkError: bad input, ok
COnly the first exception is caught; process("validation") raises uncaught, since except AppError: only matches its exact class, not subclasses.
Dcaught NetworkError: connection failed, caught ValidationError: bad input, ok

What is the output of the following code?

javascript
class NegativeAgeError(ValueError):
    pass

def validate(age):
    if age < 0:
        raise NegativeAgeError(f"age {age} is negative")
    return age

try:
    validate(-5)
except ValueError as e:
    print("caught as ValueError:", e)

try:
    validate(-3)
except NegativeAgeError as e:
    print("caught as NegativeAgeError:", e)
Acaught as ValueError: age -5 is negative, caught as NegativeAgeError: age -3 is negative
Bcaught as ValueError: age -5 is negative, then NegativeAgeError propagates uncaught — a subclass of a built-in exception can only be caught by its own exact type, not a more specific except clause for itself.
CTypeError: cannot subclass ValueError
DBoth calls raise uncaught, since catching ValueError doesn't automatically also catch a subclass like NegativeAgeError.

What is the output of the following code?

javascript
from contextlib import suppress

def risky(n):
    if n == 0:
        raise ZeroDivisionError
    if n < 0:
        raise ValueError("negative")
    return 10 / n

for n in [2, 0, -1]:
    with suppress(ZeroDivisionError, ValueError):
        print(risky(n))
print("done")
A5.0, done — suppress() only accepts a single exception type, so the call itself raises TypeError before ever reaching the loop.
B5.0, done
C5.0, then the program crashes on n=0, since suppress() can only catch one specific exception type per with block.
DNothing at all is printed — suppress also silently discards the print() calls themselves.

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.