uuid.getnode() discrepancy
mssalvatore opened this issue · 7 comments
Description
It seems that the output of uuid.getnode()
for python3.11.2-cp311-cp311-manylinux2014_x86_64.AppImage
differs from Python3.11.2 in the deadsnakes ubuntu PPA.
To reproduce
- Create an Ubuntu 22.04 LXD container. (I've also reproduced this successfully on bare metal.)
- Follow the directions from the deadsnakes PPA to install Python3.11.2
- Download
https://github.com/niess/python-appimage/releases/download/python3.11/python3.11.2-cp311-cp311-manylinux2014_x86_64.AppImage
- Launch an interpreter from the installed Python3.11.2 and run
import uuid; uuid.getnode()
- Launch an interpreter from the Appimage and run
import uuid; uuid.getnode()
- Compare the output
Hello @mssalvatore,
thank you for reporting this. I have no idea how uuid works, but I would expect identical results, whatever the python version. My understanding is that the node uuid is specific to the system, irrespective of Python version. Isn't it?
Currently, I do get identical results on my system (Debian 11).
$ python -c "import uuid; print(uuid.getnode())"
268749057538554
$ python3 -c "import uuid; print(uuid.getnode())"
268749057538554
$ ./python3.9.16-cp39-cp39-manylinux2014_x86_64.AppImage -c "import uuid; print(uuid.getnode())"
268749057538554
$ ./python3.11.2-cp311-cp311-manylinux2014_x86_64.AppImage -c "import uuid; print(uuid.getnode())"
268749057538554
The first two calls are for system Python, and the two last are for currently released AppImages. I also tried interactively and got the same result.
Do you still have this issue?
@niess Yeah, I still see it, but only on Ubuntu Jammy
Debian 11
debian@debian-11:/tmp$ python3 --version
Python 3.9.2
debian@debian-11:/tmp$ python3 -c "import uuid; print(uuid.getnode())"
95541313180
debian@debian-11:/tmp$ ./python3.9.16-cp39-cp39-manylinux2014_x86_64.AppImage -c "import uuid; print(uuid.getnode())"
95541313180
debian@debian-11:/tmp$ ./python3.10.6-cp310-cp310-manylinux2010_x86_64.AppImage -c "import uuid; print(uuid.getnode())"
95541313180
debian@debian-11:/tmp$ ./python3.11.2-cp311-cp311-manylinux2014_x86_64.AppImage -c "import uuid; print(uuid.getnode())"
95541313180
Ubuntu Jammy 22.04
ubuntu@jammy:~$ python3 --version
Python 3.10.6
ubuntu@jammy:~$ python3 -c "import uuid; print(uuid.getnode())"
208766106016652
ubuntu@jammy:~$ ./python3.9.16-cp39-cp39-manylinux2014_x86_64.AppImage -c "import uuid; print(uuid.getnode())"
95536465137
ubuntu@jammy:~$ ./python3.10.10-cp310-cp310-manylinux2014_x86_64.AppImage -c "import uuid; print(uuid.getnode())"
95536465137
ubuntu@jammy:~$ ./python3.11.2-cp311-cp311-manylinux2014_x86_64.AppImage -c "import uuid; print(uuid.getnode())"
95536465137
ubuntu@jammy:~$ python3.11 -c "import uuid; print(uuid.getnode())" # from deadsnakes PPA
208766106016652
Both the python3 from the official Ubuntu repository and the one from the deadsnakes repository agree. They look like they're using a different scheme.
Update: The manylinux 2_28 AppImage agrees with the official Ubuntu python:
ubuntu@jammy:~$ ./python3.10.10-cp310-cp310-manylinux_2_28_x86_64.AppImage -c "import uuid; print(uuid.getnode())"
208766106016652
ubuntu@jammy:~$ python3 -c "import uuid; print(uuid.getnode())"
208766106016652
They must be built against a newer version of some library that changes this behavior.
I was checking the actual implementation. This seems to be currently worked on (according to last commit, "Fix uuid.getnode").
Also, there seem to be various strategies implemented for getnode, the like _ifconfig_getnode
, _ip_config_getnode
, etc. Maybe the AppImage version uses a different strategy, due to something failing with the default one? Or conversely, for the Ubuntu PPA one?
A test could be to directly call the private versions of getnode and see which one corresponds to what you get in both cases.
Good idea:
ubuntu@jammy:~$ ./python3.11.2-cp311-cp311-manylinux2014_x86_64.AppImage -c "import uuid; print(uuid._GETTERS)"
[<function _unix_getnode at 0x7f1ef6d80d60>, <function _ip_getnode at 0x7f1ef6d809a0>, <function _ifconfig_getnode at 0x7f1ef6d80900>]
ubuntu@jammy:~$ python3.11 !*
python3.11 -c "import uuid; print(uuid._GETTERS)"
[<function _unix_getnode at 0x7f4b5d9d0680>, <function _ip_getnode at 0x7f4b5d9d0220>, <function _ifconfig_getnode at 0x7f4b5d9d0180>]
ubuntu@jammy:~$ ./python3.11.2-cp311-cp311-manylinux2014_x86_64.AppImage -c "import uuid; print(uuid._unix_getnode())"
None
ubuntu@jammy:~$ python3.11 -c "import uuid; print(uuid._unix_getnode())"
208766106016652
ubuntu@jammy:~$ ./python3.11.2-cp311-cp311-manylinux2014_x86_64.AppImage -c "import uuid; print(uuid._ip_getnode())"
95536465137
It seems that _unix_getnode()
returns None
for the AppImage, but not the official version. From the code, it would seem that this is because _generate_time_safe
is not defined (see https://github.com/python/cpython/blob/d189e2db0bca60eba328cc31b86e62a1e2b3647a/Lib/uuid.py#L579-L588). This is controlled here.
So I guess HAVE_UUID_GENERATE_TIME_SAFE
is a compile-time parameter that can affect this behavior.
OK, I see. Thank you for sorting this out.
The problem is that I do not compile the Python runtime. I relocate the binaries from the Manylinux Docker images. Thus, there is little that I could do here, I am afraid.
I don't know if this is an option for you, but provided that uuid.getnode actually depends on compiler flags, your could use one of the private methods instead? In order to have a cross-compilation flags uuid.
The problem is that I do not compile the Python runtime. I relocate the binaries from the Manylinux Docker images. Thus, there is little that I could do here, I am afraid.
Make sense. Thanks for looking into this with me.
You could use one of the private methods instead?
This might be our only option. Thanks!