raise
How Python code signals failure: raise an exception object (or class), re-raise the current one with a bare raise, and record why with from.
raise ValueError('bad input')
except OSError: log_it() raise
except KeyError as e: raise LookupError(msg) from e
raise TypeError(msg) from None
Demo
def set_age(age): if age < 0: raise ValueError(f'age must be >= 0, got {age}') return age set_age(30)
In the raise tab the message is built with an f-string at the moment of raising — include the offending value, it is the most useful part of a traceback. In the from tab, err.__cause__ is the original IndexError object; an uncaught chained error prints both tracebacks joined by "The above exception was the direct cause of the following exception". A float index (1e21 or more) raises TypeError instead, which nothing here catches. In the bare raise tab the message the caller sees is the original one: bare raise does not create a new exception.
Syntax slots
| Name | Type | Required | Description |
|---|---|---|---|
| exception | expression | no | An exception instance, or a class (instantiated with no arguments). Omitted: re-raise the exception currently being handled. |
| from cause | expression | no | An exception (or class) stored as __cause__ of the new one, or None to hide the implicit __context__ from the traceback. |
Common patterns
def withdraw(amount): if amount <= 0: raise ValueError(f'amount must be positive, got {amount!r}')
class ConfigError(Exception): pass raise ConfigError('missing key: port')
try: data = json.loads(text) except json.JSONDecodeError as e: raise ConfigError('config is not valid JSON') from e
def area(self): raise NotImplementedError('subclasses must implement area()')
Examples
Pitfalls
compile("raise ValueError, 'bad'", '<demo>', 'exec')
raise ValueError('bad')
raise NotImplemented
raise NotImplementedError('area() not written yet')
try: try: {}['port'] except KeyError: raise RuntimeError('config broken') except RuntimeError as err: print(err.__cause__)
try: try: {}['port'] except KeyError as e: raise RuntimeError('config broken') from e except RuntimeError as err: print(repr(err.__cause__))
When to use
- A function receives input it cannot work with (ValueError, TypeError)
- A situation the caller must deal with, where returning a special value would be ignored
- Re-raising after logging or cleanup (bare raise)
- Wrapping a low-level error in your own type (raise … from e)
- Internal "this cannot happen" checks during development → assert
- Normal, expected outcomes like "not found" in a search → return None or a default
- Stopping a generator → return (raising StopIteration inside one becomes RuntimeError)
Notes
FAQ
Inside an except block both re-raise the same exception object. Bare raise is the idiom: it is shorter and needs no as name. raise e additionally adds the current line to the traceback.