Skip to content

Commit 5c9a63f

Browse files
authored
gh-128863: Deprecate _PyLong_New() function (#129212)
1 parent e579cdb commit 5c9a63f

File tree

5 files changed

+47
-38
lines changed

5 files changed

+47
-38
lines changed

Doc/deprecations/c-api-pending-removal-in-3.18.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Pending removal in Python 3.18
77
* :c:func:`!_PyDict_GetItemStringWithError`: use :c:func:`PyDict_GetItemStringRef`.
88
* :c:func:`!_PyDict_Pop()`: :c:func:`PyDict_Pop`.
99
* :c:func:`!_PyLong_Sign()`: use :c:func:`PyLong_GetSign`.
10+
* :c:func:`!_PyLong_New`: use :c:func:`PyLongWriter_Create`.
1011
* :c:func:`!_PyThreadState_UncheckedGet`: use :c:func:`PyThreadState_GetUnchecked`.
1112
* :c:func:`!_PyUnicode_AsString`: use :c:func:`PyUnicode_AsUTF8`.
1213
* :c:func:`!_Py_HashPointer`: use :c:func:`Py_HashPointer`.

Doc/whatsnew/3.14.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,7 @@ Deprecated
13961396
* :c:func:`!_PyDict_GetItemStringWithError`: use :c:func:`PyDict_GetItemStringRef`.
13971397
* :c:func:`!_PyDict_Pop()`: use :c:func:`PyDict_Pop`.
13981398
* :c:func:`!_PyLong_Sign()`: use :c:func:`PyLong_GetSign`.
1399+
* :c:func:`!_PyLong_New`: use :c:func:`PyLongWriter_Create`.
13991400
* :c:func:`!_PyThreadState_UncheckedGet`: use :c:func:`PyThreadState_GetUnchecked`.
14001401
* :c:func:`!_PyUnicode_AsString`: use :c:func:`PyUnicode_AsUTF8`.
14011402
* :c:func:`!_Py_HashPointer`: use :c:func:`Py_HashPointer`.

Include/cpython/longintrepr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ struct _longobject {
100100
_PyLongValue long_value;
101101
};
102102

103-
PyAPI_FUNC(PyLongObject*) _PyLong_New(Py_ssize_t);
103+
Py_DEPRECATED(3.14) PyAPI_FUNC(PyLongObject*) _PyLong_New(Py_ssize_t);
104104

105105
// Return a copy of src.
106106
PyAPI_FUNC(PyObject*) _PyLong_Copy(PyLongObject *src);

Misc/NEWS.d/next/C_API/2025-01-15-11-42-07.gh-issue-128863.C9MkB_.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Python 3.18:
55
* :c:func:`!_PyDict_GetItemStringWithError`: use :c:func:`PyDict_GetItemStringRef`.
66
* :c:func:`!_PyDict_Pop()`: use :c:func:`PyDict_Pop`.
77
* :c:func:`!_PyLong_Sign()`: use :c:func:`PyLong_GetSign`.
8+
* :c:func:`!_PyLong_New`: use :c:func:`PyLongWriter_Create`.
89
* :c:func:`!_PyThreadState_UncheckedGet`: use :c:func:`PyThreadState_GetUnchecked`.
910
* :c:func:`!_PyUnicode_AsString`: use :c:func:`PyUnicode_AsUTF8`.
1011
* :c:func:`!_Py_HashPointer`: use :c:func:`Py_HashPointer`.

Objects/longobject.c

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ long_normalize(PyLongObject *v)
152152
# define MAX_LONG_DIGITS ((INT64_MAX-1) / PyLong_SHIFT)
153153
#endif
154154

155-
PyLongObject *
156-
_PyLong_New(Py_ssize_t size)
155+
static PyLongObject *
156+
long_alloc(Py_ssize_t size)
157157
{
158158
assert(size >= 0);
159159
PyLongObject *result = NULL;
@@ -190,14 +190,20 @@ _PyLong_New(Py_ssize_t size)
190190
return result;
191191
}
192192

193+
PyLongObject *
194+
_PyLong_New(Py_ssize_t size)
195+
{
196+
return long_alloc(size);
197+
}
198+
193199
PyLongObject *
194200
_PyLong_FromDigits(int negative, Py_ssize_t digit_count, digit *digits)
195201
{
196202
assert(digit_count >= 0);
197203
if (digit_count == 0) {
198204
return (PyLongObject *)_PyLong_GetZero();
199205
}
200-
PyLongObject *result = _PyLong_New(digit_count);
206+
PyLongObject *result = long_alloc(digit_count);
201207
if (result == NULL) {
202208
PyErr_NoMemory();
203209
return NULL;
@@ -268,7 +274,7 @@ _PyLong_FromLarge(stwodigits ival)
268274
++ndigits;
269275
t >>= PyLong_SHIFT;
270276
}
271-
PyLongObject *v = _PyLong_New(ndigits);
277+
PyLongObject *v = long_alloc(ndigits);
272278
if (v != NULL) {
273279
digit *p = v->long_value.ob_digit;
274280
_PyLong_SetSignAndDigitCount(v, sign, ndigits);
@@ -341,7 +347,7 @@ PyLong_FromLong(long ival)
341347
}
342348

343349
/* Construct output value. */
344-
v = _PyLong_New(ndigits);
350+
v = long_alloc(ndigits);
345351
if (v != NULL) {
346352
digit *p = v->long_value.ob_digit;
347353
_PyLong_SetSignAndDigitCount(v, ival < 0 ? -1 : 1, ndigits);
@@ -366,7 +372,7 @@ PyLong_FromLong(long ival)
366372
++ndigits; \
367373
t >>= PyLong_SHIFT; \
368374
} \
369-
PyLongObject *v = _PyLong_New(ndigits); \
375+
PyLongObject *v = long_alloc(ndigits); \
370376
if (v == NULL) { \
371377
return NULL; \
372378
} \
@@ -443,7 +449,7 @@ PyLong_FromDouble(double dval)
443449
frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
444450
assert(expo > 0);
445451
ndig = (expo-1) / PyLong_SHIFT + 1; /* Number of 'digits' in result */
446-
v = _PyLong_New(ndig);
452+
v = long_alloc(ndig);
447453
if (v == NULL)
448454
return NULL;
449455
frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1);
@@ -952,7 +958,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n,
952958
return NULL;
953959
}
954960
ndigits = (numsignificantbytes * 8 + PyLong_SHIFT - 1) / PyLong_SHIFT;
955-
v = _PyLong_New(ndigits);
961+
v = long_alloc(ndigits);
956962
if (v == NULL)
957963
return NULL;
958964

@@ -1482,7 +1488,7 @@ PyLong_FromLongLong(long long ival)
14821488
}
14831489

14841490
/* Construct output value. */
1485-
v = _PyLong_New(ndigits);
1491+
v = long_alloc(ndigits);
14861492
if (v != NULL) {
14871493
digit *p = v->long_value.ob_digit;
14881494
_PyLong_SetSignAndDigitCount(v, ival < 0 ? -1 : 1, ndigits);
@@ -1525,7 +1531,7 @@ PyLong_FromSsize_t(Py_ssize_t ival)
15251531
++ndigits;
15261532
t >>= PyLong_SHIFT;
15271533
}
1528-
v = _PyLong_New(ndigits);
1534+
v = long_alloc(ndigits);
15291535
if (v != NULL) {
15301536
digit *p = v->long_value.ob_digit;
15311537
_PyLong_SetSignAndDigitCount(v, negative ? -1 : 1, ndigits);
@@ -2015,7 +2021,7 @@ divrem1(PyLongObject *a, digit n, digit *prem)
20152021
PyLongObject *z;
20162022

20172023
assert(n > 0 && n <= PyLong_MASK);
2018-
z = _PyLong_New(size);
2024+
z = long_alloc(size);
20192025
if (z == NULL)
20202026
return NULL;
20212027
*prem = inplace_divrem1(z->long_value.ob_digit, a->long_value.ob_digit, size, n);
@@ -2192,7 +2198,7 @@ long_to_decimal_string_internal(PyObject *aa,
21922198
(10 * PyLong_SHIFT - 33 * _PyLong_DECIMAL_SHIFT);
21932199
assert(size_a < PY_SSIZE_T_MAX/2);
21942200
size = 1 + size_a + size_a / d;
2195-
scratch = _PyLong_New(size);
2201+
scratch = long_alloc(size);
21962202
if (scratch == NULL)
21972203
return -1;
21982204

@@ -2635,7 +2641,7 @@ long_from_binary_base(const char *start, const char *end, Py_ssize_t digits, int
26352641
return 0;
26362642
}
26372643
n = (digits * bits_per_char + PyLong_SHIFT - 1) / PyLong_SHIFT;
2638-
z = _PyLong_New(n);
2644+
z = long_alloc(n);
26392645
if (z == NULL) {
26402646
*res = NULL;
26412647
return 0;
@@ -2839,7 +2845,7 @@ long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits,
28392845
*/
28402846
double fsize_z = (double)digits * log_base_BASE[base] + 1.0;
28412847
if (fsize_z > (double)MAX_LONG_DIGITS) {
2842-
/* The same exception as in _PyLong_New(). */
2848+
/* The same exception as in long_alloc(). */
28432849
PyErr_SetString(PyExc_OverflowError,
28442850
"too many digits in integer");
28452851
*res = NULL;
@@ -2849,7 +2855,7 @@ long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits,
28492855
/* Uncomment next line to test exceedingly rare copy code */
28502856
/* size_z = 1; */
28512857
assert(size_z > 0);
2852-
z = _PyLong_New(size_z);
2858+
z = long_alloc(size_z);
28532859
if (z == NULL) {
28542860
*res = NULL;
28552861
return 0;
@@ -2912,7 +2918,7 @@ long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits,
29122918
PyLongObject *tmp;
29132919
/* Extremely rare. Get more space. */
29142920
assert(_PyLong_DigitCount(z) == size_z);
2915-
tmp = _PyLong_New(size_z + 1);
2921+
tmp = long_alloc(size_z + 1);
29162922
if (tmp == NULL) {
29172923
Py_DECREF(z);
29182924
*res = NULL;
@@ -3333,12 +3339,12 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
33333339
size_v = _PyLong_DigitCount(v1);
33343340
size_w = _PyLong_DigitCount(w1);
33353341
assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */
3336-
v = _PyLong_New(size_v+1);
3342+
v = long_alloc(size_v+1);
33373343
if (v == NULL) {
33383344
*prem = NULL;
33393345
return NULL;
33403346
}
3341-
w = _PyLong_New(size_w);
3347+
w = long_alloc(size_w);
33423348
if (w == NULL) {
33433349
Py_DECREF(v);
33443350
*prem = NULL;
@@ -3360,7 +3366,7 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
33603366
at most (and usually exactly) k = size_v - size_w digits. */
33613367
k = size_v - size_w;
33623368
assert(k >= 0);
3363-
a = _PyLong_New(k);
3369+
a = long_alloc(k);
33643370
if (a == NULL) {
33653371
Py_DECREF(w);
33663372
Py_DECREF(v);
@@ -3758,7 +3764,7 @@ x_add(PyLongObject *a, PyLongObject *b)
37583764
size_a = size_b;
37593765
size_b = size_temp; }
37603766
}
3761-
z = _PyLong_New(size_a+1);
3767+
z = long_alloc(size_a+1);
37623768
if (z == NULL)
37633769
return NULL;
37643770
for (i = 0; i < size_b; ++i) {
@@ -3807,7 +3813,7 @@ x_sub(PyLongObject *a, PyLongObject *b)
38073813
}
38083814
size_a = size_b = i+1;
38093815
}
3810-
z = _PyLong_New(size_a);
3816+
z = long_alloc(size_a);
38113817
if (z == NULL)
38123818
return NULL;
38133819
for (i = 0; i < size_b; ++i) {
@@ -3932,7 +3938,7 @@ x_mul(PyLongObject *a, PyLongObject *b)
39323938
Py_ssize_t size_b = _PyLong_DigitCount(b);
39333939
Py_ssize_t i;
39343940

3935-
z = _PyLong_New(size_a + size_b);
3941+
z = long_alloc(size_a + size_b);
39363942
if (z == NULL)
39373943
return NULL;
39383944

@@ -4042,9 +4048,9 @@ kmul_split(PyLongObject *n,
40424048
size_lo = Py_MIN(size_n, size);
40434049
size_hi = size_n - size_lo;
40444050

4045-
if ((hi = _PyLong_New(size_hi)) == NULL)
4051+
if ((hi = long_alloc(size_hi)) == NULL)
40464052
return -1;
4047-
if ((lo = _PyLong_New(size_lo)) == NULL) {
4053+
if ((lo = long_alloc(size_lo)) == NULL) {
40484054
Py_DECREF(hi);
40494055
return -1;
40504056
}
@@ -4144,7 +4150,7 @@ k_mul(PyLongObject *a, PyLongObject *b)
41444150
*/
41454151

41464152
/* 1. Allocate result space. */
4147-
ret = _PyLong_New(asize + bsize);
4153+
ret = long_alloc(asize + bsize);
41484154
if (ret == NULL) goto fail;
41494155
#ifdef Py_DEBUG
41504156
/* Fill with trash, to catch reference to uninitialized digits. */
@@ -4294,13 +4300,13 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b)
42944300
assert(2 * asize <= bsize);
42954301

42964302
/* Allocate result space, and zero it out. */
4297-
ret = _PyLong_New(asize + bsize);
4303+
ret = long_alloc(asize + bsize);
42984304
if (ret == NULL)
42994305
return NULL;
43004306
memset(ret->long_value.ob_digit, 0, _PyLong_DigitCount(ret) * sizeof(digit));
43014307

43024308
/* Successive slices of b are copied into bslice. */
4303-
bslice = _PyLong_New(asize);
4309+
bslice = long_alloc(asize);
43044310
if (bslice == NULL)
43054311
goto fail;
43064312

@@ -4766,7 +4772,7 @@ long_true_divide(PyObject *v, PyObject *w)
47664772
"intermediate overflow during division");
47674773
goto error;
47684774
}
4769-
x = _PyLong_New(a_size + shift_digits + 1);
4775+
x = long_alloc(a_size + shift_digits + 1);
47704776
if (x == NULL)
47714777
goto error;
47724778
for (i = 0; i < shift_digits; i++)
@@ -4780,7 +4786,7 @@ long_true_divide(PyObject *v, PyObject *w)
47804786
digit rem;
47814787
/* x = a >> shift */
47824788
assert(a_size >= shift_digits);
4783-
x = _PyLong_New(a_size - shift_digits);
4789+
x = long_alloc(a_size - shift_digits);
47844790
if (x == NULL)
47854791
goto error;
47864792
rem = v_rshift(x->long_value.ob_digit, a->long_value.ob_digit + shift_digits,
@@ -5360,7 +5366,7 @@ long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift)
53605366
/* Shifting all the bits of 'a' out gives either -1 or 0. */
53615367
return PyLong_FromLong(-a_negative);
53625368
}
5363-
z = _PyLong_New(newsize);
5369+
z = long_alloc(newsize);
53645370
if (z == NULL) {
53655371
return NULL;
53665372
}
@@ -5475,7 +5481,7 @@ long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift)
54755481
newsize = oldsize + wordshift;
54765482
if (remshift)
54775483
++newsize;
5478-
z = _PyLong_New(newsize);
5484+
z = long_alloc(newsize);
54795485
if (z == NULL)
54805486
return NULL;
54815487
if (_PyLong_IsNegative(a)) {
@@ -5590,7 +5596,7 @@ long_bitwise(PyLongObject *a,
55905596
size_a = _PyLong_DigitCount(a);
55915597
nega = _PyLong_IsNegative(a);
55925598
if (nega) {
5593-
z = _PyLong_New(size_a);
5599+
z = long_alloc(size_a);
55945600
if (z == NULL)
55955601
return NULL;
55965602
v_complement(z->long_value.ob_digit, a->long_value.ob_digit, size_a);
@@ -5604,7 +5610,7 @@ long_bitwise(PyLongObject *a,
56045610
size_b = _PyLong_DigitCount(b);
56055611
negb = _PyLong_IsNegative(b);
56065612
if (negb) {
5607-
z = _PyLong_New(size_b);
5613+
z = long_alloc(size_b);
56085614
if (z == NULL) {
56095615
Py_DECREF(a);
56105616
return NULL;
@@ -5648,7 +5654,7 @@ long_bitwise(PyLongObject *a,
56485654

56495655
/* We allow an extra digit if z is negative, to make sure that
56505656
the final two's complement of z doesn't overflow. */
5651-
z = _PyLong_New(size_z + negz);
5657+
z = long_alloc(size_z + negz);
56525658
if (z == NULL) {
56535659
Py_DECREF(a);
56545660
Py_DECREF(b);
@@ -5846,7 +5852,7 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg)
58465852
}
58475853
else {
58485854
alloc_a = size_a;
5849-
c = _PyLong_New(size_a);
5855+
c = long_alloc(size_a);
58505856
if (c == NULL)
58515857
goto error;
58525858
}
@@ -5862,7 +5868,7 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg)
58625868
}
58635869
else {
58645870
alloc_b = size_a;
5865-
d = _PyLong_New(size_a);
5871+
d = long_alloc(size_a);
58665872
if (d == NULL)
58675873
goto error;
58685874
}
@@ -6910,7 +6916,7 @@ PyLongWriter_Create(int negative, Py_ssize_t ndigits, void **digits)
69106916
}
69116917
assert(digits != NULL);
69126918

6913-
PyLongObject *obj = _PyLong_New(ndigits);
6919+
PyLongObject *obj = long_alloc(ndigits);
69146920
if (obj == NULL) {
69156921
goto error;
69166922
}

0 commit comments

Comments
 (0)