I have been using Python typing's 'NoReturn' wrong
I am a huge fan of python’s new typing module which was introduced in version 3.5 see the version overview here. The addition of this module gives us a range of tools to help people read and understand your code in the future.
Since I have started using typing I have been adding argument types, and return
types to almost all of my public functions. One that keeps popping up is
NoReturn
, and as it turns out I have been using it wrong.
My Mistake
I had completely forgotten about Python’s implicit returns. Almost no function in
python actually returns nothing… In my mind for what ever reason I thought
that if I don’t explicitly return something then the NoReturn
typing makes
sense, however this is not the case.
Below is an example of a function that I thought should be typed as NoReturn
but was very wrong:
def foobar():
print("BAZBAR")
The above function does not explicitly return anything, but python will add
an implicit return of None
when it ends. You can see this by assigning the
return value of that function to a variable eg: rtn = foobar()
then see the
type by running type(rtn)
, you should get <class 'NoneType'>
back! This is
an example of python adding return None
at the end of your function.
So what is NoReturn
for?
The goal of the NoReturn
type is to signify that calling this function will
end all further processing, it is the point of NO RETURN! This type should be
used in functions that will raise an exception, or a function that ends the
program, below are a few examples.
Examples of NoReturn
used correctly
def raise_error() -> NoReturn:
"""
Always raise an error.
"""
raise RuntimeError("An Error occurred")
def quit_program() -> NoReturn:
"""
Quit the process running this code.
"""
import sys
sys.exit()
I now need to go over 100s of lines of code, and fix this mistake! To fix this
mistake, I will need to go though all the instances where I have put NoReturn
and if in reality the function ends processing, then I will leave it as it is.
In most cases though I will need to replace -> NoReturn
with -> None
.
So what did I learn?
I could have avoided this if I just RTFM a little better! The python docs are a
great resource, and I should have read the NoReturn
section more carefully.
You can find the docs on NoReturn
here.
Tags: Python, Typing, Mistakes