On Sat, Sep 26, 2020 at 5:27 AM Oscar Benjamin
On Fri, 25 Sep 2020 at 18:59, Chris Angelico
wrote: On Sat, Sep 26, 2020 at 2:32 AM Oscar Benjamin
wrote: I do agree but maybe that suggests a different role for annotated exceptions in Python. Rather than attempting to enumerate all possible exceptions annotations could be used to document in a statically analysable way what the "expected" exceptions are. A type checker could use those to check whether a caller is handling the *expected* exceptions rather than to verify that the list of *all* exceptions possibly raised is exhaustive.
Consider an example:
def inverse(M: Matrix) -> Matrix: raises(NotInvertibleError) if determinant(M) == 0: raise NotInvertibleError rows, cols = M.shape for i in range(rows): for j in range(cols): ...
Here the function is expected to raise NotInvertibleError for some inputs.
Please no. Once again, this will encourage "handling" of errors by suppressing them. Don't have anything that forces people to handle exceptions they can't handle.
Why would anyone be forced to "handle" the exceptions?
The suggestion (which you've snipped away) was not that it would be a type-checking error to call the inverse function without catching the exception. It only becomes a type-checking error if a function calls the inverse function and claims not to raise the exception. The checker just verifies the consistency of the different claims about what is raised.
Forcing people to declare it is exactly the same as forcing them to handle it every other way. There are many MANY bad ways this can go, most of which have been mentioned already: 1) Catching exceptions and doing nothing, just so your linter shuts up 2) Catching exceptions and raising a generic "something went wrong" error so that's the only thing you have to declare 3) Declaring that you could raise BaseException, thus adding useless and meaningless boilerplate to your functions 4) Redeclaring every exception all the way up the chain, and having to edit them every time something changes 5) Copying and pasting a gigantic list of exceptions onto every function's signature And what are the possible *good* ways to use this? What do you actually gain? So far, the only use-case I've heard is "IDEs might help you tab-complete an except clause". That's only going to be useful if the exception tracking is accurate all the way up and down the tree, and that's only going to happen if it's done by analysis, NOT by forcing people to declare them. I've worked with Java's checked exceptions, which is what you're getting at here. They're terrible. The best way to handle them is to ensure that all your exceptions are RuntimeErrors so they don't get checked by the compiler. ChrisA