Python "bug"
Brian Sturgill
c.brian.sturgill at gmail.com
Sat Feb 10 19:37:09 UTC 2024
No, sorry... but myself, Stephen, and you are wrong.
The current python docs get this right, the WEXITSTATUS and friends only
apply to POSIX.
It turns out that ANSI C doesn't define the return value of the system
function, beyond int.
Worse, you can't just use WEXITSTATUS as that isn't checking for signal
terminations, nor
is it checking for cases where the process has not really exited yet.
And of course none of this makes sense on Windows.
They do have a solution... os.waitstatus_to_exitcode(*status*).
Though this still isn't adequate to pass through to sys.exit.
In the end I opted for sys.exit(0 if ret == 0 else 1).
Technically this is not ANSI C conformant as Python doesn't give me access
to EXIT_SUCCESS and EXIT_FAILURE,
which are the official blessed ways to use the ANSI C exit call.
Brian
On Fri, Feb 9, 2024 at 2:54 PM Sean Reifschneider <jafo00 at gmail.com> wrote:
> Exactly what Stephen said. The python equivalent of WEXITSTATUS is
> os.WEXITSTATUS(exit_code)
>
> On Fri, Feb 9, 2024 at 1:06 PM Stephen Warren <swarren at wwwdotorg.org>
> wrote:
>
>> 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
>> >
>>
>>
--
Brian
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.nclug.org/pipermail/nclug/attachments/20240210/5cea9947/attachment.htm>
More information about the NCLUG
mailing list