Skip to content

Commit 7ef6700

Browse files
authored
Merge branch 'python:main' into fix-issue-108202
2 parents 2aabadf + ddf66b5 commit 7ef6700

File tree

117 files changed

+782
-544
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+782
-544
lines changed

.github/workflows/mypy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ on:
99
paths:
1010
- "Tools/clinic/**"
1111
- "Tools/cases_generator/**"
12+
- "Tools/requirements-dev.txt"
1213
- ".github/workflows/mypy.yml"
1314
workflow_dispatch:
1415

Doc/c-api/long.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
136136
This function will no longer use :meth:`~object.__int__`.
137137
138138
139+
.. c:function:: int PyLong_AsInt(PyObject *obj)
140+
141+
Similar to :c:func:`PyLong_AsLong`, but store the result in a C
142+
:c:expr:`int` instead of a C :c:expr:`long`.
143+
144+
.. versionadded:: 3.13
145+
146+
139147
.. c:function:: long PyLong_AsLongAndOverflow(PyObject *obj, int *overflow)
140148
141149
Return a C :c:expr:`long` representation of *obj*. If *obj* is not an

Doc/data/stable_abi.dat

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Doc/whatsnew/3.13.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,12 @@ New Features
871871
:term:`shutting down <interpreter shutdown>`.
872872
(Contributed by Victor Stinner in :gh:`108014`.)
873873

874+
* Add :c:func:`PyLong_AsInt` function: similar to :c:func:`PyLong_AsLong`, but
875+
store the result in a C :c:expr:`int` instead of a C :c:expr:`long`.
876+
Previously, it was known as the private function :c:func:`!_PyLong_AsInt`
877+
(with an underscore prefix).
878+
(Contributed by Victor Stinner in :gh:`108014`.)
879+
874880
Porting to Python 3.13
875881
----------------------
876882

Include/cpython/longobject.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
# error "this header file must not be included directly"
33
#endif
44

5-
PyAPI_FUNC(int) _PyLong_AsInt(PyObject *);
5+
// Alias for backport compatibility
6+
#define _PyLong_AsInt PyLong_AsInt
67

78
PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *);
89
PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *);

Include/cpython/traceback.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,3 @@ struct _traceback {
1111
int tb_lasti;
1212
int tb_lineno;
1313
};
14-
15-
PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int, int *, PyObject **);
16-
PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int);

Include/internal/pycore_opcode_metadata.h

Lines changed: 27 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_traceback.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ extern "C" {
88
# error "this header requires Py_BUILD_CORE define"
99
#endif
1010

11+
// Export for '_ctypes' shared extension
12+
PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int, int *, PyObject **);
13+
14+
// Export for 'pyexact' shared extension
15+
PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int);
16+
1117
/* Write the Python traceback into the file 'fd'. For example:
1218
1319
Traceback (most recent call first):

Include/longobject.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,18 @@ PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long);
1818
PyAPI_FUNC(PyObject *) PyLong_FromSize_t(size_t);
1919
PyAPI_FUNC(PyObject *) PyLong_FromSsize_t(Py_ssize_t);
2020
PyAPI_FUNC(PyObject *) PyLong_FromDouble(double);
21+
2122
PyAPI_FUNC(long) PyLong_AsLong(PyObject *);
2223
PyAPI_FUNC(long) PyLong_AsLongAndOverflow(PyObject *, int *);
2324
PyAPI_FUNC(Py_ssize_t) PyLong_AsSsize_t(PyObject *);
2425
PyAPI_FUNC(size_t) PyLong_AsSize_t(PyObject *);
2526
PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *);
2627
PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *);
28+
29+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000
30+
PyAPI_FUNC(int) PyLong_AsInt(PyObject *);
31+
#endif
32+
2733
PyAPI_FUNC(PyObject *) PyLong_GetInfo(void);
2834

2935
/* It may be useful in the future. I've added it in the PyInt -> PyLong

Lib/test/clinic.test.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ test_bool_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
473473
if (nargs < 3) {
474474
goto skip_optional;
475475
}
476-
c = _PyLong_AsInt(args[2]);
476+
c = PyLong_AsInt(args[2]);
477477
if (c == -1 && PyErr_Occurred()) {
478478
goto exit;
479479
}
@@ -486,7 +486,7 @@ test_bool_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
486486

487487
static PyObject *
488488
test_bool_converter_impl(PyObject *module, int a, int b, int c)
489-
/*[clinic end generated code: output=27f0e653a70b9be3 input=939854fa9f248c60]*/
489+
/*[clinic end generated code: output=3190e46490de0644 input=939854fa9f248c60]*/
490490

491491

492492
/*[clinic input]
@@ -1009,14 +1009,14 @@ test_int_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
10091009
if (nargs < 1) {
10101010
goto skip_optional;
10111011
}
1012-
a = _PyLong_AsInt(args[0]);
1012+
a = PyLong_AsInt(args[0]);
10131013
if (a == -1 && PyErr_Occurred()) {
10141014
goto exit;
10151015
}
10161016
if (nargs < 2) {
10171017
goto skip_optional;
10181018
}
1019-
b = _PyLong_AsInt(args[1]);
1019+
b = PyLong_AsInt(args[1]);
10201020
if (b == -1 && PyErr_Occurred()) {
10211021
goto exit;
10221022
}
@@ -1035,7 +1035,7 @@ test_int_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
10351035
if (nargs < 4) {
10361036
goto skip_optional;
10371037
}
1038-
d = _PyLong_AsInt(args[3]);
1038+
d = PyLong_AsInt(args[3]);
10391039
if (d == -1 && PyErr_Occurred()) {
10401040
goto exit;
10411041
}
@@ -1048,7 +1048,7 @@ test_int_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
10481048

10491049
static PyObject *
10501050
test_int_converter_impl(PyObject *module, int a, int b, int c, myenum d)
1051-
/*[clinic end generated code: output=375eedba5ca9a5b3 input=d20541fc1ca0553e]*/
1051+
/*[clinic end generated code: output=5aed87a7589eefb2 input=d20541fc1ca0553e]*/
10521052

10531053

10541054
/*[clinic input]
@@ -4509,7 +4509,7 @@ Test_cls_with_param(TestObj *self, PyTypeObject *cls, PyObject *const *args, Py_
45094509
if (!args) {
45104510
goto exit;
45114511
}
4512-
a = _PyLong_AsInt(args[0]);
4512+
a = PyLong_AsInt(args[0]);
45134513
if (a == -1 && PyErr_Occurred()) {
45144514
goto exit;
45154515
}
@@ -4521,7 +4521,7 @@ Test_cls_with_param(TestObj *self, PyTypeObject *cls, PyObject *const *args, Py_
45214521

45224522
static PyObject *
45234523
Test_cls_with_param_impl(TestObj *self, PyTypeObject *cls, int a)
4524-
/*[clinic end generated code: output=00218e7f583e6c81 input=af158077bd237ef9]*/
4524+
/*[clinic end generated code: output=d89b99e83d442be0 input=af158077bd237ef9]*/
45254525

45264526

45274527
/*[clinic input]
@@ -4703,7 +4703,7 @@ Test_an_metho_arg_named_arg(TestObj *self, PyObject *arg_)
47034703
PyObject *return_value = NULL;
47044704
int arg;
47054705

4706-
arg = _PyLong_AsInt(arg_);
4706+
arg = PyLong_AsInt(arg_);
47074707
if (arg == -1 && PyErr_Occurred()) {
47084708
goto exit;
47094709
}
@@ -4715,7 +4715,7 @@ Test_an_metho_arg_named_arg(TestObj *self, PyObject *arg_)
47154715

47164716
static PyObject *
47174717
Test_an_metho_arg_named_arg_impl(TestObj *self, int arg)
4718-
/*[clinic end generated code: output=7d590626642194ae input=2a53a57cf5624f95]*/
4718+
/*[clinic end generated code: output=9f04de4a62287e28 input=2a53a57cf5624f95]*/
47194719

47204720

47214721
/*[clinic input]
@@ -5062,7 +5062,7 @@ mangled_c_keyword_identifier(PyObject *module, PyObject *const *args, Py_ssize_t
50625062
if (!args) {
50635063
goto exit;
50645064
}
5065-
int_value = _PyLong_AsInt(args[0]);
5065+
int_value = PyLong_AsInt(args[0]);
50665066
if (int_value == -1 && PyErr_Occurred()) {
50675067
goto exit;
50685068
}
@@ -5074,7 +5074,7 @@ mangled_c_keyword_identifier(PyObject *module, PyObject *const *args, Py_ssize_t
50745074

50755075
static PyObject *
50765076
mangled_c_keyword_identifier_impl(PyObject *module, int int_value)
5077-
/*[clinic end generated code: output=c049d7d79be26cda input=060876448ab567a2]*/
5077+
/*[clinic end generated code: output=f24b37e0368e0eb8 input=060876448ab567a2]*/
50785078

50795079

50805080
/*[clinic input]

Lib/test/test_capi/test_long.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,36 @@ def test_compact_known(self):
3434
self.assertEqual(_testcapi.call_long_compact_api(sys.maxsize),
3535
(False, -1))
3636

37+
def test_long_asint(self):
38+
PyLong_AsInt = _testcapi.PyLong_AsInt
39+
INT_MIN = _testcapi.INT_MIN
40+
INT_MAX = _testcapi.INT_MAX
41+
42+
# round trip (object -> int -> object)
43+
for value in (INT_MIN, INT_MAX, -1, 0, 1, 123):
44+
with self.subTest(value=value):
45+
self.assertEqual(PyLong_AsInt(value), value)
46+
47+
# use __index__(), not __int__()
48+
class MyIndex:
49+
def __index__(self):
50+
return 10
51+
def __int__(self):
52+
return 22
53+
self.assertEqual(PyLong_AsInt(MyIndex()), 10)
54+
55+
# bound checking
56+
with self.assertRaises(OverflowError):
57+
PyLong_AsInt(INT_MIN - 1)
58+
with self.assertRaises(OverflowError):
59+
PyLong_AsInt(INT_MAX + 1)
60+
61+
# invalid type
62+
for value in (1.0, b'2', '3'):
63+
with self.subTest(value=value):
64+
with self.assertRaises(TypeError):
65+
PyLong_AsInt(value)
66+
3767

3868
if __name__ == "__main__":
3969
unittest.main()

Lib/test/test_clinic.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2463,11 +2463,12 @@ def test_cli_force(self):
24632463
# Verify by checking the checksum.
24642464
checksum = (
24652465
"/*[clinic end generated code: "
2466-
"output=2124c291eb067d76 input=9543a8d2da235301]*/\n"
2466+
"output=c16447c01510dfb3 input=9543a8d2da235301]*/\n"
24672467
)
24682468
with open(fn, 'r', encoding='utf-8') as f:
24692469
generated = f.read()
2470-
self.assertTrue(generated.endswith(checksum))
2470+
self.assertTrue(generated.endswith(checksum),
2471+
(generated, checksum))
24712472

24722473
def test_cli_make(self):
24732474
c_code = dedent("""

Lib/test/test_stable_abi_ctypes.py

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Add :c:func:`PyLong_AsInt` function: similar to :c:func:`PyLong_AsLong`, but
2+
store the result in a C :c:expr:`int` instead of a C :c:expr:`long`.
3+
Previously, it was known as the the private function :c:func:`!_PyLong_AsInt`
4+
(with an underscore prefix). Patch by Victor Stinner.

Misc/stable_abi.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2450,3 +2450,5 @@
24502450
added = '3.13'
24512451
[function.PyDict_GetItemStringRef]
24522452
added = '3.13'
2453+
[function.PyLong_AsInt]
2454+
added = '3.13'

0 commit comments

Comments
 (0)