Skip to content

Define EXIT_SUCCESS and EXIT_FAILURE constants in sys #68241

Description

@abalkin
BPO 24053
Nosy @abalkin, @pitrou, @scoder, @rbtcollins, @skrah, @berkerpeksag, @vadmium, @serhiy-storchaka, @eamanu, @eedmunds, @Fat-Zer
PRs
  • bpo-24053: Add EXIT_SUCCESS and EXIT_FAILURE values in the sys module #14773
  • Files
  • issue24053.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/abalkin'
    closed_at = None
    created_at = <Date 2015-04-24.15:47:49.923>
    labels = ['easy', 'type-feature', '3.8']
    title = 'Define EXIT_SUCCESS and EXIT_FAILURE constants in sys'
    updated_at = <Date 2022-02-19.08:03:29.457>
    user = 'https://github.com/abalkin'

    bugs.python.org fields:

    activity = <Date 2022-02-19.08:03:29.457>
    actor = 'mark.dickinson'
    assignee = 'belopolsky'
    closed = False
    closed_date = None
    closer = None
    components = []
    creation = <Date 2015-04-24.15:47:49.923>
    creator = 'belopolsky'
    dependencies = []
    files = ['39197']
    hgrepos = []
    issue_num = 24053
    keywords = ['patch', 'easy']
    message_count = 37.0
    messages = ['241949', '241953', '241960', '241962', '241966', '241972', '241978', '242061', '242126', '242129', '242130', '242131', '242132', '242133', '242135', '242137', '242139', '242141', '242142', '242143', '242144', '242145', '242146', '242147', '242148', '242149', '242150', '242151', '242152', '242153', '242154', '247081', '255473', '331714', '332526', '413528', '413537']
    nosy_count = 11.0
    nosy_names = ['belopolsky', 'pitrou', 'scoder', 'rbcollins', 'skrah', 'berker.peksag', 'martin.panter', 'serhiy.storchaka', 'eamanu', 'edmundselliot@gmail.com', 'Fat-Zer']
    pr_nums = ['14773']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue24053'
    versions = ['Python 3.8']

    Activity

    1. abalkin commented on Apr 24, 2015

      @abalkin
      MemberAuthor

      Python defines some BSDish exit codes in the os module:

          EX_CANTCREAT = 73
          EX_CONFIG = 78
          EX_DATAERR = 65
          EX_IOERR = 74
          EX_NOHOST = 68
          EX_NOINPUT = 66
          EX_NOPERM = 77
          EX_NOUSER = 67
          EX_OK = 0
          EX_OSERR = 71
          EX_OSFILE = 72
          EX_PROTOCOL = 76
          EX_SOFTWARE = 70
          EX_TEMPFAIL = 75
          EX_UNAVAILABLE = 69
          EX_USAGE = 64

      but these are documented as only available on UNIX and may not be portable across all flavors.

      POSIX [1] and C99 defines EXIT_SUCCESS and EXIT_FAILURE constants. I propose adding those to sys.

      Having these constants in sys will make them more discoverable because they will be next to sys.exit().

      [1] http://pubs.opengroup.org/onlinepubs/009695399/functions/exit.html

    2. abalkin commented on Apr 24, 2015

      @abalkin
      MemberAuthor

      I am attaching a patch implementing these constants. If this is well-received, I will add documentation.

    3. self-assigned this
      on Apr 24, 2015
    4. ethanfurman commented on Apr 24, 2015

      @ethanfurman
      Member

      Where are EXIT_FAILURE and EXIT_SUCCESS defined?

      And we should probably call them EX_FAILURE and EX_SUCESS to match what's already there.

    5. abalkin commented on Apr 24, 2015

      @abalkin
      MemberAuthor

      Where are EXIT_FAILURE and EXIT_SUCCESS defined?

      In C stdlib:

      $ grep EXIT_ /usr/include/stdlib.h
      #define	EXIT_FAILURE	1
      #define	EXIT_SUCCESS	0

      we should probably call them EX_FAILURE and EX_SUCESS to match what's already there.

      No. EX_ macros come from a non-standard sysexits.h header. Python stdlib traditionally does not change the spelling of the constants that
      come from C libraries or standards.

      Even in the absence of POSIX and C99 standards, I would prefer EXIT_ prefix over EX_ for clarity. "EX" does not clearly mean "exit", it may stand for "exception", "execution", "example" etc.

    6. ethanfurman commented on Apr 24, 2015

      @ethanfurman
      Member

      Sounds good, I have no objections.

    7. serhiy-storchaka commented on Apr 24, 2015

      @serhiy-storchaka
      Member

      Aren't EXIT_SUCCESS and EXIT_FAILURE needed only for support VMS?

    8. abalkin commented on Apr 24, 2015

      @abalkin
      MemberAuthor

      I would say, they are there to support *humans*. I am not aware of any human language where "success" is spelled 0. (1 is a failing mark in some schools - so there is a precedent for that. :-)

    9. pitrou commented on Apr 26, 2015

      @pitrou
      Member

      Those should be in the os module, not in sys. The os module is for interfaces to the operating system, while the sys module is for Python-specific stuff.

      As for the point of adding them, I don't find them useful, but I won't oppose it either :-)

    10. abalkin commented on Apr 27, 2015

      @abalkin
      MemberAuthor

      Those should be in the os module, not in sys.

      I disagree. The whole point of this proposal is to have platform-independent status codes available next to the sys.exit() function.

      We already have over a dozen BSDish exit codes in os that are hardly ever used.

    11. pitrou commented on Apr 27, 2015

      @pitrou
      Member

      We already have over a dozen BSDish exit codes in os that are hardly
      ever used.

      Then precisely, those new codes should go in the os module as well.

    12. ethanfurman commented on Apr 27, 2015

      @ethanfurman
      Member

      I agree with Antoine -- all the exit codes should be in one place.

    13. abalkin commented on Apr 27, 2015

      @abalkin
      MemberAuthor

      Then precisely, those new codes should go in the os module as well.

      What is your logic? Having os.EX_ codes in os does not help as far as sys.exit() is concerned: no-one is using them and they are not available on all platforms. If we add EXIT_FAILURE and EXIT_SUCCESS to os now, we will only create confusion: should I use os.EX_OK or os.EXIT_SUCCESS?

      Note that sys.exit() is different from os._exit(). It may not even result in termination of the interpreter. Why should users of sys.exit() be required to import os if they want to indicate a failure?

    14. 20 remaining items

    15. rbtcollins commented on Nov 27, 2015

      @rbtcollins
      Member

      @serhiy, EXIT_FAILURE is used in Python's C code itself (just once admittedly, and then we use 0 sometimes for success and sometimes for errors, and then 1 for errors... aiee.)

      FWIW to the extent that folk want to write posix code in Python, I'm all for helping them, I find the amount of help this will be to be hard to assess. There is some code to adding the constants in documentation and learning surface area.

      Right now we don't document all the ways Python can interact with exit codes, and I suspect thats actually a bigger burden than writing the code to generate any given code.

    16. eedmunds commented on Dec 12, 2018

      eedmundsmannequin
      Mannequin

      I have personally come across situations where I am calling a Python script from a C program and would like to check the exit codes of the script, and have had to write sys.exit(1) and sys.exit(0) in Python, and compared them to EXIT_SUCCESS/EXIT_FAILURE in C. It would have been easy to introduce a bug where I returned the wrong exit code, so I was hoping they would have been implemented in sys.

      It seems like a no-brainer to add these, they reduce magic number use and improve the accessibility of Python to people coming from C. I would love to add these if everyone is OK with it.

    17. eamanu commented on Dec 26, 2018

      eamanumannequin
      Mannequin

      Hi Elliot!

      It seems like a no-brainer to add these, they reduce magic number use and improve the accessibility of Python to people coming from C. I would love to add these if everyone is OK with it.

      Sound great. But IMO I think that this can be solved doing:

          EXIT_FAILURE = 1
          EXIT_SUCCESS = 0
      
          sys.exit(EXIT_SUCCES)

      And what is the difference between EX_OK and EXIT_SUCCESS? both values are 0.

      BTW, I think this is a good improve and more for C coder.

      I recommend you mmake the PR.

    18. Fat-Zer commented on Feb 19, 2022

      Fat-Zermannequin
      Mannequin

      Any reasons the PR still not merged?

    19. scoder commented on Feb 19, 2022

      @scoder
      Contributor

      Any reasons the PR still not merged?

      There was dissent about whether these constants should be added or not. It doesn't help to merge a PR that is not expected to provide a benefit.

    20. transferred this issue fromon Apr 10, 2022
    21. arhadthedev commented on May 16, 2022

      @arhadthedev
      Member

      If I am alone in finding exit(EXIT_FAILURE) clearer than exit(1), I should certainly drop my proposal.

      @abalkin Currently, sys.exit(message) chooses the EXIT_SUCCESS/EXIT_FAILURE code depending on whether the message is None.

      Is sys.exit(EXIT_SUCCESS)/sys.exit(EXIT_FAILURE) still relevant then?

    22. calestyo commented on Jul 26, 2023

      @calestyo
      Contributor

      Is sys.exit(EXIT_SUCCESS)/sys.exit(EXIT_FAILURE) still relevant then?

      Maybe one doesn't want to give an actual message but just control the exit status?

      Also I have for example code, where depending on what happens I set some exit_status variable. But I don't e.g. just pass that to sys.exit() in the end, but have another if before, that would want to check something like exit_status != EXIT_SUCCESS and do extra things depending on that.

      So I think one really "needs" the symbol.

      Also, these are really standardised system symbols, so people might want to use them for checking exit statuses of subprocesses and not just as part of sys.exit().

      As for the discussion about sys vs. os... AFAIU POSIX, only EXIT_SUCCESS is defined to be a fixed value (0)... so I'd interpret that as EXIT_FAILURE being potentially platform-dependent.

      Oh and it was mentioned that EX_OK would be documented as UNIX-only, but current documentation seems to say "Availability: Unix, Windows.".

    23. pitrou commented on Jul 26, 2023

      @pitrou
      Member

      Hmm... let's be pragmatic here. sys.exit(0) is known to exit with success. sys.exit(non-zero integer) is known to be a failure exit. Which exit code you choose is on you: many CLI utilities can actually return different error codes depending on the actual error.

      Since all concrete use cases are well-served already, I will close this isuue.

    24. karcherm commented on Oct 5, 2026

      @karcherm
      Contributor

      I read through the whole issue, and I am not convinced that not defining these codes make sense.

      sys.exit(0) is known to exit with success.

      This is obviously true. Nevertheless, I'm currently reviewing code that contains a function which is meant to be invoked as entrypoint using [project.scripts] in pyproject.toml. When reading that function, it contains return 0 and return 1 statements. As that code is actually correct, it returns 0 for success and 1 for failure. But, as you might already have noticed, the code does not contain sys.exit(0), which is well-known to be "OK", or sys.exit(1) which is well-known to mean "some generic failure happened, but the author of this tool didn't bother to define specific exit codes".
      In my not so humble oppinion, return EXIT_SUCCESS and return EXIT_FAILURE convey a lot more meaning than returning the magic numbers 0 and 1.

      If we are looking at integral function return values to indicate operation status there are many conventions:

      • System calls like read, in which negative is bad and positive is good (positive values usually indicating some kind of count)
      • Process exit codes in which non-zero is bad and 0 is good
      • Standard system calls, in which -1 is bad and 0 is good, which actually happens to be consistent with the contract of read and the contract of exit codes
      • Ad-Hoc booleans in which 0 is False (which is bad) and 1 is True (which is good)

      Just reading return EXIT_SUCCESS or return EXIT_FAILURE conveys two important messages:

      1. The return code is meant to be a process exit code
      2. EXIT_SUCCESS means "good" in this situation.

      While of course you might argue that you might want more than 1 "bad" exit code, the convention of using "1" as generic error code if no special convention exists has been around since more than 40 years, and will be around as long as C exists. As these constants are not just POSIX, but even C99, they should be available on nearly any platform around today, which sets them apart from EX_..., and is a good reason to put them into sys instead of os, because the availability of these constants is not meant to be OS specific.

      Suggesting to reopen this issue, because I would have filed a new one if this issue didn't exist.

    25. added
      3.16new features, bugs and security fixes
      and removed on Oct 6, 2026
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    Labels

    3.16new features, bugs and security fixeseasytype-featureA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions