msg241946 - (view) |
Author: Alexander Belopolsky (belopolsky) * |
Date: 2015-04-24 15:29 |
$ python3
Python 3.4.3 (default, Mar 2 2015, 11:08:35)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> import subprocess
>>> subprocess.call([sys.executable, '-c', "import sys;sys.exit(512)"])
0
>>> subprocess.call([sys.executable, '-c', "import sys;sys.exit(256)"])
0
See also #14376.
|
msg241952 - (view) |
Author: Stefan Krah (skrah) * |
Date: 2015-04-24 16:07 |
At first glance the return values look right to me:
The value of exit returned to the parent should be status & 0377.
|
msg241954 - (view) |
Author: Alexander Belopolsky (belopolsky) * |
Date: 2015-04-24 16:43 |
> The value of exit returned to the parent should be status & 0377.
Apparently, this is not so on Windows. See msg241903 in #24045.
POSIX defines [1] exit to return status & 0377, but that does not mean that sys.exit(256) must return 0 without a warning. It is very unlikely that someone would intentionally use code=256 to signify success. It is much more likely that sys.exit(256) is a result of a programming error.
I believe a better behavior for sys.exit() would be to truncate the code values to 8-bit range so that non-zero status would always be returned as non-zero, but possibly different value.
[1] http://pubs.opengroup.org/onlinepubs/009695399/functions/exit.html
|
msg241957 - (view) |
Author: Ethan Furman (ethan.furman) * |
Date: 2015-04-24 16:57 |
If anything changes here it needs to be O/S dependent. MS Windows can work with DWORD return values, so truncating to 8-bits is wrong for that platform.
|
msg241958 - (view) |
Author: Eryk Sun (eryksun) * |
Date: 2015-04-24 17:09 |
> I believe a better behavior for sys.exit() would be to truncate
> the code values to 8-bit range so that non-zero status would
> always be returned as non-zero, but possibly different value.
OK, so long as it's just for POSIX systems. Windows ExitProcess, ExitThread, TerminateProcess, and TerminateThread all use an unsigned int value for the exit code, and it's common to use a [Win32 error code][1] in the 16-bit range 0x0000 to 0xFFFF.
[1]: https://msdn.microsoft.com/en-us/library/cc231199
|
msg241961 - (view) |
Author: Alexander Belopolsky (belopolsky) * |
Date: 2015-04-24 17:24 |
I agree that the truncation limits should be OS dependent and preserve the values to the extent possible on a given platform. I just want to avoid a situation when sys.exit(code) returns zero for a non-zero code.
BTW, what does sys.exit(2**63) return on Windows?
|
msg241964 - (view) |
Author: Ethan Furman (ethan.furman) * |
Date: 2015-04-24 17:45 |
Windows 7
C:\Python27>python
Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
--> import sys
--> sys.exit(2**63)
9223372036854775808
C:\Python27>python
Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
--> import sys
--> sys.exit(2**63+1)
9223372036854775809
|
msg241965 - (view) |
Author: Alexander Belopolsky (belopolsky) * |
Date: 2015-04-24 17:53 |
--> sys.exit(2**63)
9223372036854775808
Interesting. So it is probably not unheard of in the Windows world to use errors codes like 1000,1001,..1024,.. to avoid conflicts with "system" codes.
Maybe on POSIX systems, sys.code(code) should print code and return say 255 for code outside of -255..255 range?
|
msg241967 - (view) |
Author: Eryk Sun (eryksun) * |
Date: 2015-04-24 18:18 |
> --> import sys
> --> sys.exit(2**63)
> 9223372036854775808
The above is only Python 2.x behavior. On Windows, sys.maxint is 2147483647 (even for 64-bit Windows), so 2**63 is a Python long. Thus handle_system_exit takes the PyFile_WriteObject branch, with the actual exit code set to 1.
>>> import sys
>>> sys.exit(2**63)
9223372036854775808
C:\>echo %errorlevel%
1
In Python 3, PyLong_AsLong overflows for any value bigger than LONG_MAX, which sets the result to -1, i.e. 32-bit 0xFFFFFFFF, with overflow set. handle_system_exit ignores the overflow exception, so any exit code larger than 0x7FFFFFFF (2**31-1) is returned as 0xFFFFFFFF (2**32-1).
>>> cmd = '%s -c "import sys;sys.exit(%%d)"' % sys.executable
>>> subprocess.call(cmd % (2**31-1))
2147483647
>>> subprocess.call(cmd % (2**31))
4294967295
>>> subprocess.call(cmd % (2**63))
4294967295
|
msg242272 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2015-04-30 14:59 |
Printing the actual value feels more consistent with the documented API, so I'm in favor of that (ie: don't let errors pass silently). I'm sure someone somewhere is depending on this :(, but I see you have versions marked for 3.5 only, which makes sense to me.
|
msg242359 - (view) |
Author: Steven D'Aprano (steven.daprano) * |
Date: 2015-05-02 00:13 |
Maybe I've misunderstood RDM's comment, but if sys.exit(code) starts automatically printing the return code, that's going to break a lot of scripts.
|
msg242367 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2015-05-02 01:57 |
I meant when it is otherwise out of range. That is, treat it like any other object that can't be returned as the return code: print it. But only if it can't otherwise be used as the exit code.
|
msg242375 - (view) |
Author: Serhiy Storchaka (serhiy.storchaka) * |
Date: 2015-05-02 04:42 |
Python 2 prints large return code only by accident, because it have unsupported type (sys.exit supports only int, not long). This is considered as a bug (issue14376) because small return codes of type long (0L or 1L) are printed too.
I don't think this issue need other fix besides a note that the program can return "success" for some non-zero values.
|
msg273848 - (view) |
Author: Martin Panter (martin.panter) * |
Date: 2016-08-29 01:54 |
Here is a relevant Posix bug thread:
http://austingroupbugs.net/view.php?id=947
As well as Windows, apparently Solaris, OS X, and a recent version of Free BSD have more than eight bits of exit status. I don’t know if Python’s sys.exit() supports this though.
|
|
Date |
User |
Action |
Args |
2022-04-11 14:58:16 | admin | set | github: 68240 |
2021-03-12 17:42:44 | eryksun | set | versions:
+ Python 3.8, Python 3.9, Python 3.10, - Python 3.5 |
2016-08-29 01:54:15 | martin.panter | set | nosy:
+ martin.panter messages:
+ msg273848
|
2015-07-21 07:15:43 | ethan.furman | set | nosy:
- ethan.furman
|
2015-05-03 05:55:53 | Arfrever | set | nosy:
+ Arfrever
|
2015-05-02 04:42:21 | serhiy.storchaka | set | nosy:
+ serhiy.storchaka messages:
+ msg242375
|
2015-05-02 01:57:25 | r.david.murray | set | messages:
+ msg242367 |
2015-05-02 00:13:52 | steven.daprano | set | nosy:
+ steven.daprano messages:
+ msg242359
|
2015-04-30 14:59:12 | r.david.murray | set | nosy:
+ r.david.murray messages:
+ msg242272
|
2015-04-24 18:18:52 | eryksun | set | messages:
+ msg241967 |
2015-04-24 17:53:43 | belopolsky | set | messages:
+ msg241965 |
2015-04-24 17:45:42 | ethan.furman | set | messages:
+ msg241964 |
2015-04-24 17:24:39 | belopolsky | set | messages:
+ msg241961 |
2015-04-24 17:09:33 | eryksun | set | nosy:
+ eryksun messages:
+ msg241958
|
2015-04-24 16:57:16 | ethan.furman | set | nosy:
+ ethan.furman messages:
+ msg241957
|
2015-04-24 16:51:45 | belopolsky | set | title: sys.exit(code) returns "success" to the OS for some values of code -> sys.exit(code) returns "success" to the OS for some nonzero values of code |
2015-04-24 16:43:21 | belopolsky | set | messages:
+ msg241954 |
2015-04-24 16:07:25 | skrah | set | nosy:
+ skrah messages:
+ msg241952
|
2015-04-24 15:29:13 | belopolsky | create | |