New submission from Dmitry Marakasov <amd...@amdmi3.ru>:
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) ---------------------------------------------------------------------- Traceback (most recent call last): File "/usr/ports/lang/python311/work/Python-3.11.0a1/Lib/test/test_posix.py", line 686, in test_makedev self.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: 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 Linux (Ubuntu 18.04): typedef __dev_t dev_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: ====================================================================== ERROR: test_makedev (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/usr/ports/lang/python311/work/Python-3.11.0a1/Lib/test/test_posix.py", line 704, in test_makedev self.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__) #define DEVICE_MAJORMINOR_T int #else #define DEVICE_MAJORMINOR_T unsigned int #endif 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) ---------- components: Extension Modules, FreeBSD files: posixmodule.c.patch keywords: patch messages: 406030 nosy: AMDmi3, koobs priority: normal severity: normal status: open title: Fix types for dev_t processing in posix module type: behavior versions: Python 3.10, Python 3.11, Python 3.6, Python 3.7, Python 3.8, Python 3.9 Added file: https://bugs.python.org/file50433/posixmodule.c.patch _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue45767> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com