Alfe
Alfe

Reputation: 59526

How to declare procedure/function hybrid in MyPy

I've got a function which might return a value (then it must be an int) or behaves like a procedure (i. e. it doesn't call return at all, effectively returning None then). You might have guessed, it is the main() function in this well-known pattern:

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

The function sys.exit() is prepared for this, it accepts int and None equally.

Some main() functions just do things and terminate without an explicit return, others return an explicit int. I'd like to declare this in a constant typing so that changing my main() from "not returning anything" to "return an exit code" doesn't mean I have to adjust the typing declaration.

My trials:

def main(argv: List[str]) -> Optional[int]:
    print_something()

(Then MyPy complains about missing return statement.)

def main(argv: List[str]) -> Union[int, None]:
    print_something()

(The same as above.)

def main(argv: List[str]) -> Optional[int]:
    print_something()
    return

("error: Return value expected" :rage:)

def main(argv: List[str]) -> Optional[int]:
    print_something()
    return None

(Aww, come on. But works, yeah. I'm not happy with the useless return None in the end. I think Optional already makes it clear that nothing might be returned.)

def main(argv: List[str]) -> Any:
    print_something()

(Works of course, but using Any is too general. Returning e. g. a string accidentally would not be found by the static type checker.)

Is there any way I didn't think of yet to achieve what I want?

Upvotes: 0

Views: 199

Answers (1)

Mr. Kelsey
Mr. Kelsey

Reputation: 530

(Aww, come on. But works, yeah. I'm not happy with the useless return None in the end. I think Optional already makes it clear that nothing might be returned.)

I would argue that Optional makes it clear that it might return the optional value. IE. int. I believe that you still have to put the expected return value. In this case it would be None.

There is a good discussion about None as a return value here

See also mypy docs regarding strict optional types and none checking

Upvotes: 0

Related Questions