Python "bug"

Stephen Warren swarren at wwwdotorg.org
Fri Feb 9 20:05:53 UTC 2024


This is nothing to do with Python at all; it's the way the POSIX exit() 
and system() functions are specified, which Python's os module is a 
lightweight wrapper around. Python doesn't define these APIs; it simply 
exposes them.

In particular, the value returned by system() (POSIX; called from C or 
Python) is not the exit status, but an encoded value. In C, you must 
(after checking some other conditions...) use WEXITSTATUS() to extract 
the exit status of the invoked process. I don't recall immediately how 
to invoke that macro from Python. WEXITSTATUS happens to be implemented 
as follows on my system, but portable code should not rely on this:

/usr/include/x86_64-linux-gnu/bits/waitstatus.h
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)

/usr/include/stdlib.h

#define WEXITSTATUS(status) __WEXITSTATUS (status)

On 2/9/24 11:43, Brian Sturgill wrote:
> Python  has some quirks.
> 
> Anyway, here's the bug I've just wasted an hour on...
> 
> I have a shell script, which error checked the return of a Python script.
> 
> The python script autogens an example written in python
> that automatically creates an output 3d object to be used by my
> documentation web page.
> 
> In other words, the shell invokes python, which generates a python program,
> which it then runs.  Error status were being pass as appropriate.
> However, I had a syntax error.
> The shell script claims it got 0.
> Python claimed it was sending 256.
> 
> It turns out that the sys.exit function recommends sticking to 0-127.
> 
> The irony is that Python itself was generating the 256 exit status, 
> which it cannot handle.
> 
> Try these:
> (piecad) brian at george:~/work/piecad$ python -c "import sys; sys.exit(256)"
> (piecad) brian at george:~/work/piecad$ echo $?
> 0
> (piecad) brian at george:~/work/piecad$ python -c "import sys; sys.exit(255)"
> (piecad) brian at george:~/work/piecad$ echo $?
> 255
> 
> Bash seems to be limited to 0-255, which is what man 3 exit says should 
> be the range.
> 
> But the plot thickens... the real culprit was the os.system function.
> Which does return the exit status, but as the second byte of the 
> returned 16-bit
> integer.
> So essentially, python returned a 1 status for the syntax error,
> which o.system intentionally made into 256. Which the shell then 
> translated to 0.
> 
> Whose fault is it?  Well, me of course. I should have read the 4 pages 
> of documentation
> it took to figure out what was going on! :-)
> 
> --
> 
> Brian
> 



More information about the NCLUG mailing list