]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-132629: Deprecate accepting out-of-range values for unsigned integers in PyArg_Par...
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 13 Jul 2025 09:44:54 +0000 (12:44 +0300)
committerGitHub <noreply@github.com>
Sun, 13 Jul 2025 09:44:54 +0000 (12:44 +0300)
For unsigned integer formats in the PyArg_Parse* functions,
accepting Python integers with value that is larger than
the maximal value the corresponding C type or less than
the minimal value for the corresponding signed integer type
is now deprecated.

19 files changed:
Doc/c-api/arg.rst
Doc/whatsnew/3.15.rst
Lib/test/clinic.test.c
Lib/test/test_capi/test_getargs.py
Lib/test/test_clinic.py
Misc/NEWS.d/next/C_API/2025-04-17-12-37-27.gh-issue-132629.01ArwX.rst [new file with mode: 0644]
Modules/clinic/_cursesmodule.c.h
Modules/clinic/_testclinic.c.h
Modules/clinic/_zoneinfo.c.h
Modules/clinic/binascii.c.h
Modules/clinic/fcntlmodule.c.h
Modules/clinic/posixmodule.c.h
Modules/clinic/selectmodule.c.h
Modules/clinic/signalmodule.c.h
Modules/clinic/zlibmodule.c.h
Modules/fcntlmodule.c
PC/clinic/msvcrtmodule.c.h
Python/getargs.c
Tools/clinic/libclinic/converters.py

index ab9f9c4539ae9a0b691a5f23a26dbff511a9b5c8..803572afc39ae315824093816ce7d397da13d955 100644 (file)
@@ -241,9 +241,11 @@ the Python object to the required type.
 
 For signed integer formats, :exc:`OverflowError` is raised if the value
 is out of range for the C type.
-For unsigned integer formats, no range checking is done --- the
+For unsigned integer formats, the
 most significant bits are silently truncated when the receiving field is too
-small to receive the value.
+small to receive the value, and :exc:`DeprecationWarning` is emitted when
+the value is larger than the maximal value for the C type or less than
+the minimal value for the corresponding signed integer type of the same size.
 
 ``b`` (:class:`int`) [unsigned char]
    Convert a nonnegative Python integer to an unsigned tiny integer, stored in a C
@@ -252,27 +254,25 @@ small to receive the value.
 ``B`` (:class:`int`) [unsigned char]
    Convert a Python integer to a tiny integer without overflow checking, stored in a C
    :c:expr:`unsigned char`.
+   Convert a Python integer to a C :c:expr:`unsigned char`.
 
 ``h`` (:class:`int`) [short int]
    Convert a Python integer to a C :c:expr:`short int`.
 
 ``H`` (:class:`int`) [unsigned short int]
-   Convert a Python integer to a C :c:expr:`unsigned short int`, without overflow
-   checking.
+   Convert a Python integer to a C :c:expr:`unsigned short int`.
 
 ``i`` (:class:`int`) [int]
    Convert a Python integer to a plain C :c:expr:`int`.
 
 ``I`` (:class:`int`) [unsigned int]
-   Convert a Python integer to a C :c:expr:`unsigned int`, without overflow
-   checking.
+   Convert a Python integer to a C :c:expr:`unsigned int`.
 
 ``l`` (:class:`int`) [long int]
    Convert a Python integer to a C :c:expr:`long int`.
 
 ``k`` (:class:`int`) [unsigned long]
-   Convert a Python integer to a C :c:expr:`unsigned long` without
-   overflow checking.
+   Convert a Python integer to a C :c:expr:`unsigned long`.
 
    .. versionchanged:: 3.14
       Use :meth:`~object.__index__` if available.
@@ -281,8 +281,7 @@ small to receive the value.
    Convert a Python integer to a C :c:expr:`long long`.
 
 ``K`` (:class:`int`) [unsigned long long]
-   Convert a Python integer to a C :c:expr:`unsigned long long`
-   without overflow checking.
+   Convert a Python integer to a C :c:expr:`unsigned long long`.
 
    .. versionchanged:: 3.14
       Use :meth:`~object.__index__` if available.
@@ -310,6 +309,14 @@ small to receive the value.
 ``D`` (:class:`complex`) [Py_complex]
    Convert a Python complex number to a C :c:type:`Py_complex` structure.
 
+.. deprecated:: next
+
+   For unsigned integer formats ``B``, ``H``, ``I``, ``k`` and ``K``,
+   :exc:`DeprecationWarning` is emitted when the value is larger than
+   the maximal value for the C type or less than the minimal value for
+   the corresponding signed integer type of the same size.
+
+
 Other objects
 -------------
 
index 010abb7d9b92788f00c7c0c7d643ca363b9e2c8d..2f713fbb888c30104791681290a50027646e0447 100644 (file)
@@ -462,7 +462,11 @@ Porting to Python 3.15
 Deprecated C APIs
 -----------------
 
-* TODO
+* For unsigned integer formats in :c:func:`PyArg_ParseTuple`,
+  accepting Python integers with value that is larger than the maximal value
+  for the C type or less than the minimal value for the corresponding
+  signed integer type of the same size is now deprecated.
+  (Contributed by Serhiy Storchaka in :gh:`132629`.)
 
 .. Add C API deprecations above alphabetically, not here at the end.
 
index 4a67fcd2c3e9b386d97fe8675d596ff5fbfc523d..dc5b4b27a07f99531c4ca582882c8d232b7248d2 100644 (file)
@@ -1020,12 +1020,19 @@ test_unsigned_char_converter(PyObject *module, PyObject *const *args, Py_ssize_t
         goto skip_optional;
     }
     {
-        unsigned long ival = PyLong_AsUnsignedLongMask(args[2]);
-        if (ival == (unsigned long)-1 && PyErr_Occurred()) {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned char),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
             goto exit;
         }
-        else {
-            c = (unsigned char) ival;
+        if ((size_t)_bytes > sizeof(unsigned char)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
         }
     }
 skip_optional:
@@ -1038,7 +1045,7 @@ exit:
 static PyObject *
 test_unsigned_char_converter_impl(PyObject *module, unsigned char a,
                                   unsigned char b, unsigned char c)
-/*[clinic end generated code: output=45920dbedc22eb55 input=021414060993e289]*/
+/*[clinic end generated code: output=49eda9faaf53372a input=021414060993e289]*/
 
 
 /*[clinic input]
@@ -1151,9 +1158,21 @@ test_unsigned_short_converter(PyObject *module, PyObject *const *args, Py_ssize_
     if (nargs < 3) {
         goto skip_optional;
     }
-    c = (unsigned short)PyLong_AsUnsignedLongMask(args[2]);
-    if (c == (unsigned short)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned short),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned short)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
 skip_optional:
     return_value = test_unsigned_short_converter_impl(module, a, b, c);
@@ -1165,7 +1184,7 @@ exit:
 static PyObject *
 test_unsigned_short_converter_impl(PyObject *module, unsigned short a,
                                    unsigned short b, unsigned short c)
-/*[clinic end generated code: output=e6e990df729114fc input=cdfd8eff3d9176b4]*/
+/*[clinic end generated code: output=f591c7797e150f49 input=cdfd8eff3d9176b4]*/
 
 
 /*[clinic input]
@@ -1298,9 +1317,21 @@ test_unsigned_int_converter(PyObject *module, PyObject *const *args, Py_ssize_t
     if (nargs < 3) {
         goto skip_optional;
     }
-    c = (unsigned int)PyLong_AsUnsignedLongMask(args[2]);
-    if (c == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
 skip_optional:
     return_value = test_unsigned_int_converter_impl(module, a, b, c);
@@ -1312,7 +1343,7 @@ exit:
 static PyObject *
 test_unsigned_int_converter_impl(PyObject *module, unsigned int a,
                                  unsigned int b, unsigned int c)
-/*[clinic end generated code: output=f9cdbe410ccc98a3 input=5533534828b62fc0]*/
+/*[clinic end generated code: output=50a413f1cc82dc11 input=5533534828b62fc0]*/
 
 
 /*[clinic input]
@@ -1414,7 +1445,22 @@ test_unsigned_long_converter(PyObject *module, PyObject *const *args, Py_ssize_t
         _PyArg_BadArgument("test_unsigned_long_converter", "argument 3", "int", args[2]);
         goto exit;
     }
-    c = PyLong_AsUnsignedLongMask(args[2]);
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned long),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned long)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
+    }
 skip_optional:
     return_value = test_unsigned_long_converter_impl(module, a, b, c);
 
@@ -1425,7 +1471,7 @@ exit:
 static PyObject *
 test_unsigned_long_converter_impl(PyObject *module, unsigned long a,
                                   unsigned long b, unsigned long c)
-/*[clinic end generated code: output=d74eed227d77a31b input=f450d94cae1ef73b]*/
+/*[clinic end generated code: output=1bbf5620093cc914 input=f450d94cae1ef73b]*/
 
 
 /*[clinic input]
@@ -1529,7 +1575,22 @@ test_unsigned_long_long_converter(PyObject *module, PyObject *const *args, Py_ss
         _PyArg_BadArgument("test_unsigned_long_long_converter", "argument 3", "int", args[2]);
         goto exit;
     }
-    c = PyLong_AsUnsignedLongLongMask(args[2]);
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned long long),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned long long)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
+    }
 skip_optional:
     return_value = test_unsigned_long_long_converter_impl(module, a, b, c);
 
@@ -1542,7 +1603,7 @@ test_unsigned_long_long_converter_impl(PyObject *module,
                                        unsigned long long a,
                                        unsigned long long b,
                                        unsigned long long c)
-/*[clinic end generated code: output=5ca4e4dfb3db644b input=a15115dc41866ff4]*/
+/*[clinic end generated code: output=582a6623dc845824 input=a15115dc41866ff4]*/
 
 
 /*[clinic input]
index 67a8da7599511fbce176468208562226db99a5b5..dc2000089684a652c36d886a7a0c795d65845cb9 100644 (file)
@@ -48,8 +48,8 @@ except ImportError:
 LARGE = 0x7FFFFFFF
 VERY_LARGE = 0xFF0000121212121212121242
 
-from _testcapi import UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, INT_MAX, \
-     INT_MIN, LONG_MIN, LONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, \
+from _testcapi import UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, ULLONG_MAX, INT_MAX, \
+     INT_MIN, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, \
      SHRT_MIN, SHRT_MAX, FLT_MIN, FLT_MAX, DBL_MIN, DBL_MAX
 
 DBL_MAX_EXP = sys.float_info.max_exp
@@ -57,9 +57,8 @@ INF = float('inf')
 NAN = float('nan')
 
 # fake, they are not defined in Python's header files
-LLONG_MAX = 2**63-1
-LLONG_MIN = -2**63
-ULLONG_MAX = 2**64-1
+SCHAR_MAX = UCHAR_MAX // 2
+SCHAR_MIN = SCHAR_MAX - UCHAR_MAX
 
 NULL = None
 
@@ -209,10 +208,23 @@ class Unsigned_TestCase(unittest.TestCase):
         self.assertEqual(UCHAR_MAX, getargs_B(-1))
         self.assertEqual(0, getargs_B(0))
         self.assertEqual(UCHAR_MAX, getargs_B(UCHAR_MAX))
-        self.assertEqual(0, getargs_B(UCHAR_MAX+1))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(0, getargs_B(UCHAR_MAX+1))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(1, getargs_B(-UCHAR_MAX))
+        self.assertEqual(SCHAR_MAX+1, getargs_B(SCHAR_MIN))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(SCHAR_MAX, getargs_B(SCHAR_MIN-1))
+
+        self.assertEqual(128, getargs_B(-2**7))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(127, getargs_B(-2**7-1))
 
         self.assertEqual(42, getargs_B(42))
-        self.assertEqual(UCHAR_MAX & VERY_LARGE, getargs_B(VERY_LARGE))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(UCHAR_MAX & VERY_LARGE, getargs_B(VERY_LARGE))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(UCHAR_MAX & -VERY_LARGE, getargs_B(-VERY_LARGE))
 
     def test_H(self):
         from _testcapi import getargs_H
@@ -233,11 +245,18 @@ class Unsigned_TestCase(unittest.TestCase):
         self.assertEqual(USHRT_MAX, getargs_H(-1))
         self.assertEqual(0, getargs_H(0))
         self.assertEqual(USHRT_MAX, getargs_H(USHRT_MAX))
-        self.assertEqual(0, getargs_H(USHRT_MAX+1))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(0, getargs_H(USHRT_MAX+1))
+        self.assertEqual(SHRT_MAX+1, getargs_H(SHRT_MIN))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(SHRT_MAX, getargs_H(SHRT_MIN-1))
 
         self.assertEqual(42, getargs_H(42))
 
-        self.assertEqual(VERY_LARGE & USHRT_MAX, getargs_H(VERY_LARGE))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(USHRT_MAX & VERY_LARGE, getargs_H(VERY_LARGE))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(USHRT_MAX & -VERY_LARGE, getargs_H(-VERY_LARGE))
 
     def test_I(self):
         from _testcapi import getargs_I
@@ -258,11 +277,18 @@ class Unsigned_TestCase(unittest.TestCase):
         self.assertEqual(UINT_MAX, getargs_I(-1))
         self.assertEqual(0, getargs_I(0))
         self.assertEqual(UINT_MAX, getargs_I(UINT_MAX))
-        self.assertEqual(0, getargs_I(UINT_MAX+1))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(0, getargs_I(UINT_MAX+1))
+        self.assertEqual(INT_MAX+1, getargs_I(INT_MIN))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(INT_MAX, getargs_I(INT_MIN-1))
 
         self.assertEqual(42, getargs_I(42))
 
-        self.assertEqual(VERY_LARGE & UINT_MAX, getargs_I(VERY_LARGE))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(UINT_MAX & VERY_LARGE, getargs_I(VERY_LARGE))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(UINT_MAX & -VERY_LARGE, getargs_I(-VERY_LARGE))
 
     def test_k(self):
         from _testcapi import getargs_k
@@ -283,11 +309,18 @@ class Unsigned_TestCase(unittest.TestCase):
         self.assertEqual(ULONG_MAX, getargs_k(-1))
         self.assertEqual(0, getargs_k(0))
         self.assertEqual(ULONG_MAX, getargs_k(ULONG_MAX))
-        self.assertEqual(0, getargs_k(ULONG_MAX+1))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(0, getargs_k(ULONG_MAX+1))
+        self.assertEqual(LONG_MAX+1, getargs_k(LONG_MIN))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(LONG_MAX, getargs_k(LONG_MIN-1))
 
         self.assertEqual(42, getargs_k(42))
 
-        self.assertEqual(VERY_LARGE & ULONG_MAX, getargs_k(VERY_LARGE))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ULONG_MAX & VERY_LARGE, getargs_k(VERY_LARGE))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ULONG_MAX & -VERY_LARGE, getargs_k(-VERY_LARGE))
 
 class Signed_TestCase(unittest.TestCase):
     def test_h(self):
@@ -434,11 +467,18 @@ class LongLong_TestCase(unittest.TestCase):
         self.assertEqual(ULLONG_MAX, getargs_K(ULLONG_MAX))
         self.assertEqual(0, getargs_K(0))
         self.assertEqual(ULLONG_MAX, getargs_K(ULLONG_MAX))
-        self.assertEqual(0, getargs_K(ULLONG_MAX+1))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(0, getargs_K(ULLONG_MAX+1))
+        self.assertEqual(LLONG_MAX+1, getargs_K(LLONG_MIN))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(LLONG_MAX, getargs_K(LLONG_MIN-1))
 
         self.assertEqual(42, getargs_K(42))
 
-        self.assertEqual(VERY_LARGE & ULLONG_MAX, getargs_K(VERY_LARGE))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ULLONG_MAX & VERY_LARGE, getargs_K(VERY_LARGE))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ULLONG_MAX & -VERY_LARGE, getargs_K(-VERY_LARGE))
 
 
 class Float_TestCase(unittest.TestCase, FloatsAreIdenticalMixin):
index 580d54e0eb094df588d585d37b8034b5ae2808a7..a6ed887999242f2b79a0e2652034c7509e70e8a7 100644 (file)
@@ -3048,6 +3048,8 @@ class ClinicFunctionalTest(unittest.TestCase):
 
     def test_unsigned_char_converter(self):
         from _testcapi import UCHAR_MAX
+        SCHAR_MAX = UCHAR_MAX // 2
+        SCHAR_MIN = SCHAR_MAX - UCHAR_MAX
         with self.assertRaises(OverflowError):
             ac_tester.unsigned_char_converter(-1)
         with self.assertRaises(OverflowError):
@@ -3057,8 +3059,13 @@ class ClinicFunctionalTest(unittest.TestCase):
         with self.assertRaises(TypeError):
             ac_tester.unsigned_char_converter([])
         self.assertEqual(ac_tester.unsigned_char_converter(), (12, 34, 56))
-        self.assertEqual(ac_tester.unsigned_char_converter(0, 0, UCHAR_MAX + 1), (0, 0, 0))
-        self.assertEqual(ac_tester.unsigned_char_converter(0, 0, (UCHAR_MAX + 1) * 3 + 123), (0, 0, 123))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_char_converter(0, 0, UCHAR_MAX + 1), (0, 0, 0))
+        self.assertEqual(ac_tester.unsigned_char_converter(0, 0, SCHAR_MIN), (0, 0, SCHAR_MAX + 1))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_char_converter(0, 0, SCHAR_MIN - 1), (0, 0, SCHAR_MAX))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_char_converter(0, 0, (UCHAR_MAX + 1) * 3 + 123), (0, 0, 123))
 
     def test_short_converter(self):
         from _testcapi import SHRT_MIN, SHRT_MAX
@@ -3072,7 +3079,7 @@ class ClinicFunctionalTest(unittest.TestCase):
         self.assertEqual(ac_tester.short_converter(4321), (4321,))
 
     def test_unsigned_short_converter(self):
-        from _testcapi import USHRT_MAX
+        from _testcapi import SHRT_MIN, SHRT_MAX, USHRT_MAX
         with self.assertRaises(ValueError):
             ac_tester.unsigned_short_converter(-1)
         with self.assertRaises(OverflowError):
@@ -3082,8 +3089,13 @@ class ClinicFunctionalTest(unittest.TestCase):
         with self.assertRaises(TypeError):
             ac_tester.unsigned_short_converter([])
         self.assertEqual(ac_tester.unsigned_short_converter(), (12, 34, 56))
-        self.assertEqual(ac_tester.unsigned_short_converter(0, 0, USHRT_MAX + 1), (0, 0, 0))
-        self.assertEqual(ac_tester.unsigned_short_converter(0, 0, (USHRT_MAX + 1) * 3 + 123), (0, 0, 123))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_short_converter(0, 0, USHRT_MAX + 1), (0, 0, 0))
+        self.assertEqual(ac_tester.unsigned_short_converter(0, 0, SHRT_MIN), (0, 0, SHRT_MAX + 1))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_short_converter(0, 0, SHRT_MIN - 1), (0, 0, SHRT_MAX))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_short_converter(0, 0, (USHRT_MAX + 1) * 3 + 123), (0, 0, 123))
 
     def test_int_converter(self):
         from _testcapi import INT_MIN, INT_MAX
@@ -3099,7 +3111,7 @@ class ClinicFunctionalTest(unittest.TestCase):
         self.assertEqual(ac_tester.int_converter(1, 2, '3'), (1, 2, ord('3')))
 
     def test_unsigned_int_converter(self):
-        from _testcapi import UINT_MAX
+        from _testcapi import INT_MIN, INT_MAX, UINT_MAX
         with self.assertRaises(ValueError):
             ac_tester.unsigned_int_converter(-1)
         with self.assertRaises(OverflowError):
@@ -3109,8 +3121,13 @@ class ClinicFunctionalTest(unittest.TestCase):
         with self.assertRaises(TypeError):
             ac_tester.unsigned_int_converter([])
         self.assertEqual(ac_tester.unsigned_int_converter(), (12, 34, 56))
-        self.assertEqual(ac_tester.unsigned_int_converter(0, 0, UINT_MAX + 1), (0, 0, 0))
-        self.assertEqual(ac_tester.unsigned_int_converter(0, 0, (UINT_MAX + 1) * 3 + 123), (0, 0, 123))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_int_converter(0, 0, UINT_MAX + 1), (0, 0, 0))
+        self.assertEqual(ac_tester.unsigned_int_converter(0, 0, INT_MIN), (0, 0, INT_MAX + 1))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_int_converter(0, 0, INT_MIN - 1), (0, 0, INT_MAX))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_int_converter(0, 0, (UINT_MAX + 1) * 3 + 123), (0, 0, 123))
 
     def test_long_converter(self):
         from _testcapi import LONG_MIN, LONG_MAX
@@ -3124,7 +3141,7 @@ class ClinicFunctionalTest(unittest.TestCase):
         self.assertEqual(ac_tester.long_converter(-1234), (-1234,))
 
     def test_unsigned_long_converter(self):
-        from _testcapi import ULONG_MAX
+        from _testcapi import LONG_MIN, LONG_MAX, ULONG_MAX
         with self.assertRaises(ValueError):
             ac_tester.unsigned_long_converter(-1)
         with self.assertRaises(OverflowError):
@@ -3134,8 +3151,13 @@ class ClinicFunctionalTest(unittest.TestCase):
         with self.assertRaises(TypeError):
             ac_tester.unsigned_long_converter([])
         self.assertEqual(ac_tester.unsigned_long_converter(), (12, 34, 56))
-        self.assertEqual(ac_tester.unsigned_long_converter(0, 0, ULONG_MAX + 1), (0, 0, 0))
-        self.assertEqual(ac_tester.unsigned_long_converter(0, 0, (ULONG_MAX + 1) * 3 + 123), (0, 0, 123))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_long_converter(0, 0, ULONG_MAX + 1), (0, 0, 0))
+        self.assertEqual(ac_tester.unsigned_long_converter(0, 0, LONG_MIN), (0, 0, LONG_MAX + 1))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_long_converter(0, 0, LONG_MIN - 1), (0, 0, LONG_MAX))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_long_converter(0, 0, (ULONG_MAX + 1) * 3 + 123), (0, 0, 123))
 
     def test_long_long_converter(self):
         from _testcapi import LLONG_MIN, LLONG_MAX
@@ -3149,7 +3171,7 @@ class ClinicFunctionalTest(unittest.TestCase):
         self.assertEqual(ac_tester.long_long_converter(-1234), (-1234,))
 
     def test_unsigned_long_long_converter(self):
-        from _testcapi import ULLONG_MAX
+        from _testcapi import LLONG_MIN, LLONG_MAX, ULLONG_MAX
         with self.assertRaises(ValueError):
             ac_tester.unsigned_long_long_converter(-1)
         with self.assertRaises(OverflowError):
@@ -3159,8 +3181,13 @@ class ClinicFunctionalTest(unittest.TestCase):
         with self.assertRaises(TypeError):
             ac_tester.unsigned_long_long_converter([])
         self.assertEqual(ac_tester.unsigned_long_long_converter(), (12, 34, 56))
-        self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, ULLONG_MAX + 1), (0, 0, 0))
-        self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, (ULLONG_MAX + 1) * 3 + 123), (0, 0, 123))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, ULLONG_MAX + 1), (0, 0, 0))
+        self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, LLONG_MIN), (0, 0, LLONG_MAX + 1))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, LLONG_MIN - 1), (0, 0, LLONG_MAX))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, (ULLONG_MAX + 1) * 3 + 123), (0, 0, 123))
 
     def test_py_ssize_t_converter(self):
         from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
diff --git a/Misc/NEWS.d/next/C_API/2025-04-17-12-37-27.gh-issue-132629.01ArwX.rst b/Misc/NEWS.d/next/C_API/2025-04-17-12-37-27.gh-issue-132629.01ArwX.rst
new file mode 100644 (file)
index 0000000..38b7a0a
--- /dev/null
@@ -0,0 +1,4 @@
+For unsigned integer formats in :c:func:`PyArg_ParseTuple`, accepting Python
+integers with value that is larger than the maximal value for the C type or
+less than the minimal value for the corresponding signed integer type
+of the same size is now deprecated.
index 49c864318c8aa8819a8be7cf8cd70f8b3bce16b5..a8c32d6510604ae7e88ea352221581d134531854 100644 (file)
@@ -2372,7 +2372,22 @@ _curses_ungetmouse(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
         _PyArg_BadArgument("ungetmouse", "argument 5", "int", args[4]);
         goto exit;
     }
-    bstate = PyLong_AsUnsignedLongMask(args[4]);
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[4], &bstate, sizeof(unsigned long),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned long)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
+    }
     return_value = _curses_ungetmouse_impl(module, id, x, y, z, bstate);
 
 exit:
@@ -3138,7 +3153,22 @@ _curses_mousemask(PyObject *module, PyObject *arg)
         _PyArg_BadArgument("mousemask", "argument", "int", arg);
         goto exit;
     }
-    newmask = PyLong_AsUnsignedLongMask(arg);
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(arg, &newmask, sizeof(unsigned long),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned long)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
+    }
     return_value = _curses_mousemask_impl(module, newmask);
 
 exit:
@@ -4420,4 +4450,4 @@ _curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored
 #ifndef _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
     #define _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
 #endif /* !defined(_CURSES_ASSUME_DEFAULT_COLORS_METHODDEF) */
-/*[clinic end generated code: output=a083473003179b30 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=79ddaae4da3b80df input=a9049054013a1b77]*/
index 970528ce9ea46d763c1cb27fff8bfee77483140f..68c92a86226bc98c61bd3bd40b1ba6af37b7c0d0 100644 (file)
@@ -746,12 +746,19 @@ unsigned_char_converter(PyObject *module, PyObject *const *args, Py_ssize_t narg
         goto skip_optional;
     }
     {
-        unsigned long ival = PyLong_AsUnsignedLongMask(args[2]);
-        if (ival == (unsigned long)-1 && PyErr_Occurred()) {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned char),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
             goto exit;
         }
-        else {
-            c = (unsigned char) ival;
+        if ((size_t)_bytes > sizeof(unsigned char)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
         }
     }
 skip_optional:
@@ -848,9 +855,21 @@ unsigned_short_converter(PyObject *module, PyObject *const *args, Py_ssize_t nar
     if (nargs < 3) {
         goto skip_optional;
     }
-    c = (unsigned short)PyLong_AsUnsignedLongMask(args[2]);
-    if (c == (unsigned short)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned short),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned short)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
 skip_optional:
     return_value = unsigned_short_converter_impl(module, a, b, c);
@@ -955,9 +974,21 @@ unsigned_int_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs
     if (nargs < 3) {
         goto skip_optional;
     }
-    c = (unsigned int)PyLong_AsUnsignedLongMask(args[2]);
-    if (c == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
 skip_optional:
     return_value = unsigned_int_converter_impl(module, a, b, c);
@@ -1042,7 +1073,22 @@ unsigned_long_converter(PyObject *module, PyObject *const *args, Py_ssize_t narg
         _PyArg_BadArgument("unsigned_long_converter", "argument 3", "int", args[2]);
         goto exit;
     }
-    c = PyLong_AsUnsignedLongMask(args[2]);
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned long),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned long)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
+    }
 skip_optional:
     return_value = unsigned_long_converter_impl(module, a, b, c);
 
@@ -1126,7 +1172,22 @@ unsigned_long_long_converter(PyObject *module, PyObject *const *args, Py_ssize_t
         _PyArg_BadArgument("unsigned_long_long_converter", "argument 3", "int", args[2]);
         goto exit;
     }
-    c = PyLong_AsUnsignedLongLongMask(args[2]);
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned long long),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned long long)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
+    }
 skip_optional:
     return_value = unsigned_long_long_converter_impl(module, a, b, c);
 
@@ -4481,4 +4542,4 @@ _testclinic_TestClass_posonly_poskw_varpos_array_no_fastcall(PyObject *type, PyO
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=84ffc31f27215baa input=a9049054013a1b77]*/
+/*[clinic end generated code: output=6b04671afdafbecf input=a9049054013a1b77]*/
index 09ac157cbfd1355aaa4ad5276fd1ccf47eeadab4..19564a6c13f246af804957b6a90b9b28e6e96460 100644 (file)
@@ -434,12 +434,19 @@ zoneinfo_ZoneInfo__unpickle(PyObject *type, PyTypeObject *cls, PyObject *const *
     }
     key = args[0];
     {
-        unsigned long ival = PyLong_AsUnsignedLongMask(args[1]);
-        if (ival == (unsigned long)-1 && PyErr_Occurred()) {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &from_cache, sizeof(unsigned char),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
             goto exit;
         }
-        else {
-            from_cache = (unsigned char) ival;
+        if ((size_t)_bytes > sizeof(unsigned char)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
         }
     }
     return_value = zoneinfo_ZoneInfo__unpickle_impl((PyTypeObject *)type, cls, key, from_cache);
@@ -447,4 +454,4 @@ zoneinfo_ZoneInfo__unpickle(PyObject *type, PyTypeObject *cls, PyObject *const *
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=8e9e204f390261b9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=c6df04d7b400bd7f input=a9049054013a1b77]*/
index 602e42a4c1aaa4bde9a67ed9e61ebe202af2082e..ce29e0d11a45cd30a5886d5c01aa0e0eb7459718 100644 (file)
@@ -292,9 +292,21 @@ binascii_crc_hqx(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) {
         goto exit;
     }
-    crc = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
-    if (crc == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &crc, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
     return_value = binascii_crc_hqx_impl(module, &data, crc);
 
@@ -336,9 +348,21 @@ binascii_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (nargs < 2) {
         goto skip_optional;
     }
-    crc = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
-    if (crc == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &crc, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
 skip_optional:
     _return_value = binascii_crc32_impl(module, &data, crc);
@@ -788,4 +812,4 @@ exit:
 
     return return_value;
 }
-/*[clinic end generated code: output=adb855a2797c3cad input=a9049054013a1b77]*/
+/*[clinic end generated code: output=fba6a71e0d7d092f input=a9049054013a1b77]*/
index 00a929064ba7006b4c99028d20e478bd1dab4010..005e9b9e12afd92737d1f35662874d45ff5574f3 100644 (file)
@@ -124,7 +124,22 @@ fcntl_ioctl(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
         PyErr_Format(PyExc_TypeError, "ioctl() argument 2 must be int, not %T", args[1]);
         goto exit;
     }
-    code = PyLong_AsUnsignedLongMask(args[1]);
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &code, sizeof(unsigned long),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned long)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
+    }
     if (nargs < 3) {
         goto skip_optional;
     }
@@ -264,4 +279,4 @@ skip_optional:
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=65a16bc64c7b4de4 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=bf84289b741e7cf6 input=a9049054013a1b77]*/
index 3621a0625411d336e52381801efcc50a293c0a56..22f426c5192bf28e746d7480f101094dc95666ed 100644 (file)
@@ -844,7 +844,22 @@ os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *
         _PyArg_BadArgument("chflags", "argument 'flags'", "int", args[1]);
         goto exit;
     }
-    flags = PyLong_AsUnsignedLongMask(args[1]);
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &flags, sizeof(unsigned long),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned long)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
+    }
     if (!noptargs) {
         goto skip_optional_pos;
     }
@@ -928,7 +943,22 @@ os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject
         _PyArg_BadArgument("lchflags", "argument 'flags'", "int", args[1]);
         goto exit;
     }
-    flags = PyLong_AsUnsignedLongMask(args[1]);
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &flags, sizeof(unsigned long),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned long)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
+    }
     return_value = os_lchflags_impl(module, &path, flags);
 
 exit:
@@ -11373,9 +11403,21 @@ os_memfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj
     if (!noptargs) {
         goto skip_optional_pos;
     }
-    flags = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
-    if (flags == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &flags, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
 skip_optional_pos:
     return_value = os_memfd_create_impl(module, name, flags);
@@ -13398,4 +13440,4 @@ os__emscripten_debugger(PyObject *module, PyObject *Py_UNUSED(ignored))
 #ifndef OS__EMSCRIPTEN_DEBUGGER_METHODDEF
     #define OS__EMSCRIPTEN_DEBUGGER_METHODDEF
 #endif /* !defined(OS__EMSCRIPTEN_DEBUGGER_METHODDEF) */
-/*[clinic end generated code: output=ae64df0389746258 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=5341daae6581a62b input=a9049054013a1b77]*/
index 253ad8c9e78f00c015ff18af4676098080999bac..c0a5f678ad038d278b892664bf8014400bd1e28c 100644 (file)
@@ -783,9 +783,21 @@ select_epoll_register(PyObject *self, PyObject *const *args, Py_ssize_t nargs, P
     if (!noptargs) {
         goto skip_optional_pos;
     }
-    eventmask = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
-    if (eventmask == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &eventmask, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
 skip_optional_pos:
     return_value = select_epoll_register_impl((pyEpoll_Object *)self, fd, eventmask);
@@ -860,9 +872,21 @@ select_epoll_modify(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyO
     if (fd < 0) {
         goto exit;
     }
-    eventmask = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
-    if (eventmask == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &eventmask, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
     return_value = select_epoll_modify_impl((pyEpoll_Object *)self, fd, eventmask);
 
@@ -1375,4 +1399,4 @@ exit:
 #ifndef SELECT_KQUEUE_CONTROL_METHODDEF
     #define SELECT_KQUEUE_CONTROL_METHODDEF
 #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */
-/*[clinic end generated code: output=6fc20d78802511d1 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=2a66dd831f22c696 input=a9049054013a1b77]*/
index 955861b4da37d9caa84d32a3b46aed0b5c563649..b0cd9e2e561640a16e1328fb15854177ca0a01b4 100644 (file)
@@ -660,7 +660,22 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
         _PyArg_BadArgument("pthread_kill", "argument 1", "int", args[0]);
         goto exit;
     }
-    thread_id = PyLong_AsUnsignedLongMask(args[0]);
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[0], &thread_id, sizeof(unsigned long),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned long)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
+    }
     signalnum = PyLong_AsInt(args[1]);
     if (signalnum == -1 && PyErr_Occurred()) {
         goto exit;
@@ -779,4 +794,4 @@ exit:
 #ifndef SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF
     #define SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF
 #endif /* !defined(SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF) */
-/*[clinic end generated code: output=48bfaffeb25df5d2 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=37ae8ebeae4178fa input=a9049054013a1b77]*/
index 146a7e250019f04f318f00122ac1bcbf23fd0bbf..016af258d63deaa011b7ce167897e98893e6f58d 100644 (file)
@@ -1028,9 +1028,21 @@ zlib_adler32(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (nargs < 2) {
         goto skip_optional;
     }
-    value = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
-    if (value == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &value, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
 skip_optional:
     return_value = zlib_adler32_impl(module, &data, value);
@@ -1080,13 +1092,37 @@ zlib_adler32_combine(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (!_PyArg_CheckPositional("adler32_combine", nargs, 3, 3)) {
         goto exit;
     }
-    adler1 = (unsigned int)PyLong_AsUnsignedLongMask(args[0]);
-    if (adler1 == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[0], &adler1, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
-    adler2 = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
-    if (adler2 == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &adler2, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
     if (!PyLong_Check(args[2])) {
         _PyArg_BadArgument("adler32_combine", "argument 3", "int", args[2]);
@@ -1137,9 +1173,21 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (nargs < 2) {
         goto skip_optional;
     }
-    value = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
-    if (value == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &value, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
 skip_optional:
     _return_value = zlib_crc32_impl(module, &data, value);
@@ -1193,13 +1241,37 @@ zlib_crc32_combine(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     if (!_PyArg_CheckPositional("crc32_combine", nargs, 3, 3)) {
         goto exit;
     }
-    crc1 = (unsigned int)PyLong_AsUnsignedLongMask(args[0]);
-    if (crc1 == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[0], &crc1, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
-    crc2 = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
-    if (crc2 == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &crc2, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
     if (!PyLong_Check(args[2])) {
         _PyArg_BadArgument("crc32_combine", "argument 3", "int", args[2]);
@@ -1239,4 +1311,4 @@ exit:
 #ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF
     #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF
 #endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */
-/*[clinic end generated code: output=3f7692eb3b5d5a0c input=a9049054013a1b77]*/
+/*[clinic end generated code: output=3054c8894aa44568 input=a9049054013a1b77]*/
index 90363b9dca331627444aeb1a7d74447f6f7369a1..524eb54b984ca8e78585984bac674d38437accef 100644 (file)
@@ -1,9 +1,9 @@
 /* fcntl module */
 
-// Need limited C API version 3.13 for PyLong_AsInt()
+// Need limited C API version 3.14 for PyLong_AsNativeBytes() in AC code
 #include "pyconfig.h"   // Py_GIL_DISABLED
 #ifndef Py_GIL_DISABLED
-#  define Py_LIMITED_API 0x030d0000
+#  define Py_LIMITED_API 0x030e0000
 #endif
 
 #include "Python.h"
index a77d0855af293fe0f4c7abe390f39f4cfc5ae679..647aadfa46bbed448bd63ce43ca7aeaff65506bd 100644 (file)
@@ -690,9 +690,21 @@ msvcrt_SetErrorMode(PyObject *module, PyObject *arg)
     PyObject *return_value = NULL;
     unsigned int mode;
 
-    mode = (unsigned int)PyLong_AsUnsignedLongMask(arg);
-    if (mode == (unsigned int)-1 && PyErr_Occurred()) {
-        goto exit;
+    {
+        Py_ssize_t _bytes = PyLong_AsNativeBytes(arg, &mode, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (_bytes < 0) {
+            goto exit;
+        }
+        if ((size_t)_bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                goto exit;
+            }
+        }
     }
     return_value = msvcrt_SetErrorMode_impl(module, mode);
 
@@ -731,4 +743,4 @@ exit:
 #ifndef MSVCRT_GETERRORMODE_METHODDEF
     #define MSVCRT_GETERRORMODE_METHODDEF
 #endif /* !defined(MSVCRT_GETERRORMODE_METHODDEF) */
-/*[clinic end generated code: output=692c6f52bb9193ce input=a9049054013a1b77]*/
+/*[clinic end generated code: output=f67eaf745685429d input=a9049054013a1b77]*/
index 0cf596285cc7b583a11c88b2a11b971a70073334..02f5c0e37ee42a265c1ba87d8a981052092c0894 100644 (file)
@@ -734,11 +734,20 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
                   values allowed */
         unsigned char *p = va_arg(*p_va, unsigned char *);
         HANDLE_NULLABLE;
-        unsigned long ival = PyLong_AsUnsignedLongMask(arg);
-        if (ival == (unsigned long)-1 && PyErr_Occurred())
+        Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned char),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (bytes < 0) {
             RETURN_ERR_OCCURRED;
-        else
-            *p = (unsigned char) ival;
+        }
+        if ((size_t)bytes > sizeof(unsigned char)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                RETURN_ERR_OCCURRED;
+            }
+        }
         break;
     }
 
@@ -767,11 +776,20 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
                    unsigned allowed */
         unsigned short *p = va_arg(*p_va, unsigned short *);
         HANDLE_NULLABLE;
-        unsigned long ival = PyLong_AsUnsignedLongMask(arg);
-        if (ival == (unsigned long)-1 && PyErr_Occurred())
+        Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned short),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (bytes < 0) {
             RETURN_ERR_OCCURRED;
-        else
-            *p = (unsigned short) ival;
+        }
+        if ((size_t)bytes > sizeof(unsigned short)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                RETURN_ERR_OCCURRED;
+            }
+        }
         break;
     }
 
@@ -800,11 +818,20 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
                    unsigned allowed */
         unsigned int *p = va_arg(*p_va, unsigned int *);
         HANDLE_NULLABLE;
-        unsigned long ival = PyLong_AsUnsignedLongMask(arg);
-        if (ival == (unsigned long)-1 && PyErr_Occurred())
+        Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned int),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (bytes < 0) {
             RETURN_ERR_OCCURRED;
-        else
-            *p = (unsigned int) ival;
+        }
+        if ((size_t)bytes > sizeof(unsigned int)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                RETURN_ERR_OCCURRED;
+            }
+        }
         break;
     }
 
@@ -838,15 +865,23 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
     case 'k': { /* long sized bitfield */
         unsigned long *p = va_arg(*p_va, unsigned long *);
         HANDLE_NULLABLE;
-        unsigned long ival;
         if (!PyIndex_Check(arg)) {
             return converterr(nullable, "int", arg, msgbuf, bufsize);
         }
-        ival = PyLong_AsUnsignedLongMask(arg);
-        if (ival == (unsigned long)(long)-1 && PyErr_Occurred()) {
+        Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned long),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (bytes < 0) {
             RETURN_ERR_OCCURRED;
         }
-        *p = ival;
+        if ((size_t)bytes > sizeof(unsigned long)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                RETURN_ERR_OCCURRED;
+            }
+        }
         break;
     }
 
@@ -864,15 +899,23 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
     case 'K': { /* long long sized bitfield */
         unsigned long long *p = va_arg(*p_va, unsigned long long *);
         HANDLE_NULLABLE;
-        unsigned long long ival;
         if (!PyIndex_Check(arg)) {
             return converterr(nullable, "int", arg, msgbuf, bufsize);
         }
-        ival = PyLong_AsUnsignedLongLongMask(arg);
-        if (ival == (unsigned long long)(long long)-1 && PyErr_Occurred()) {
+        Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned long long),
+                Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                Py_ASNATIVEBYTES_ALLOW_INDEX |
+                Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+        if (bytes < 0) {
             RETURN_ERR_OCCURRED;
         }
-        *p = ival;
+        if ((size_t)bytes > sizeof(unsigned long long)) {
+            if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                "integer value out of range", 1) < 0)
+            {
+                RETURN_ERR_OCCURRED;
+            }
+        }
         break;
     }
 
index 39d0ac557a60f5660d5a4dba57c9912cc2bc9c5c..6e89e8de7cccf1c51c23885493bd7b9764760aae 100644 (file)
@@ -18,6 +18,7 @@ TypeSet = set[bltns.type[object]]
 
 
 class BaseUnsignedIntConverter(CConverter):
+    bitwise = False
 
     def use_converter(self) -> None:
         if self.converter:
@@ -25,6 +26,38 @@ class BaseUnsignedIntConverter(CConverter):
                              f'{self.converter}()')
 
     def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
+        if self.bitwise:
+            result = self.format_code("""
+                {{{{
+                    Py_ssize_t _bytes = PyLong_AsNativeBytes({argname}, &{paramname}, sizeof({type}),
+                            Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+                            Py_ASNATIVEBYTES_ALLOW_INDEX |
+                            Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+                    if (_bytes < 0) {{{{
+                        goto exit;
+                    }}}}
+                    if ((size_t)_bytes > sizeof({type})) {{{{
+                        if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                            "integer value out of range", 1) < 0)
+                        {{{{
+                            goto exit;
+                        }}}}
+                    }}}}
+                }}}}
+                """,
+                argname=argname,
+                type=self.type,
+                bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi))
+            if self.format_unit in ('k', 'K'):
+                result = self.format_code("""
+                if (!PyIndex_Check({argname})) {{{{
+                    {bad_argument}
+                    goto exit;
+                }}}}""",
+                    argname=argname,
+                    bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi)) + result
+            return result
+
         if not limited_capi:
             return super().parse_arg(argname, displayname, limited_capi=limited_capi)
         return self.format_code("""
@@ -172,13 +205,14 @@ class char_converter(CConverter):
 
 
 @add_legacy_c_converter('B', bitwise=True)
-class unsigned_char_converter(CConverter):
+class unsigned_char_converter(BaseUnsignedIntConverter):
     type = 'unsigned char'
     default_type = int
     format_unit = 'b'
     c_ignored_default = "'\0'"
 
     def converter_init(self, *, bitwise: bool = False) -> None:
+        self.bitwise = bitwise
         if bitwise:
             self.format_unit = 'B'
 
@@ -206,19 +240,6 @@ class unsigned_char_converter(CConverter):
                 }}}}
                 """,
                 argname=argname)
-        elif self.format_unit == 'B':
-            return self.format_code("""
-                {{{{
-                    unsigned long ival = PyLong_AsUnsignedLongMask({argname});
-                    if (ival == (unsigned long)-1 && PyErr_Occurred()) {{{{
-                        goto exit;
-                    }}}}
-                    else {{{{
-                        {paramname} = (unsigned char) ival;
-                    }}}}
-                }}}}
-                """,
-                argname=argname)
         return super().parse_arg(argname, displayname, limited_capi=limited_capi)
 
 
@@ -265,22 +286,12 @@ class unsigned_short_converter(BaseUnsignedIntConverter):
     c_ignored_default = "0"
 
     def converter_init(self, *, bitwise: bool = False) -> None:
+        self.bitwise = bitwise
         if bitwise:
             self.format_unit = 'H'
         else:
             self.converter = '_PyLong_UnsignedShort_Converter'
 
-    def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
-        if self.format_unit == 'H':
-            return self.format_code("""
-                {paramname} = (unsigned short)PyLong_AsUnsignedLongMask({argname});
-                if ({paramname} == (unsigned short)-1 && PyErr_Occurred()) {{{{
-                    goto exit;
-                }}}}
-                """,
-                argname=argname)
-        return super().parse_arg(argname, displayname, limited_capi=limited_capi)
-
 
 @add_legacy_c_converter('C', accept={str})
 class int_converter(CConverter):
@@ -336,22 +347,12 @@ class unsigned_int_converter(BaseUnsignedIntConverter):
     c_ignored_default = "0"
 
     def converter_init(self, *, bitwise: bool = False) -> None:
+        self.bitwise = bitwise
         if bitwise:
             self.format_unit = 'I'
         else:
             self.converter = '_PyLong_UnsignedInt_Converter'
 
-    def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
-        if self.format_unit == 'I':
-            return self.format_code("""
-                {paramname} = (unsigned int)PyLong_AsUnsignedLongMask({argname});
-                if ({paramname} == (unsigned int)-1 && PyErr_Occurred()) {{{{
-                    goto exit;
-                }}}}
-                """,
-                argname=argname)
-        return super().parse_arg(argname, displayname, limited_capi=limited_capi)
-
 
 class long_converter(CConverter):
     type = 'long'
@@ -377,25 +378,12 @@ class unsigned_long_converter(BaseUnsignedIntConverter):
     c_ignored_default = "0"
 
     def converter_init(self, *, bitwise: bool = False) -> None:
+        self.bitwise = bitwise
         if bitwise:
             self.format_unit = 'k'
         else:
             self.converter = '_PyLong_UnsignedLong_Converter'
 
-    def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
-        if self.format_unit == 'k':
-            return self.format_code("""
-                if (!PyIndex_Check({argname})) {{{{
-                    {bad_argument}
-                    goto exit;
-                }}}}
-                {paramname} = PyLong_AsUnsignedLongMask({argname});
-                """,
-                argname=argname,
-                bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi),
-            )
-        return super().parse_arg(argname, displayname, limited_capi=limited_capi)
-
 
 class long_long_converter(CConverter):
     type = 'long long'
@@ -421,25 +409,12 @@ class unsigned_long_long_converter(BaseUnsignedIntConverter):
     c_ignored_default = "0"
 
     def converter_init(self, *, bitwise: bool = False) -> None:
+        self.bitwise = bitwise
         if bitwise:
             self.format_unit = 'K'
         else:
             self.converter = '_PyLong_UnsignedLongLong_Converter'
 
-    def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
-        if self.format_unit == 'K':
-            return self.format_code("""
-                if (!PyIndex_Check({argname})) {{{{
-                    {bad_argument}
-                    goto exit;
-                }}}}
-                {paramname} = PyLong_AsUnsignedLongLongMask({argname});
-                """,
-                argname=argname,
-                bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi),
-            )
-        return super().parse_arg(argname, displayname, limited_capi=limited_capi)
-
 
 class Py_ssize_t_converter(CConverter):
     type = 'Py_ssize_t'