Return Type: If conditional call to sys.exit() in function

Viewed 513

Assuming I have the following function in a console script (1):

def example(x: int) -> typing.Union[typing.NoReturn, int]:
    if x > 10: # something is wrong, if this condition is true
        # logging
        # cleanup
       sys.exit()
    return x * 10

Is the return type correctly specified? As NoReturn means that the function never returns (cf.: https://docs.python.org/3/library/typing.html), this seems wrong. But mypy doesn't complain about the combination of Union and NoReturn.

This seems wrong (2), as SystemExit isn't returned, but raised by sys.exit (and leads to errors with mypy):

def example(x: int) -> Union[SystemExit, int]:
    ...

What about (3):

def example(x: int) -> Union[SystemExit, int]:
    if x > 10: # something is wrong, if this condition is true
        # logging
        # cleanup
       return sys.exit()
    return x * 10

This seems plausible, too (4). However, the signature hides the special behaviour then:

def example(x: int) -> int:
    if x > 10: # something is wrong, if this condition is true
        # logging
        # cleanup
       sys.exit()
    return x * 10
2 Answers

NoReturn is used to state that function never returns.

If we annotate as NoReturn all functions that may not return control, this would apply to all functions that may throw an exception.

what if instead of calling sys.exit() inside the example function you call it outside

def example(x: int) -> int:
    if x > 10: # something is wrong, if this condition is true
        # logging
        # cleanup
        return [] # or x = []
    return x * 10

then in your code

 if x==[]:
    sys.exit()
Related