https://github.com/python/cpython/commit/e18829a8adb3a64ffffffbd7dcada3c3611522b0
commit: e18829a8adb3a64ffffffbd7dcada3c3611522b0
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-07-13T12:44:54+03:00
summary:
gh-132629: Deprecate accepting out-of-range values for unsigned integers in
PyArg_Parse (GH-132630)
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.
files:
A Misc/NEWS.d/next/C_API/2025-04-17-12-37-27.gh-issue-132629.01ArwX.rst
M Doc/c-api/arg.rst
M Doc/whatsnew/3.15.rst
M Lib/test/clinic.test.c
M Lib/test/test_capi/test_getargs.py
M Lib/test/test_clinic.py
M Modules/clinic/_cursesmodule.c.h
M Modules/clinic/_testclinic.c.h
M Modules/clinic/_zoneinfo.c.h
M Modules/clinic/binascii.c.h
M Modules/clinic/fcntlmodule.c.h
M Modules/clinic/posixmodule.c.h
M Modules/clinic/selectmodule.c.h
M Modules/clinic/signalmodule.c.h
M Modules/clinic/zlibmodule.c.h
M Modules/fcntlmodule.c
M PC/clinic/msvcrtmodule.c.h
M Python/getargs.c
M Tools/clinic/libclinic/converters.py
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index ab9f9c4539ae9a..803572afc39ae3 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -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
-------------
diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst
index 010abb7d9b9278..2f713fbb888c30 100644
--- a/Doc/whatsnew/3.15.rst
+++ b/Doc/whatsnew/3.15.rst
@@ -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.
diff --git a/Lib/test/clinic.test.c b/Lib/test/clinic.test.c
index 4a67fcd2c3e9b3..dc5b4b27a07f99 100644
--- a/Lib/test/clinic.test.c
+++ b/Lib/test/clinic.test.c
@@ -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 @@ test_unsigned_char_converter(PyObject *module, PyObject
*const *args, Py_ssize_t
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 @@ test_unsigned_short_converter(PyObject *module, PyObject
*const *args, Py_ssize_
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 @@ test_unsigned_int_converter(PyObject *module, PyObject
*const *args, Py_ssize_t
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 @@ test_unsigned_long_converter(PyObject *module, PyObject
*const *args, Py_ssize_t
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]
diff --git a/Lib/test/test_capi/test_getargs.py
b/Lib/test/test_capi/test_getargs.py
index 67a8da7599511f..dc2000089684a6 100644
--- a/Lib/test/test_capi/test_getargs.py
+++ b/Lib/test/test_capi/test_getargs.py
@@ -48,8 +48,8 @@
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 @@
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 @@ def test_B(self):
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 @@ def test_H(self):
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 @@ def test_I(self):
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 @@ def test_k(self):
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 @@ def test_K(self):
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):
diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py
index 580d54e0eb094d..a6ed887999242f 100644
--- a/Lib/test/test_clinic.py
+++ b/Lib/test/test_clinic.py
@@ -3048,6 +3048,8 @@ def test_char_converter(self):
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 @@ def test_unsigned_char_converter(self):
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 @@ def test_short_converter(self):
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 @@ def test_unsigned_short_converter(self):
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 @@ def test_int_converter(self):
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 @@ def test_unsigned_int_converter(self):
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 @@ def test_long_converter(self):
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 @@ def test_unsigned_long_converter(self):
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 @@ def test_long_long_converter(self):
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 @@ def test_unsigned_long_long_converter(self):
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
index 00000000000000..38b7a0a493e39f
--- /dev/null
+++ b/Misc/NEWS.d/next/C_API/2025-04-17-12-37-27.gh-issue-132629.01ArwX.rst
@@ -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.
diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h
index 49c864318c8aa8..a8c32d6510604a 100644
--- a/Modules/clinic/_cursesmodule.c.h
+++ b/Modules/clinic/_cursesmodule.c.h
@@ -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]*/
diff --git a/Modules/clinic/_testclinic.c.h b/Modules/clinic/_testclinic.c.h
index 970528ce9ea46d..68c92a86226bc9 100644
--- a/Modules/clinic/_testclinic.c.h
+++ b/Modules/clinic/_testclinic.c.h
@@ -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]*/
diff --git a/Modules/clinic/_zoneinfo.c.h b/Modules/clinic/_zoneinfo.c.h
index 09ac157cbfd135..19564a6c13f246 100644
--- a/Modules/clinic/_zoneinfo.c.h
+++ b/Modules/clinic/_zoneinfo.c.h
@@ -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]*/
diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h
index 602e42a4c1aaa4..ce29e0d11a45cd 100644
--- a/Modules/clinic/binascii.c.h
+++ b/Modules/clinic/binascii.c.h
@@ -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 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args,
Py_ssize_t nargs, PyObj
return return_value;
}
-/*[clinic end generated code: output=adb855a2797c3cad input=a9049054013a1b77]*/
+/*[clinic end generated code: output=fba6a71e0d7d092f input=a9049054013a1b77]*/
diff --git a/Modules/clinic/fcntlmodule.c.h b/Modules/clinic/fcntlmodule.c.h
index 00a929064ba700..005e9b9e12afd9 100644
--- a/Modules/clinic/fcntlmodule.c.h
+++ b/Modules/clinic/fcntlmodule.c.h
@@ -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 @@ fcntl_lockf(PyObject *module, PyObject *const *args,
Py_ssize_t nargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=65a16bc64c7b4de4 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=bf84289b741e7cf6 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h
index 3621a0625411d3..22f426c5192bf2 100644
--- a/Modules/clinic/posixmodule.c.h
+++ b/Modules/clinic/posixmodule.c.h
@@ -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]*/
diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h
index 253ad8c9e78f00..c0a5f678ad038d 100644
--- a/Modules/clinic/selectmodule.c.h
+++ b/Modules/clinic/selectmodule.c.h
@@ -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 @@ select_kqueue_control(PyObject *self, PyObject *const
*args, Py_ssize_t nargs)
#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]*/
diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h
index 955861b4da37d9..b0cd9e2e561640 100644
--- a/Modules/clinic/signalmodule.c.h
+++ b/Modules/clinic/signalmodule.c.h
@@ -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 @@ signal_pidfd_send_signal(PyObject *module, PyObject *const
*args, Py_ssize_t nar
#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]*/
diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h
index 146a7e250019f0..016af258d63dea 100644
--- a/Modules/clinic/zlibmodule.c.h
+++ b/Modules/clinic/zlibmodule.c.h
@@ -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 @@ zlib_crc32_combine(PyObject *module, PyObject *const
*args, Py_ssize_t nargs)
#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]*/
diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c
index 90363b9dca3316..524eb54b984ca8 100644
--- a/Modules/fcntlmodule.c
+++ b/Modules/fcntlmodule.c
@@ -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"
diff --git a/PC/clinic/msvcrtmodule.c.h b/PC/clinic/msvcrtmodule.c.h
index a77d0855af293f..647aadfa46bbed 100644
--- a/PC/clinic/msvcrtmodule.c.h
+++ b/PC/clinic/msvcrtmodule.c.h
@@ -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 @@ msvcrt_SetErrorMode(PyObject *module, PyObject *arg)
#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]*/
diff --git a/Python/getargs.c b/Python/getargs.c
index 0cf596285cc7b5..02f5c0e37ee42a 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -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;
}
diff --git a/Tools/clinic/libclinic/converters.py
b/Tools/clinic/libclinic/converters.py
index 39d0ac557a60f5..6e89e8de7cccf1 100644
--- a/Tools/clinic/libclinic/converters.py
+++ b/Tools/clinic/libclinic/converters.py
@@ -18,6 +18,7 @@
class BaseUnsignedIntConverter(CConverter):
+ bitwise = False
def use_converter(self) -> None:
if self.converter:
@@ -25,6 +26,38 @@ def use_converter(self) -> None:
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 @@ def parse_arg(self, argname: str, displayname: str, *,
limited_capi: bool) -> st
@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 @@ def parse_arg(self, argname: str, displayname: str, *,
limited_capi: bool) -> st
}}}}
""",
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'
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]