You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Fix types for dev_t processing in posix module: use uint64_t (unsigned) instead of int64_t (signed) #89928
Traceback (most recent call last):
File "/usr/ports/lang/python311/work/Python-3.11.0a1/Lib/test/test_posix.py", line 686, in test_makedevself.assertGreaterEqual(dev, 0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^AssertionError: -5228656221359548839 not greater than or equal to 0
The test checks that posix.stat(somepath).st_dev >= 0, but negative value was returned.
Python uses PyLong_FromLongLong to convert from dev_t C type which st_dev is:
Linux (Ubuntu18.04):
typedef__dev_tdev_t; // sys/stat.h__STD_TYPE__DEV_T_TYPE__dev_t; // sys/types.h#define__DEV_T_TYPE __UQUAD_TYPE; // sys/typesizes.h
So I suggest the attached patch to switch _PyLong_FromDev to PyLong_FromUnsignedLongLong which also makes it consistent with _Py_Dev_Converter which converts the other way with PyLong_AsUnsignedLongLong.
This change fixes the mentioned test, but another test failure is unmasked:
Traceback (most recent call last):
File "/usr/ports/lang/python311/work/Python-3.11.0a1/Lib/test/test_posix.py", line 704, in test_makedevself.assertEqual(posix.makedev(major, minor), dev)
^^^^^^^^^^^^^^^^^^^^^^^^^^^OverflowError: Python int too large to convert to C int
This problem needs couple more trivial changes, but I'm not sure how to make them correctly (and I'm also confused by how this file relates with clinic/posixmodule.c).
The problems are that:
os_major_impl/os_minor_impl and os_makedev_impl are inconsistent in their argument/return types for major/minor dev numbers: the former use unsigned int, while the latter uses int.
the correct type is platform dependent, for instance Linux uses unsigned int and FreeBSD uses int (from man makedev).
I guess that to fix this failure one needs to add a macro/typedef for the type for minor/major dev numbers like
#if defined(__FreeBSD__)
#defineDEVICE_MAJORMINOR_T int
#else#defineDEVICE_MAJORMINOR_T unsigned int
#endif
changed the title [-]Fix types for dev_t processing in posix module[/-][+]Fix types for dev_t processing in posix module: use uint64_t (unsigned) instead of int64_t (signed)[/+]on May 24, 2024
Activity
AMDmi3 commentedon Nov 9, 2021
So, I was investigating a test failure of python 3.11 and 3.10 on FreeBSD (but it likely applies to all python versions):
======================================================================
FAIL: test_makedev (test.test_posix.PosixTester)
----------------------------------------------------------------------
The test checks that posix.stat(somepath).st_dev >= 0, but negative value was returned.
Python uses PyLong_FromLongLong to convert from dev_t C type which st_dev is:
https://github.com/python/cpython/blob/main/Modules/posixmodule.c#L2410
https://github.com/python/cpython/blob/main/Modules/posixmodule.c#L901
POSIX does not seem to define signedness of dev_t,
https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/sys_types.h.html
only saying it shall be an "integer type". However on practice on both FreeBSD and Linux it's unsigned:
FreeBSD:
typedef __dev_t dev_t; // sys/types.h
typedef __uint64_t __dev_t; // sys/_types.h
So I suggest the attached patch to switch _PyLong_FromDev to PyLong_FromUnsignedLongLong which also makes it consistent with _Py_Dev_Converter which converts the other way with PyLong_AsUnsignedLongLong.
This change fixes the mentioned test, but another test failure is unmasked:
======================================================================
ERROR: test_makedev (test.test_posix.PosixTester)
----------------------------------------------------------------------
This problem needs couple more trivial changes, but I'm not sure how to make them correctly (and I'm also confused by how this file relates with clinic/posixmodule.c).
The problems are that:
unsigned int, while the latter usesint.unsigned intand FreeBSD usesint(fromman makedev).I guess that to fix this failure one needs to add a macro/typedef for the type for minor/major dev numbers like
and use it in the named functions:
static DEVICE_MAJORMINOR_T os_major_impl(PyObject *module, dev_t device)
static DEVICE_MAJORMINOR_T os_minor_impl(PyObject *module, dev_t device)
static dev_t os_makedev_impl(PyObject *module, DEVICE_MAJORMINOR_T major, DEVICE_MAJORMINOR_T minor)
10 remaining items
vstinner commentedon May 24, 2024
I closed the FreeBSD issue #113078 as a duplicate of this issue.
[-]Fix types for dev_t processing in posix module[/-][+]Fix types for dev_t processing in posix module: use uint64_t (unsigned) instead of int64_t (signed)[/+]gh-89928: Fix integer conversion of device numbers (GH-31794)
pythongh-89928: Fix integer conversion of device numbers (pythonGH-31794
[3.12] pythongh-89928: Fix integer conversion of device numbers (pyth…
vstinner commentedon Jun 4, 2024
Thanks for the fix @serhiy-storchaka!
[3.12] gh-89928: Fix integer conversion of device numbers (GH-31794) (G…
[3.13] gh-89928: Fix integer conversion of device numbers (GH-31794) (G…
pythongh-89928: Fix integer conversion of device numbers (pythonGH-31794
pythongh-89928: Fix integer conversion of device numbers (pythonGH-31794
pythongh-89928: Fix integer conversion of device numbers (pythonGH-31794