-
Notifications
You must be signed in to change notification settings - Fork 250
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
Annotating functions which don't raise exceptions #604
Comments
This is related to #71 . In a sense, it's complement of it: there, people want to annotate which exceptions are thrown. Supposedly, when these annotations are full and complete, functions which aren't annotated to raise any exception, are those which don't raise them. In reality of course, that level of coverage is not realistically achievable, so instead of explicitly marking all exceptions raised, thin RFC proposes to allow to explicitly mark those functions which don't raise exceptions. |
I had this idea in mind for some time, and the discussion in https://mail.python.org/pipermail/python-dev/2019-January/155998.html only gives an example that "nothrow" property is important to the Python language, whether those in powers of it admit, or not. To recap, the talk in that thread (and with reference to the official docs at https://docs.python.org/3/reference/compound_stmts.html#try) is that
is compiled as
The reason why there're 2 statements "N = None; del N", is exactly for that (compiler-generated) code to have no-throw property - even if "body" (containing arbitrary user code) has But the reason the exception handler body needs to be wrapped into extra try-finally in the first place, is from the reservations that it may throw exceptions! If we'd know that it doesn't, we could avoid that overhead. And note that it doesn't even apply to "native code generation", but to bytecode generation, as done e.g. by CPython. Of course, I don't call for CPython itself to do such an optimization. But there're many Python language implementations which try to advance performance state of the start for the language, and setting a common ground for them to annotate nothrow/NoRaise functions is worthy a task IMHO. With that idea I submit this ticket. |
What exactly do you want? Do you just want to have a syntax to attach some extra info to (return) types that would be ignored by type checkers but may be used by some other tools? If yes, then this is essentially a duplicate of #600. With that you can write: def func() -> Annotated[int, NoRaise]:
... |
Thanks for reference to #600. I guess I could crash there with alternative syntax ideas ;-). Beyond syntax for multiple annotations, it's also about choosing a specific annotation symbol for "no-throw" case. (I understand it unlikely to be added to "typing" module any type soon, so question is "if it would be added, what would it be", and python/typing is a kind of crossroads among different annotations projects, that's why I posted it here). |
The choice of name is up to the team/tool that is going to support it, other type checkers will just ignore it. We can keep this open for a while to see who else is interested in this feature. |
+1 |
Perhaps an approach to consider interesting approach is similar to what Swift does
|
I would find it interesting to be able to annotate functions which never throw exceptions. "Never" can be either in the absolute sense, or in the sense of "checked exceptions", with some subset of exception designated as "unchecked" (details of this designation are perhaps up to the actual tool to process annotations).
Example of a function which absolutely never raises exceptions (well, at least per language semantics, particular implementations might still have means to break with some implementation-related exceptions):
Example of a function which may throw (unchecked) exception if API contract is violated:
So, hopefully these examples show that the notion does exist in Python.
Now the question how to annotate it. Following the existing
NoReturn
, it would be calledNoRaise
orNoThrow
. "nothrow" terminology if familiar from C++ (and it seems to be replaced even there), so perhaps sticking with native Python terminology makes sense (but "throw" is native to Python too, re: exception handling with generators).More interesting question is where to put that annotation. Taking the example above, a natural annotation would be:
And I was quite surprised that the usual "implicit tuple" syntax rule doesn't apply here, and the above is SyntaxError as of CPy3.7:
I wonder if that warrants a separate issue report. And whether it was a cunning design choice mere mortals need to decipher, because that seems too obvious thing to overlook with an implicit tuple syntax, again (neither problematic from forma grammar perspective, even in LL it's
"->" expr ("," expr)* ":"
, which is trivial, Python has more complex grammar rules in many places.So, all in all, now it would need to be written as:
Which is of course not as pretty as without parens.
The text was updated successfully, but these errors were encountered: