With apology on reviving a pretty-dead thread, I would like to note a completely different use case for exception annotations.
Specifically, I may want to specify an interface with a function signature that indicates which exceptions will be thrown under certain edge cases. As a basic example, with the proposed syntax:
class MyObjectHandler(ABC):
....
@abstractmethod
def get_by_id(id_: str) -> None ^ NoSuchObjectException:
...
A type checker will not check that you handle or raise all exceptions that might be raised in your code, or even that you explicitly hint all exceptions that you raise; instead, it may check only that you do raise those exceptions that you explicitly hinted.
This is very useful for two reasons:
One, that when you implement MyObjectInterface
, you’ll know to raise the proper exception if a user tried to get a nonexisting object. Today this info will sit in the docstring of the method in the base class, but this is much less concise and much easier to miss — IDEs will generate the function signature in implementation stub, but not the docstring.
That Interface implementations handle edge cases in a consistent manner is extremely important, because the functions that use these interfaces must be able to handle them themselves. The code that uses MyObjectHandler
wants to know when the get operation fails for this reason. Will it return None? Will it raise an exception? If so, which type? Being able to look at the type hinting both at implementation and at use has an immense benefit.
Two, at runtime, frameworks that generate UI out of pythonic functions, like fastapi
and typer
, will be able to automatically generate documentation for error responses.
As an example, fastapi
could provide some way to specify the status code of exception types, and then if it knows that an api function raises NoSuchObjectException
, the generated openapi.json could detail a possible response of 404 if the requested object does not exist. This would save a great amount of time writing down your possible responses by hand, which is what you have to do currently — as fastapi
simply has no way to know otherwise.