-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add optional exception checking #1773
Comments
I've thought about this a bit but there are no concrete plans. For this to work in practice, this would likely have to be opt-in: you don't need to annotate exceptions but you can, and you can define whether exceptions should be checked on a per-file basis. I suspect that this would work best for exceptions that are mostly unpredictable (such as network related errors), especially if they happen pretty rarely so it's easy to forget about them. For things like |
I would prefer annotated exceptions. Consider this silly example:
If by design of the application every house should have a toilet, in a correct application the last line shouldn't happen. We might want it still, however, to avoid weird behavior, for testing, and satisfying mypy. The caller wouldn't want to check for
or let it propagate
In other words, I'd like mypy to check for exceptions that are a part of the control flow of a correctly written application. |
From purely theoretical point of view (because it is completely unclear when and how this will be implemented), I think it makes sense to use |
If it was Java, I could perhaps throw a subclass of If you think of exceptions as not only errors, but also as possible return values, I think it only makes sense to have them a part of the function signature. |
Just to clarify, I meant that But again, as I said this is all just my fantasies. |
This would make more sense with a Failure type so you could adapt code with exceptions into a codebase that wants to entirely opt out of exceptions |
I don't think it would be good to couple checked exceptions to the AssertionError exception, because then you'd have to change your code to make sure an exception has to be caught. I would rather do something like this:
Additionally, you could declare an Exception class as checked:
A class that is declared as checked would need to be checked every time it is raised. This way you could make any kind of exception checked or not. This could be helpful e.g. when writing a library that does network or other io stuff, so that you don't have to change all exceptions to be subclasses of AssertionError only to have them checked. Also, having exception checking based on the exception's actual type would be useless when making a stub for a class. I believe that all mypy annotations must be implementable without actual code changes, otherwise it would break stubs. |
Exceptions shouldn't be declared as checked or not - all exceptions should be checked functions without a While code with a specific annotation would be limited to only calling checked functions that raise a subclass of that exception This way existing code will still typecheck new code without exceptions will only be required to wrap external functions with a function that returns a Failure/Success instance
|
I don't think all exceptions should be checked. There are a lot of exceptions that could be raised on almost any line (e.g. This effect can also occur with user code. Say, you implement something similar to a Thus it must be possible to declare an exception as checked or unchecked. Also I would hate if this syntax could not be implemented as a stub. Having to change existing code would seriously break using mypy with 3rd-party libraries that have not been typed by the author of that library. E.g. I use Django, which is not typed. The way I work with that is that I declare stubs for all methods that I call (in our setup we have mandatory typing enabled). That way I can safely update the library without having to merge anything. I only have to check that the stubs still fit with the interface declared by Django. |
By the way, what about a related feature that might overlap in usage but could be easier to implement: This feature would take, as an input, the code base and a reference to a function and would return all uncaught exceptions that would be raised along the way, together with all lines of code that raise that specific exception. So e.g. for this code:
and the reference to function
This could be used either to check for all possible exceptions that a function could raise while creating code that uses the function, so that the programmer knows what exceptions to expect. But it could also be used as a kind of static exception checker, if you input the reference to the main function / the main module. That way you can easily spot what exceptions could still be leaked. Optionally, the programmer could supply the checker a list of exceptions to ignore, e.g. MemoryError. This way there is no need to differentiate between checked or unchecked exceptions, since the programmer decides which exceptions they want to check for and which ones to ignore. |
I made something a while ago that kinda follows this idea: https://github.com/Julynx/exception-control The code probably sucks but I like the concept a lot. Being able to identify and follow exceptions across function calls without actually having to run the code and make it fail on purpose to see the exceptions it raises makes sense to me. I actually don't mind exceptions instead of optional return values, I just want to be able to reliably identify and catch all possible exceptions if I want to. Its basically impossible to do that in Python atm. |
Folks looking for raised exception checking might want to consider this simple alternative of returning "unexceptional exceptions": https://github.com/castedo/unexceptional | https://gitlab.com/castedo/unexceptional The main points of the helper functions and pattern is:
There are pros and cons to this alternative approach. But it's simple and one can benefit from it today. |
Over here python/typing#71 it was discussed to add exception information to stubs, that can be interpreted by tools like mypy. It would be great to have that as an optional function that gives warnings on uncaught exceptions, especially on user-declared exceptions.
Are there any plans on adding a feature like that to mypy?
The text was updated successfully, but these errors were encountered: