Skip to content

sys.exit and SystemExit #8513

Closed
Closed
@Akuli

Description

@Akuli

sys.exit() is defined as:

typeshed/stdlib/sys.pyi

Lines 224 to 225 in c68bcc7

# sys.exit() accepts an optional argument of anything printable
def exit(__status: object = ...) -> NoReturn: ...

The argument ends up in the .code attribute of a SystemExit exception.

>>> import sys
>>> try: sys.exit()
... except SystemExit as e: print(repr(e.code))
... 
None
>>> try: sys.exit("lol")
... except SystemExit as e: print(repr(e.code))
... 
'lol'
>>> try: sys.exit({"foo": "bar"})
... except SystemExit as e: print(repr(e.code))
... 
{'foo': 'bar'}

But that's typed as:

typeshed/stdlib/builtins.pyi

Lines 1793 to 1794 in c68bcc7

class SystemExit(BaseException):
code: int

These should be the same IMO, but what should they be? The interpreter handles uncaught SystemExit exceptions like this:

  • If the code is None, exit the process with status zero.
  • If the code is an integer, exit the process with that status.
  • Otherwise, print the code (to stderr) and exit the process with status 1.

I'd suggest using str | int | None, where we use str because we don't have any way to express "anything reasonably printable" without saying "any object". This way you can use each of the interpreter's behaviors as intended, and if you accidentally pass in e.g. 0.0, the type checker will warn you instead of making you wonder why your process printed 0.0 and failed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions