The core exception concept
The core concept behind exceptions can be summarized as, "when in doubt, raise an exception". In a typical situation, each Python function or method will return a value or have some documented side-effect. For everything that isn't on the "happy path" that leads to success, the Python approach is to raise an exception.
Even though most exceptions describe erroneous situations, an exception is not necessarily an error. It's merely an exceptional condition that a given function can't handle. For example, iterators raise the StopIteration
exception when they can no longer produce a result item. This is an exceptional situation that occurs just once in the life cycle of an iterator object.
When working with numbers, as a second example, division by zero is exceptional. If we divide by any other value, the happy path leads us to a result. While it's possible to contrive a Not a Number (NaN) value as the result of division by zero...