From 827a3a4c875843483d36c45fe1173aeaaf0ce736 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Fri, 30 May 2025 07:43:01 -0500 Subject: [PATCH 1/3] Add patch for stable `uuid.getnode` --- cpython-unix/build-cpython.sh | 7 + .../patch-uuid-getnode-stable-3.13.patch | 708 ++++++++++++++++++ 2 files changed, 715 insertions(+) create mode 100644 cpython-unix/patch-uuid-getnode-stable-3.13.patch diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh index b44bb9713..7773a76a5 100755 --- a/cpython-unix/build-cpython.sh +++ b/cpython-unix/build-cpython.sh @@ -76,6 +76,13 @@ if [ -n "${CROSS_COMPILING}" ]; then fi fi +# `uuid.getnode()` is not stable on our libuuid, CPython should fallback to another method +# Cherry-pick https://github.com/python/cpython/pull/134704 until it is released +# We could backport this to more versions too, it won't be done by the upstream +if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" && -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_14}" ]]; then + patch -p1 -i ${ROOT}/patch-uuid-getnode-stable-3.13.patch +fi + # This patch is slightly different on Python 3.10+. if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_10}" ]; then patch -p1 -i ${ROOT}/patch-xopen-source-ios.patch diff --git a/cpython-unix/patch-uuid-getnode-stable-3.13.patch b/cpython-unix/patch-uuid-getnode-stable-3.13.patch new file mode 100644 index 000000000..175398d30 --- /dev/null +++ b/cpython-unix/patch-uuid-getnode-stable-3.13.patch @@ -0,0 +1,708 @@ +diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py +index e7e44c6413c2e2..ce396aa942b6ed 100755 +--- a/Lib/test/test_uuid.py ++++ b/Lib/test/test_uuid.py +@@ -1,6 +1,7 @@ + import unittest + from test import support + from test.support import import_helper ++from test.support.script_helper import assert_python_ok + import builtins + import contextlib + import copy +@@ -773,10 +774,37 @@ def test_cli_uuid5_ouputted_with_valid_namespace_and_name(self): + class TestUUIDWithoutExtModule(BaseTestUUID, unittest.TestCase): + uuid = py_uuid + ++ + @unittest.skipUnless(c_uuid, 'requires the C _uuid module') + class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase): + uuid = c_uuid + ++ def check_has_stable_libuuid_extractable_node(self): ++ if not self.uuid._has_stable_extractable_node: ++ self.skipTest("libuuid cannot deduce MAC address") ++ ++ @unittest.skipUnless(os.name == 'posix', 'POSIX only') ++ def test_unix_getnode_from_libuuid(self): ++ self.check_has_stable_libuuid_extractable_node() ++ script = 'import uuid; print(uuid._unix_getnode())' ++ _, n_a, _ = assert_python_ok('-c', script) ++ _, n_b, _ = assert_python_ok('-c', script) ++ n_a, n_b = n_a.decode().strip(), n_b.decode().strip() ++ self.assertTrue(n_a.isdigit()) ++ self.assertTrue(n_b.isdigit()) ++ self.assertEqual(n_a, n_b) ++ ++ @unittest.skipUnless(os.name == 'nt', 'Windows only') ++ def test_windows_getnode_from_libuuid(self): ++ self.check_has_stable_libuuid_extractable_node() ++ script = 'import uuid; print(uuid._windll_getnode())' ++ _, n_a, _ = assert_python_ok('-c', script) ++ _, n_b, _ = assert_python_ok('-c', script) ++ n_a, n_b = n_a.decode().strip(), n_b.decode().strip() ++ self.assertTrue(n_a.isdigit()) ++ self.assertTrue(n_b.isdigit()) ++ self.assertEqual(n_a, n_b) ++ + + class BaseTestInternals: + _uuid = py_uuid +diff --git a/Lib/uuid.py b/Lib/uuid.py +index c286eac38e1ef4..6ab1658cc5249a 100644 +--- a/Lib/uuid.py ++++ b/Lib/uuid.py +@@ -572,22 +572,24 @@ def _netstat_getnode(): + try: + import _uuid + _generate_time_safe = getattr(_uuid, "generate_time_safe", None) ++ _has_stable_extractable_node = _uuid.has_stable_extractable_node + _UuidCreate = getattr(_uuid, "UuidCreate", None) + except ImportError: + _uuid = None + _generate_time_safe = None ++ _has_stable_extractable_node = False + _UuidCreate = None + + + def _unix_getnode(): + """Get the hardware address on Unix using the _uuid extension module.""" +- if _generate_time_safe: ++ if _generate_time_safe and _has_stable_extractable_node: + uuid_time, _ = _generate_time_safe() + return UUID(bytes=uuid_time).node + + def _windll_getnode(): + """Get the hardware address on Windows using the _uuid extension module.""" +- if _UuidCreate: ++ if _UuidCreate and _has_stable_extractable_node: + uuid_bytes = _UuidCreate() + return UUID(bytes_le=uuid_bytes).node + +diff --git a/Modules/_uuidmodule.c b/Modules/_uuidmodule.c +index c5e78b1510b5e3..c31a7e8fea5608 100644 +--- a/Modules/_uuidmodule.c ++++ b/Modules/_uuidmodule.c +@@ -78,23 +78,47 @@ py_UuidCreate(PyObject *Py_UNUSED(context), + return NULL; + } + ++static int ++py_windows_has_stable_node(void) ++{ ++ UUID uuid; ++ RPC_STATUS res; ++ Py_BEGIN_ALLOW_THREADS ++ res = UuidCreateSequential(&uuid); ++ Py_END_ALLOW_THREADS ++ return res == RPC_S_OK; ++} + #endif /* MS_WINDOWS */ + + + static int +-uuid_exec(PyObject *module) { ++uuid_exec(PyObject *module) ++{ ++#define ADD_INT(NAME, VALUE) \ ++ do { \ ++ if (PyModule_AddIntConstant(module, (NAME), (VALUE)) < 0) { \ ++ return -1; \ ++ } \ ++ } while (0) ++ + assert(sizeof(uuid_t) == 16); + #if defined(MS_WINDOWS) +- int has_uuid_generate_time_safe = 0; ++ ADD_INT("has_uuid_generate_time_safe", 0); + #elif defined(HAVE_UUID_GENERATE_TIME_SAFE) +- int has_uuid_generate_time_safe = 1; ++ ADD_INT("has_uuid_generate_time_safe", 1); + #else +- int has_uuid_generate_time_safe = 0; ++ ADD_INT("has_uuid_generate_time_safe", 0); + #endif +- if (PyModule_AddIntConstant(module, "has_uuid_generate_time_safe", +- has_uuid_generate_time_safe) < 0) { +- return -1; +- } ++ ++#if defined(MS_WINDOWS) ++ ADD_INT("has_stable_extractable_node", py_windows_has_stable_node()); ++#elif defined(HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC) ++ ADD_INT("has_stable_extractable_node", 1); ++#else ++ ADD_INT("has_stable_extractable_node", 0); ++#endif ++ ++#undef ADD_INT + return 0; + } + +diff --git a/configure b/configure +index 1cd1f690f7b9c1..cc976aafc09b34 100755 +--- a/configure ++++ b/configure +@@ -13381,6 +13381,7 @@ fi + + + ++ + have_uuid=missing + + for ac_header in uuid.h +@@ -13390,6 +13391,7 @@ if test "x$ac_cv_header_uuid_h" = xyes + then : + printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h + ++ + for ac_func in uuid_create uuid_enc_be + do : + as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` +@@ -13399,7 +13401,9 @@ then : + cat >>confdefs.h <<_ACEOF + #define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 + _ACEOF +- have_uuid=yes ++ ++ have_uuid=yes ++ ac_cv_have_uuid_h=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + +@@ -13489,6 +13493,7 @@ if test "x$ac_cv_header_uuid_uuid_h" = xyes + then : + printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h + ++ ac_cv_have_uuid_uuid_h=yes + py_check_lib_save_LIBS=$LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 + printf %s "checking for uuid_generate_time in -luuid... " >&6; } +@@ -13570,8 +13575,9 @@ fi + printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } + if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes + then : +- have_uuid=yes +- printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h ++ ++ have_uuid=yes ++ ac_cv_have_uuid_generate_time_safe=yes + + fi + +@@ -13615,6 +13621,7 @@ if test "x$ac_cv_header_uuid_uuid_h" = xyes + then : + printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h + ++ ac_cv_have_uuid_uuid_h=yes + py_check_lib_save_LIBS=$LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 + printf %s "checking for uuid_generate_time in -luuid... " >&6; } +@@ -13696,8 +13703,9 @@ fi + printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } + if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes + then : +- have_uuid=yes +- printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h ++ ++ have_uuid=yes ++ ac_cv_have_uuid_generate_time_safe=yes + + fi + +@@ -13727,11 +13735,25 @@ else + LIBUUID_LIBS=$pkg_cv_LIBUUID_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + printf "%s\n" "yes" >&6; } ++<<<<<<< HEAD + have_uuid=yes + printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h + + printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h + ++======= ++ have_uuid=yes ++ ac_cv_have_uuid_generate_time_safe=yes ++ # The uuid.h file to include may be *or* . ++ # Since pkg-config --cflags uuid may return -I/usr/include/uuid, ++ # it's possible to write '#include ' in _uuidmodule.c, ++ # assuming that the compiler flags are properly updated. ++ # ++ # Ideally, we should have defined HAVE_UUID_H if and only if ++ # #include can be written, *without* assuming extra ++ # include path. ++ ac_cv_have_uuid_h=yes ++>>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901)) + + fi + +@@ -13752,6 +13774,7 @@ if test "x$ac_cv_func_uuid_generate_time" = xyes + then : + + have_uuid=yes ++ ac_cv_have_uuid_uuid_h=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + +@@ -13764,11 +13787,198 @@ done + + fi + ++<<<<<<< HEAD ++======= ++if test "x$ac_cv_have_uuid_h" = xyes ++then : ++ printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h ++ ++fi ++if test "x$ac_cv_have_uuid_uuid_h" = xyes ++then : ++ printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h ++ ++fi ++if test "x$ac_cv_have_uuid_generate_time_safe" = xyes ++then : ++ ++ printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h ++ ++ ++fi ++ ++# gh-124228: While the libuuid library is available on NetBSD, it supports only UUID version 4. ++# This restriction inhibits the proper generation of time-based UUIDs. ++if test "$ac_sys_system" = "NetBSD"; then ++ have_uuid=missing ++ printf "%s\n" "#define HAVE_UUID_H 0" >>confdefs.h ++ ++fi ++ ++>>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901)) + if test "x$have_uuid" = xmissing + then : + have_uuid=no + fi + ++# gh-132710: The UUID node is fetched by using libuuid when possible ++# and cached. While the node is constant within the same process, ++# different interpreters may have different values as libuuid may ++# randomize the node value if the latter cannot be deduced. ++# ++# Consumers may define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC ++# to indicate that libuuid is unstable and should not be relied ++# upon to deduce the MAC address. ++ ++ ++if test "$have_uuid" = "yes" -a "$HAVE_UUID_GENERATE_TIME_SAFE" = "1" ++then ++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if uuid_generate_time_safe() node value is stable" >&5 ++printf %s "checking if uuid_generate_time_safe() node value is stable... " >&6; } ++ save_CFLAGS=$CFLAGS ++save_CPPFLAGS=$CPPFLAGS ++save_LDFLAGS=$LDFLAGS ++save_LIBS=$LIBS ++ ++ ++ # Be sure to add the extra include path if we used pkg-config ++ # as HAVE_UUID_H may be set even though is only reachable ++ # by adding extra -I flags. ++ # ++ # If the following script does not compile, we simply assume that ++ # libuuid is missing. ++ CFLAGS="$CFLAGS $LIBUUID_CFLAGS" ++ LIBS="$LIBS $LIBUUID_LIBS" ++ if test "$cross_compiling" = yes ++then : ++ ++ ++else case e in #( ++ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++ #include // PRIu64 ++ #include // uint64_t ++ #include // fopen(), fclose() ++ ++ #ifdef HAVE_UUID_H ++ #include ++ #else ++ #include ++ #endif ++ ++ #define ERR 1 ++ int main(void) { ++ uuid_t uuid; // unsigned char[16] ++ (void)uuid_generate_time_safe(uuid); ++ uint64_t node = 0; ++ for (size_t i = 0; i < 6; i++) { ++ node |= (uint64_t)uuid[15 - i] << (8 * i); ++ } ++ FILE *fp = fopen("conftest.out", "w"); ++ if (fp == NULL) { ++ return ERR; ++ } ++ int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0; ++ rc |= fclose(fp); ++ return rc == 0 ? 0 : ERR; ++ } ++_ACEOF ++if ac_fn_c_try_run "$LINENO" ++then : ++ ++ py_cv_uuid_node1=`cat conftest.out` ++ ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ ++ conftest.$ac_objext conftest.beam conftest.$ac_ext ;; ++esac ++fi ++ ++CFLAGS=$save_CFLAGS ++CPPFLAGS=$save_CPPFLAGS ++LDFLAGS=$save_LDFLAGS ++LIBS=$save_LIBS ++ ++ ++ save_CFLAGS=$CFLAGS ++save_CPPFLAGS=$CPPFLAGS ++save_LDFLAGS=$LDFLAGS ++save_LIBS=$LIBS ++ ++ ++ # Be sure to add the extra include path if we used pkg-config ++ # as HAVE_UUID_H may be set even though is only reachable ++ # by adding extra -I flags. ++ # ++ # If the following script does not compile, we simply assume that ++ # libuuid is missing. ++ CFLAGS="$CFLAGS $LIBUUID_CFLAGS" ++ LIBS="$LIBS $LIBUUID_LIBS" ++ if test "$cross_compiling" = yes ++then : ++ ++ ++else case e in #( ++ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++ #include // PRIu64 ++ #include // uint64_t ++ #include // fopen(), fclose() ++ ++ #ifdef HAVE_UUID_H ++ #include ++ #else ++ #include ++ #endif ++ ++ #define ERR 1 ++ int main(void) { ++ uuid_t uuid; // unsigned char[16] ++ (void)uuid_generate_time_safe(uuid); ++ uint64_t node = 0; ++ for (size_t i = 0; i < 6; i++) { ++ node |= (uint64_t)uuid[15 - i] << (8 * i); ++ } ++ FILE *fp = fopen("conftest.out", "w"); ++ if (fp == NULL) { ++ return ERR; ++ } ++ int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0; ++ rc |= fclose(fp); ++ return rc == 0 ? 0 : ERR; ++ } ++_ACEOF ++if ac_fn_c_try_run "$LINENO" ++then : ++ ++ py_cv_uuid_node2=`cat conftest.out` ++ ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ ++ conftest.$ac_objext conftest.beam conftest.$ac_ext ;; ++esac ++fi ++ ++CFLAGS=$save_CFLAGS ++CPPFLAGS=$save_CPPFLAGS ++LDFLAGS=$save_LDFLAGS ++LIBS=$save_LIBS ++ ++ ++ if test -n "$py_cv_uuid_node1" -a "$py_cv_uuid_node1" = "$py_cv_uuid_node2" ++ then ++ printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC 1" >>confdefs.h ++ ++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: stable" >&5 ++printf "%s\n" "stable" >&6; } ++ else ++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unstable" >&5 ++printf "%s\n" "unstable" >&6; } ++ fi ++fi ++ + # 'Real Time' functions on Solaris + # posix4 on Solaris 2.6 + # pthread (first!) on Linux +diff --git a/configure.ac b/configure.ac +index 3fcb18922c5330..9898af7ffd5f25 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3740,15 +3740,17 @@ dnl check for uuid dependencies + AH_TEMPLATE([HAVE_UUID_H], [Define to 1 if you have the header file.]) + AH_TEMPLATE([HAVE_UUID_UUID_H], [Define to 1 if you have the header file.]) + AH_TEMPLATE([HAVE_UUID_GENERATE_TIME_SAFE], [Define if uuid_generate_time_safe() exists.]) ++AH_TEMPLATE([HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC], [Define if uuid_generate_time_safe() is able to deduce a MAC address.]) + have_uuid=missing + + dnl AIX provides support for RFC4122 (uuid) in libc.a starting with AIX 6.1 + dnl (anno 2007). FreeBSD and OpenBSD provides support in libc as well. + dnl Little-endian FreeBSD, OpenBSD and NetBSD needs encoding into an octet + dnl stream in big-endian byte-order +-AC_CHECK_HEADERS([uuid.h], +- [AC_CHECK_FUNCS([uuid_create uuid_enc_be], +- [have_uuid=yes ++AC_CHECK_HEADERS([uuid.h], [ ++ AC_CHECK_FUNCS([uuid_create uuid_enc_be], [ ++ have_uuid=yes ++ ac_cv_have_uuid_h=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + ]) +@@ -3758,19 +3760,29 @@ AS_VAR_IF([have_uuid], [missing], [ + PKG_CHECK_MODULES( + [LIBUUID], [uuid >= 2.20], + [dnl linux-util's libuuid has uuid_generate_time_safe() since v2.20 (2011) +- dnl and provides . ++ dnl and provides assuming specific include paths are given + have_uuid=yes +- AC_DEFINE([HAVE_UUID_H], [1]) +- AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) ++ ac_cv_have_uuid_generate_time_safe=yes ++ # The uuid.h file to include may be *or* . ++ # Since pkg-config --cflags uuid may return -I/usr/include/uuid, ++ # it's possible to write '#include ' in _uuidmodule.c, ++ # assuming that the compiler flags are properly updated. ++ # ++ # Ideally, we should have defined HAVE_UUID_H if and only if ++ # #include can be written, *without* assuming extra ++ # include path. ++ ac_cv_have_uuid_h=yes + ], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBUUID_CFLAGS" + LIBS="$LIBS $LIBUUID_LIBS" + AC_CHECK_HEADERS([uuid/uuid.h], [ ++ ac_cv_have_uuid_uuid_h=yes + PY_CHECK_LIB([uuid], [uuid_generate_time], [have_uuid=yes]) +- PY_CHECK_LIB([uuid], [uuid_generate_time_safe], +- [have_uuid=yes +- AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) ]) ]) ++ PY_CHECK_LIB([uuid], [uuid_generate_time_safe], [ ++ have_uuid=yes ++ ac_cv_have_uuid_generate_time_safe=yes ++ ])]) + AS_VAR_IF([have_uuid], [yes], [ + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-"-luuid"} +@@ -3785,14 +3797,90 @@ AS_VAR_IF([have_uuid], [missing], [ + AC_CHECK_HEADERS([uuid/uuid.h], [ + AC_CHECK_FUNC([uuid_generate_time], [ + have_uuid=yes ++ ac_cv_have_uuid_uuid_h=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + ]) + ]) + ]) + ++AS_VAR_IF([ac_cv_have_uuid_h], [yes], [AC_DEFINE([HAVE_UUID_H], [1])]) ++AS_VAR_IF([ac_cv_have_uuid_uuid_h], [yes], [AC_DEFINE([HAVE_UUID_UUID_H], [1])]) ++AS_VAR_IF([ac_cv_have_uuid_generate_time_safe], [yes], [ ++ AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) ++]) ++ ++# gh-124228: While the libuuid library is available on NetBSD, it supports only UUID version 4. ++# This restriction inhibits the proper generation of time-based UUIDs. ++if test "$ac_sys_system" = "NetBSD"; then ++ have_uuid=missing ++ AC_DEFINE([HAVE_UUID_H], [0]) ++fi ++ + AS_VAR_IF([have_uuid], [missing], [have_uuid=no]) + ++# gh-132710: The UUID node is fetched by using libuuid when possible ++# and cached. While the node is constant within the same process, ++# different interpreters may have different values as libuuid may ++# randomize the node value if the latter cannot be deduced. ++# ++# Consumers may define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC ++# to indicate that libuuid is unstable and should not be relied ++# upon to deduce the MAC address. ++AC_DEFUN([PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC], [WITH_SAVE_ENV([ ++ # Be sure to add the extra include path if we used pkg-config ++ # as HAVE_UUID_H may be set even though is only reachable ++ # by adding extra -I flags. ++ # ++ # If the following script does not compile, we simply assume that ++ # libuuid is missing. ++ CFLAGS="$CFLAGS $LIBUUID_CFLAGS" ++ LIBS="$LIBS $LIBUUID_LIBS" ++ AC_RUN_IFELSE([AC_LANG_SOURCE([[ ++ #include // PRIu64 ++ #include // uint64_t ++ #include // fopen(), fclose() ++ ++ #ifdef HAVE_UUID_H ++ #include ++ #else ++ #include ++ #endif ++ ++ #define ERR 1 ++ int main(void) { ++ uuid_t uuid; // unsigned char[16] ++ (void)uuid_generate_time_safe(uuid); ++ uint64_t node = 0; ++ for (size_t i = 0; i < 6; i++) { ++ node |= (uint64_t)uuid[15 - i] << (8 * i); ++ } ++ FILE *fp = fopen("conftest.out", "w"); ++ if (fp == NULL) { ++ return ERR; ++ } ++ int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0; ++ rc |= fclose(fp); ++ return rc == 0 ? 0 : ERR; ++ }]])], [ ++ AS_VAR_SET([$1], [`cat conftest.out`]) ++ ], [], [] ++ )])]) ++ ++if test "$have_uuid" = "yes" -a "$HAVE_UUID_GENERATE_TIME_SAFE" = "1" ++then ++ AC_MSG_CHECKING([if uuid_generate_time_safe() node value is stable]) ++ PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC([py_cv_uuid_node1]) ++ PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC([py_cv_uuid_node2]) ++ if test -n "$py_cv_uuid_node1" -a "$py_cv_uuid_node1" = "$py_cv_uuid_node2" ++ then ++ AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC], [1]) ++ AC_MSG_RESULT([stable]) ++ else ++ AC_MSG_RESULT([unstable]) ++ fi ++fi ++ + # 'Real Time' functions on Solaris + # posix4 on Solaris 2.6 + # pthread (first!) on Linux +diff --git a/pyconfig.h.in b/pyconfig.h.in +index 3c16c694c84599..73358a0f35ae82 100644 +--- a/pyconfig.h.in ++++ b/pyconfig.h.in +@@ -1548,6 +1548,9 @@ + /* Define if uuid_generate_time_safe() exists. */ + #undef HAVE_UUID_GENERATE_TIME_SAFE + ++/* Define if uuid_generate_time_safe() is able to deduce a MAC address. */ ++#undef HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC ++ + /* Define to 1 if you have the header file. */ + #undef HAVE_UUID_H + + +From cb0f32a7d64b6dc4a63c4a683bb52a97ebe1d78a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= + <10796600+picnixz@users.noreply.github.com> +Date: Mon, 26 May 2025 12:34:00 +0200 +Subject: [PATCH 2/2] rgen + +--- + configure | 25 ++++++------------------- + 1 file changed, 6 insertions(+), 19 deletions(-) + +diff --git a/configure b/configure +index cc976aafc09b34..47e4f29e23a7ac 100755 +--- a/configure ++++ b/configure +@@ -13735,14 +13735,7 @@ else + LIBUUID_LIBS=$pkg_cv_LIBUUID_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + printf "%s\n" "yes" >&6; } +-<<<<<<< HEAD + have_uuid=yes +- printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h +- +- printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h +- +-======= +- have_uuid=yes + ac_cv_have_uuid_generate_time_safe=yes + # The uuid.h file to include may be *or* . + # Since pkg-config --cflags uuid may return -I/usr/include/uuid, +@@ -13753,7 +13746,6 @@ printf "%s\n" "yes" >&6; } + # #include can be written, *without* assuming extra + # include path. + ac_cv_have_uuid_h=yes +->>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901)) + + fi + +@@ -13787,8 +13779,6 @@ done + + fi + +-<<<<<<< HEAD +-======= + if test "x$ac_cv_have_uuid_h" = xyes + then : + printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h +@@ -13815,7 +13805,6 @@ if test "$ac_sys_system" = "NetBSD"; then + + fi + +->>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901)) + if test "x$have_uuid" = xmissing + then : + have_uuid=no +@@ -13853,8 +13842,8 @@ save_LIBS=$LIBS + then : + + +-else case e in #( +- e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++else $as_nop ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + + #include // PRIu64 +@@ -13891,8 +13880,7 @@ then : + + fi + rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +-esac ++ conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + + CFLAGS=$save_CFLAGS +@@ -13919,8 +13907,8 @@ save_LIBS=$LIBS + then : + + +-else case e in #( +- e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++else $as_nop ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + + #include // PRIu64 +@@ -13957,8 +13945,7 @@ then : + + fi + rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +-esac ++ conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + + CFLAGS=$save_CFLAGS From 86322ed93e50ac137dafb6875a4abcfc3229ea9b Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Thu, 5 Jun 2025 11:18:27 -0500 Subject: [PATCH 2/3] Fix patch test for c module --- cpython-unix/patch-uuid-getnode-stable-3.13.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpython-unix/patch-uuid-getnode-stable-3.13.patch b/cpython-unix/patch-uuid-getnode-stable-3.13.patch index 175398d30..3bb06b278 100644 --- a/cpython-unix/patch-uuid-getnode-stable-3.13.patch +++ b/cpython-unix/patch-uuid-getnode-stable-3.13.patch @@ -20,7 +20,7 @@ index e7e44c6413c2e2..ce396aa942b6ed 100755 uuid = c_uuid + def check_has_stable_libuuid_extractable_node(self): -+ if not self.uuid._has_stable_extractable_node: ++ if not self.uuid.has_stable_extractable_node: + self.skipTest("libuuid cannot deduce MAC address") + + @unittest.skipUnless(os.name == 'posix', 'POSIX only') From c0cf9499b802c28bbf62b50ecb5c4cda78b69e3a Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Thu, 5 Jun 2025 12:19:51 -0500 Subject: [PATCH 3/3] Fix patch --- cpython-unix/patch-uuid-getnode-stable-3.13.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpython-unix/patch-uuid-getnode-stable-3.13.patch b/cpython-unix/patch-uuid-getnode-stable-3.13.patch index 3bb06b278..11bdf83a0 100644 --- a/cpython-unix/patch-uuid-getnode-stable-3.13.patch +++ b/cpython-unix/patch-uuid-getnode-stable-3.13.patch @@ -20,7 +20,7 @@ index e7e44c6413c2e2..ce396aa942b6ed 100755 uuid = c_uuid + def check_has_stable_libuuid_extractable_node(self): -+ if not self.uuid.has_stable_extractable_node: ++ if not self.uuid._has_stable_extractable_node: + self.skipTest("libuuid cannot deduce MAC address") + + @unittest.skipUnless(os.name == 'posix', 'POSIX only') @@ -56,7 +56,7 @@ index c286eac38e1ef4..6ab1658cc5249a 100644 try: import _uuid _generate_time_safe = getattr(_uuid, "generate_time_safe", None) -+ _has_stable_extractable_node = _uuid.has_stable_extractable_node ++ _has_stable_extractable_node = getattr(_uuid, "has_stable_extractable_node", False) _UuidCreate = getattr(_uuid, "UuidCreate", None) except ImportError: _uuid = None