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