caught = False
try:
raise ValueError('test')
except ValueError:
caught = True
assert caught
msg = None
try:
raise TypeError('the message')
except TypeError as e:
msg = repr(e)
assert msg == "TypeError('the message')"
which = None
try:
raise TypeError('type error')
except ValueError:
which = 'value'
except TypeError:
which = 'type'
except:
which = 'bare'
assert which == 'type'
caught_bare = False
try:
raise KeyError('key')
except:
caught_bare = True
assert caught_bare
else_ran = False
try:
x = 1
except:
pass
else:
else_ran = True
assert else_ran
else_ran_with_exc = True
try:
raise ValueError()
except ValueError:
pass
else:
else_ran_with_exc = False
assert else_ran_with_exc
finally_ran = False
try:
x = 1
finally:
finally_ran = True
assert finally_ran
finally_after_catch = False
try:
raise ValueError()
except ValueError:
pass
finally:
finally_after_catch = True
assert finally_after_catch
caught_reraised = False
try:
try:
raise ValueError('original')
except ValueError:
raise except ValueError as e:
caught_reraised = repr(e) == "ValueError('original')"
assert caught_reraised
outer_caught = False
inner_caught = False
try:
try:
raise ValueError('inner')
except ValueError:
inner_caught = True
raise TypeError('outer')
except TypeError:
outer_caught = True
assert inner_caught and outer_caught, 'nested exceptions should work'
caught_by_base = False
try:
raise KeyError('key')
except Exception:
caught_by_base = True
assert caught_by_base
caught_tuple = False
try:
raise TypeError('type')
except (ValueError, TypeError):
caught_tuple = True
assert caught_tuple
def try_return_finally():
try:
return 1
finally:
pass
assert try_return_finally() == 1
def finally_return_overrides():
try:
return 1
finally:
return 2
assert finally_return_overrides() == 2
handler_exc_propagated = False
try:
try:
raise ValueError()
except ValueError:
raise TypeError('from handler')
except TypeError as e:
handler_exc_propagated = repr(e) == "TypeError('from handler')"
assert handler_exc_propagated
def finally_return_overrides_handler_exc():
try:
raise TypeError('Error')
finally:
return 'finally wins handler'
assert finally_return_overrides_handler_exc() == 'finally wins handler'
def finally_return_overrides_handler_exc2():
try:
try:
raise ValueError('inner')
except ValueError:
raise TypeError('handler failure')
finally:
return 'finally wins handler'
assert finally_return_overrides_handler_exc2() == 'finally wins handler'
def finally_return_overrides_else_exc():
try:
try:
pass
except ValueError:
pass
else:
raise RuntimeError('else failure')
finally:
return 'finally wins else'
assert finally_return_overrides_else_exc() == 'finally wins else'
e_cleared = False
try:
try:
raise ValueError('test')
except ValueError as e:
pass
_ = e except NameError:
e_cleared = True
assert e_cleared
unhandled_propagated = False
try:
try:
raise KeyError('unhandled')
except ValueError:
pass except KeyError as e:
unhandled_propagated = repr(e) == "KeyError('unhandled')"
assert unhandled_propagated
finally_before_propagate = False
try:
try:
raise KeyError('propagate')
except ValueError:
pass
finally:
finally_before_propagate = True
except KeyError:
pass
assert finally_before_propagate
finally_exc_wins = False
try:
try:
raise ValueError('original')
finally:
raise TypeError('from finally')
except TypeError as e:
finally_exc_wins = repr(e) == "TypeError('from finally')"
except ValueError:
finally_exc_wins = False assert finally_exc_wins
else_exc_propagated = False
try:
try:
pass except:
pass
else:
raise ValueError('from else')
except ValueError as e:
else_exc_propagated = repr(e) == "ValueError('from else')"
assert else_exc_propagated
finally_after_else_exc = False
try:
try:
pass
except:
pass
else:
raise ValueError('else error')
finally:
finally_after_else_exc = True
except ValueError:
pass
assert finally_after_else_exc
caught_key_by_lookup = False
try:
raise KeyError('key')
except LookupError:
caught_key_by_lookup = True
assert caught_key_by_lookup
caught_index_by_lookup = False
try:
raise IndexError('index')
except LookupError:
caught_index_by_lookup = True
assert caught_index_by_lookup
caught_value_by_lookup = False
try:
try:
raise ValueError('value')
except LookupError:
caught_value_by_lookup = True
except ValueError:
pass
assert not caught_value_by_lookup, 'LookupError should NOT catch ValueError'
caught_zero_by_arith = False
try:
raise ZeroDivisionError('zero')
except ArithmeticError:
caught_zero_by_arith = True
assert caught_zero_by_arith
caught_overflow_by_arith = False
try:
raise OverflowError('overflow')
except ArithmeticError:
caught_overflow_by_arith = True
assert caught_overflow_by_arith
caught_notimpl_by_runtime = False
try:
raise NotImplementedError('not impl')
except RuntimeError:
caught_notimpl_by_runtime = True
assert caught_notimpl_by_runtime
caught_recursion_by_runtime = False
try:
raise RecursionError('recursion')
except RuntimeError:
caught_recursion_by_runtime = True
assert caught_recursion_by_runtime
caught_timeout_by_oserror = False
try:
raise TimeoutError('timed out')
except OSError:
caught_timeout_by_oserror = True
assert caught_timeout_by_oserror, 'OSError should catch TimeoutError'
caught_timeout_specifically = False
try:
raise TimeoutError('timed out')
except TimeoutError:
caught_timeout_specifically = True
except OSError:
pass
assert caught_timeout_specifically, 'TimeoutError handler should match TimeoutError'
try:
raise TimeoutError('timed out')
except TimeoutError as e:
assert isinstance(e, TimeoutError), 'exception should be instance of TimeoutError'
assert isinstance(e, OSError), 'TimeoutError should be instance of OSError'
assert not isinstance(e, ValueError), 'TimeoutError should not be ValueError'
caught_by_tuple_base = False
try:
raise KeyError('key')
except (ValueError, LookupError):
caught_by_tuple_base = True
assert caught_by_tuple_base
try:
raise KeyError('key')
except KeyError as e:
assert isinstance(e, KeyError)
assert isinstance(e, LookupError)
assert isinstance(e, Exception)
assert not isinstance(e, ArithmeticError), 'KeyError should not be ArithmeticError'
try:
raise ZeroDivisionError('zero')
except ZeroDivisionError as e:
assert isinstance(e, ZeroDivisionError)
assert isinstance(e, ArithmeticError)
assert isinstance(e, Exception)
assert not isinstance(e, LookupError), 'ZeroDivisionError should not be LookupError'
multi_no_match_propagated = False
try:
try:
raise MemoryError('out of memory')
except ValueError:
pass
except TypeError:
pass
except KeyError:
pass
except MemoryError as e:
multi_no_match_propagated = repr(e) == "MemoryError('out of memory')"
assert multi_no_match_propagated
caught_value_by_base = False
try:
raise ValueError('value')
except BaseException:
caught_value_by_base = True
assert caught_value_by_base
caught_key_by_base = False
try:
raise KeyError('key')
except BaseException:
caught_key_by_base = True
assert caught_key_by_base
caught_type_by_base = False
try:
raise TypeError('type')
except BaseException:
caught_type_by_base = True
assert caught_type_by_base
caught_keyboard_by_base = False
try:
raise KeyboardInterrupt()
except BaseException:
caught_keyboard_by_base = True
assert caught_keyboard_by_base
caught_sysexit_by_base = False
try:
raise SystemExit()
except BaseException:
caught_sysexit_by_base = True
assert caught_sysexit_by_base
caught_keyboard_by_exc = False
try:
try:
raise KeyboardInterrupt()
except Exception:
caught_keyboard_by_exc = True
except BaseException:
pass
assert not caught_keyboard_by_exc, 'Exception should NOT catch KeyboardInterrupt'
caught_sysexit_by_exc = False
try:
try:
raise SystemExit()
except Exception:
caught_sysexit_by_exc = True
except BaseException:
pass
assert not caught_sysexit_by_exc, 'Exception should NOT catch SystemExit'
caught_value_by_exc = False
try:
raise ValueError('test')
except Exception:
caught_value_by_exc = True
assert caught_value_by_exc
try:
raise ValueError('test')
except ValueError as e:
assert isinstance(e, BaseException)
try:
raise KeyboardInterrupt()
except KeyboardInterrupt as e:
assert isinstance(e, BaseException)
assert not isinstance(e, Exception), 'KeyboardInterrupt should NOT be instance of Exception'
try:
raise SystemExit()
except SystemExit as e:
assert isinstance(e, BaseException)
assert not isinstance(e, Exception), 'SystemExit should NOT be instance of Exception'
caught_by_tuple_with_base = False
try:
raise KeyboardInterrupt()
except (ValueError, BaseException):
caught_by_tuple_with_base = True
assert caught_by_tuple_with_base
_msg = 'catching classes that do not inherit from BaseException is not allowed'
_rejected = False
try:
try:
raise TypeError()
except ((ValueError,),):
assert False, 'nested tuple should not be descended into'
except TypeError as exc:
_rejected = True
assert str(exc) == _msg, f'unexpected message: {exc}'
assert _rejected
_rejected = False
try:
try:
raise TypeError()
except ((ValueError,), (KeyError, TypeError)):
assert False, 'tuple of tuples should not match'
except TypeError as exc:
_rejected = True
assert str(exc) == _msg, f'unexpected message: {exc}'
assert _rejected
_rejected = False
try:
try:
raise TypeError()
except (TypeError, (ValueError,)):
assert False, 'must validate whole tuple, not short-circuit on match'
except TypeError as exc:
_rejected = True
assert str(exc) == _msg, f'unexpected message: {exc}'
assert _rejected
_rejected = False
try:
try:
raise TypeError()
except ((ValueError,), TypeError):
assert False, 'leading nested tuple should be rejected'
except TypeError as exc:
_rejected = True
assert str(exc) == _msg, f'unexpected message: {exc}'
assert _rejected
deep = (ValueError,)
for _ in range(1000):
deep = (deep,)
_rejected = False
try:
try:
raise TypeError()
except deep:
assert False, 'deeply nested tuple should not be descended into'
except TypeError as exc:
_rejected = True
assert str(exc) == _msg, f'unexpected message: {exc}'
assert _rejected
caught_empty_tuple = False
try:
try:
raise TypeError('propagate')
except ():
assert False, 'empty tuple never matches'
except TypeError as exc:
caught_empty_tuple = True
assert str(exc) == 'propagate', f'unexpected message: {exc}'
assert caught_empty_tuple
big_flat = tuple([ValueError] * 5000 + [TypeError])
caught_big_flat = False
try:
raise TypeError()
except big_flat:
caught_big_flat = True
assert caught_big_flat
def _return_from_except_then_bare_raise_in_finally() -> None:
try:
try:
raise ValueError('original')
except ValueError:
return
finally:
try:
raise except ValueError:
assert False, '`return` from except must clear the exception before finally runs'
except RuntimeError as exc:
assert str(exc) == 'No active exception to reraise'
_return_from_except_then_bare_raise_in_finally()
def _return_from_doubly_nested_except() -> None:
try:
try:
try:
raise ValueError('inner')
except ValueError:
raise TypeError('middle')
except TypeError:
return
finally:
try:
raise
except (ValueError, TypeError):
assert False, "`return` from doubly-nested except must clear every handler's exception state"
except RuntimeError as exc:
assert str(exc) == 'No active exception to reraise'
_return_from_doubly_nested_except()
def _returns_from_except_no_finally() -> str:
try:
raise ValueError('original')
except ValueError:
return 'returned'
assert _returns_from_except_no_finally() == 'returned'
try:
raise except ValueError:
assert False, "caller should not see inner function's exception as current"
except RuntimeError as exc:
assert str(exc) == 'No active exception to reraise'
try:
try:
try:
raise ValueError('first')
except ValueError:
raise TypeError('second')
except TypeError:
raise KeyError('third')
except KeyError as third:
assert str(third) == "'third'"
try:
raise
except RuntimeError as exc:
assert str(exc) == 'No active exception to reraise'
try:
raise ValueError('outer')
except ValueError as caught:
try:
raise KeyError('inner')
except KeyError:
pass
try:
raise
except ValueError as bare:
assert str(bare) == 'outer'
def _callee_raises_and_handles():
try:
raise ValueError('callee internal')
except ValueError:
pass
_callee_raises_and_handles()
try:
raise
except RuntimeError as exc:
assert str(exc) == 'No active exception to reraise'
_return_through_inner_finally_log: list[tuple[str, str]] = []
def _return_through_inner_finally() -> str:
try:
raise ValueError('outer')
except ValueError:
try:
return 'done'
finally:
try:
raise except ValueError as caught:
_return_through_inner_finally_log.append(('ValueError', str(caught)))
except RuntimeError as e:
_return_through_inner_finally_log.append(('RuntimeError', str(e)))
return 'unreachable'
assert _return_through_inner_finally() == 'done'
assert _return_through_inner_finally_log == [('ValueError', 'outer')], (
f'expected outer ValueError to remain active inside inner finally, got {_return_through_inner_finally_log!r}'
)
try:
raise
except RuntimeError as exc:
assert str(exc) == 'No active exception to reraise'
_two_finally_log: list[tuple[str, str, str]] = []
def _return_through_two_finallys() -> str:
try:
raise ValueError('A')
except ValueError:
try: try:
raise TypeError('B')
except TypeError:
try: return 'done'
finally:
try:
raise except TypeError as t:
_two_finally_log.append(('inner_finally', 'TypeError', str(t)))
except ValueError as v:
_two_finally_log.append(('inner_finally', 'ValueError', str(v)))
finally:
try:
raise except ValueError as v:
_two_finally_log.append(('outer_finally', 'ValueError', str(v)))
except TypeError as t:
_two_finally_log.append(('outer_finally', 'TypeError', str(t)))
except RuntimeError as r:
_two_finally_log.append(('outer_finally', 'RuntimeError', str(r)))
return 'fallback'
assert _return_through_two_finallys() == 'done'
assert _two_finally_log == [
('inner_finally', 'TypeError', 'B'),
('outer_finally', 'ValueError', 'A'),
], f'unexpected log {_two_finally_log!r}'
def _bare_raise_identity():
try:
try:
raise ValueError('ident')
except ValueError as inner:
captured = inner
raise
except ValueError as outer:
return outer is captured
assert _bare_raise_identity() is True, 'bare raise should re-raise the same object'
def _explicit_raise_identity():
try:
raise ValueError('ident')
except ValueError as first:
captured = first
try:
raise captured
except ValueError as second:
return second is captured
assert _explicit_raise_identity() is True, 'raise <instance> should re-raise the same object'
def _identity_through_finally():
order = []
try:
try:
raise ValueError('deep')
except ValueError as inner:
captured = inner
try:
raise
finally:
order.append('finally')
except ValueError as outer:
return outer is captured, order
assert _identity_through_finally() == (True, ['finally'])