Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5f09bb0

Browse filesBrowse files
authored
bpo-35134: Add Include/cpython/longobject.h (GH-29044)
Move Include/longobject.h non-limited API to a new Include/cpython/longobject.h header file. Move the following definitions to the internal C API: * _PyLong_DigitValue * _PyLong_FormatAdvancedWriter() * _PyLong_FormatWriter()
1 parent aad88d3 commit 5f09bb0
Copy full SHA for 5f09bb0

File tree

Expand file treeCollapse file tree

11 files changed

+135
-132
lines changed
Filter options
Expand file treeCollapse file tree

11 files changed

+135
-132
lines changed

‎Include/cpython/longobject.h

Copy file name to clipboard
+95Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#ifndef Py_CPYTHON_LONGOBJECT_H
2+
# error "this header file must not be included directly"
3+
#endif
4+
5+
PyAPI_FUNC(int) _PyLong_AsInt(PyObject *);
6+
7+
PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *);
8+
PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *);
9+
PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *);
10+
PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *);
11+
PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *);
12+
13+
/* _PyLong_Frexp returns a double x and an exponent e such that the
14+
true value is approximately equal to x * 2**e. e is >= 0. x is
15+
0.0 if and only if the input is 0 (in which case, e and x are both
16+
zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is
17+
possible if the number of bits doesn't fit into a Py_ssize_t, sets
18+
OverflowError and returns -1.0 for x, 0 for e. */
19+
PyAPI_FUNC(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e);
20+
21+
PyAPI_FUNC(PyObject *) PyLong_FromUnicodeObject(PyObject *u, int base);
22+
PyAPI_FUNC(PyObject *) _PyLong_FromBytes(const char *, Py_ssize_t, int);
23+
24+
/* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0.
25+
v must not be NULL, and must be a normalized long.
26+
There are no error cases.
27+
*/
28+
PyAPI_FUNC(int) _PyLong_Sign(PyObject *v);
29+
30+
/* _PyLong_NumBits. Return the number of bits needed to represent the
31+
absolute value of a long. For example, this returns 1 for 1 and -1, 2
32+
for 2 and -2, and 2 for 3 and -3. It returns 0 for 0.
33+
v must not be NULL, and must be a normalized long.
34+
(size_t)-1 is returned and OverflowError set if the true result doesn't
35+
fit in a size_t.
36+
*/
37+
PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v);
38+
39+
/* _PyLong_DivmodNear. Given integers a and b, compute the nearest
40+
integer q to the exact quotient a / b, rounding to the nearest even integer
41+
in the case of a tie. Return (q, r), where r = a - q*b. The remainder r
42+
will satisfy abs(r) <= abs(b)/2, with equality possible only if q is
43+
even.
44+
*/
45+
PyAPI_FUNC(PyObject *) _PyLong_DivmodNear(PyObject *, PyObject *);
46+
47+
/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in
48+
base 256, and return a Python int with the same numeric value.
49+
If n is 0, the integer is 0. Else:
50+
If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB;
51+
else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the
52+
LSB.
53+
If is_signed is 0/false, view the bytes as a non-negative integer.
54+
If is_signed is 1/true, view the bytes as a 2's-complement integer,
55+
non-negative if bit 0x80 of the MSB is clear, negative if set.
56+
Error returns:
57+
+ Return NULL with the appropriate exception set if there's not
58+
enough memory to create the Python int.
59+
*/
60+
PyAPI_FUNC(PyObject *) _PyLong_FromByteArray(
61+
const unsigned char* bytes, size_t n,
62+
int little_endian, int is_signed);
63+
64+
/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long
65+
v to a base-256 integer, stored in array bytes. Normally return 0,
66+
return -1 on error.
67+
If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at
68+
bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and
69+
the LSB at bytes[n-1].
70+
If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes
71+
are filled and there's nothing special about bit 0x80 of the MSB.
72+
If is_signed is 1/true, bytes is filled with the 2's-complement
73+
representation of v's value. Bit 0x80 of the MSB is the sign bit.
74+
Error returns (-1):
75+
+ is_signed is 0 and v < 0. TypeError is set in this case, and bytes
76+
isn't altered.
77+
+ n isn't big enough to hold the full mathematical value of v. For
78+
example, if is_signed is 0 and there are more digits in the v than
79+
fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of
80+
being large enough to hold a sign bit. OverflowError is set in this
81+
case, but bytes holds the least-significant n bytes of the true value.
82+
*/
83+
PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v,
84+
unsigned char* bytes, size_t n,
85+
int little_endian, int is_signed);
86+
87+
/* _PyLong_Format: Convert the long to a string object with given base,
88+
appending a base prefix of 0[box] if base is 2, 8 or 16. */
89+
PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *obj, int base);
90+
91+
/* For use by the gcd function in mathmodule.c */
92+
PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *);
93+
94+
PyAPI_FUNC(PyObject *) _PyLong_Rshift(PyObject *, size_t);
95+
PyAPI_FUNC(PyObject *) _PyLong_Lshift(PyObject *, size_t);

‎Include/internal/pycore_long.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_long.h
+26Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,32 @@ static inline PyObject* _PyLong_GetOne(void)
3737
PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
3838
PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);
3939

40+
/* Used by Python/mystrtoul.c, _PyBytes_FromHex(),
41+
_PyBytes_DecodeEscape(), etc. */
42+
PyAPI_DATA(unsigned char) _PyLong_DigitValue[256];
43+
44+
/* Format the object based on the format_spec, as defined in PEP 3101
45+
(Advanced String Formatting). */
46+
PyAPI_FUNC(int) _PyLong_FormatAdvancedWriter(
47+
_PyUnicodeWriter *writer,
48+
PyObject *obj,
49+
PyObject *format_spec,
50+
Py_ssize_t start,
51+
Py_ssize_t end);
52+
53+
PyAPI_FUNC(int) _PyLong_FormatWriter(
54+
_PyUnicodeWriter *writer,
55+
PyObject *obj,
56+
int base,
57+
int alternate);
58+
59+
PyAPI_FUNC(char*) _PyLong_FormatBytesWriter(
60+
_PyBytesWriter *writer,
61+
char *str,
62+
PyObject *obj,
63+
int base,
64+
int alternate);
65+
4066
#ifdef __cplusplus
4167
}
4268
#endif

‎Include/longobject.h

Copy file name to clipboardExpand all lines: Include/longobject.h
+3-130Lines changed: 3 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ PyAPI_FUNC(Py_ssize_t) PyLong_AsSsize_t(PyObject *);
2626
PyAPI_FUNC(size_t) PyLong_AsSize_t(PyObject *);
2727
PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *);
2828
PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *);
29-
#ifndef Py_LIMITED_API
30-
PyAPI_FUNC(int) _PyLong_AsInt(PyObject *);
31-
#endif
3229
PyAPI_FUNC(PyObject *) PyLong_GetInfo(void);
3330

3431
/* It may be useful in the future. I've added it in the PyInt -> PyLong
@@ -65,30 +62,6 @@ PyAPI_FUNC(PyObject *) PyLong_GetInfo(void);
6562
# error "void* different in size from int, long and long long"
6663
#endif /* SIZEOF_VOID_P */
6764

68-
#ifndef Py_LIMITED_API
69-
PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *);
70-
PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *);
71-
PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *);
72-
PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *);
73-
PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *);
74-
#endif
75-
76-
/* Used by Python/mystrtoul.c, _PyBytes_FromHex(),
77-
_PyBytes_DecodeEscape(), etc. */
78-
#ifndef Py_LIMITED_API
79-
PyAPI_DATA(unsigned char) _PyLong_DigitValue[256];
80-
#endif
81-
82-
/* _PyLong_Frexp returns a double x and an exponent e such that the
83-
true value is approximately equal to x * 2**e. e is >= 0. x is
84-
0.0 if and only if the input is 0 (in which case, e and x are both
85-
zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is
86-
possible if the number of bits doesn't fit into a Py_ssize_t, sets
87-
OverflowError and returns -1.0 for x, 0 for e. */
88-
#ifndef Py_LIMITED_API
89-
PyAPI_FUNC(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e);
90-
#endif
91-
9265
PyAPI_FUNC(double) PyLong_AsDouble(PyObject *);
9366
PyAPI_FUNC(PyObject *) PyLong_FromVoidPtr(void *);
9467
PyAPI_FUNC(void *) PyLong_AsVoidPtr(PyObject *);
@@ -101,102 +74,6 @@ PyAPI_FUNC(unsigned long long) PyLong_AsUnsignedLongLongMask(PyObject *);
10174
PyAPI_FUNC(long long) PyLong_AsLongLongAndOverflow(PyObject *, int *);
10275

10376
PyAPI_FUNC(PyObject *) PyLong_FromString(const char *, char **, int);
104-
#ifndef Py_LIMITED_API
105-
PyAPI_FUNC(PyObject *) PyLong_FromUnicodeObject(PyObject *u, int base);
106-
PyAPI_FUNC(PyObject *) _PyLong_FromBytes(const char *, Py_ssize_t, int);
107-
#endif
108-
109-
#ifndef Py_LIMITED_API
110-
/* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0.
111-
v must not be NULL, and must be a normalized long.
112-
There are no error cases.
113-
*/
114-
PyAPI_FUNC(int) _PyLong_Sign(PyObject *v);
115-
116-
117-
/* _PyLong_NumBits. Return the number of bits needed to represent the
118-
absolute value of a long. For example, this returns 1 for 1 and -1, 2
119-
for 2 and -2, and 2 for 3 and -3. It returns 0 for 0.
120-
v must not be NULL, and must be a normalized long.
121-
(size_t)-1 is returned and OverflowError set if the true result doesn't
122-
fit in a size_t.
123-
*/
124-
PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v);
125-
126-
/* _PyLong_DivmodNear. Given integers a and b, compute the nearest
127-
integer q to the exact quotient a / b, rounding to the nearest even integer
128-
in the case of a tie. Return (q, r), where r = a - q*b. The remainder r
129-
will satisfy abs(r) <= abs(b)/2, with equality possible only if q is
130-
even.
131-
*/
132-
PyAPI_FUNC(PyObject *) _PyLong_DivmodNear(PyObject *, PyObject *);
133-
134-
/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in
135-
base 256, and return a Python int with the same numeric value.
136-
If n is 0, the integer is 0. Else:
137-
If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB;
138-
else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the
139-
LSB.
140-
If is_signed is 0/false, view the bytes as a non-negative integer.
141-
If is_signed is 1/true, view the bytes as a 2's-complement integer,
142-
non-negative if bit 0x80 of the MSB is clear, negative if set.
143-
Error returns:
144-
+ Return NULL with the appropriate exception set if there's not
145-
enough memory to create the Python int.
146-
*/
147-
PyAPI_FUNC(PyObject *) _PyLong_FromByteArray(
148-
const unsigned char* bytes, size_t n,
149-
int little_endian, int is_signed);
150-
151-
/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long
152-
v to a base-256 integer, stored in array bytes. Normally return 0,
153-
return -1 on error.
154-
If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at
155-
bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and
156-
the LSB at bytes[n-1].
157-
If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes
158-
are filled and there's nothing special about bit 0x80 of the MSB.
159-
If is_signed is 1/true, bytes is filled with the 2's-complement
160-
representation of v's value. Bit 0x80 of the MSB is the sign bit.
161-
Error returns (-1):
162-
+ is_signed is 0 and v < 0. TypeError is set in this case, and bytes
163-
isn't altered.
164-
+ n isn't big enough to hold the full mathematical value of v. For
165-
example, if is_signed is 0 and there are more digits in the v than
166-
fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of
167-
being large enough to hold a sign bit. OverflowError is set in this
168-
case, but bytes holds the least-significant n bytes of the true value.
169-
*/
170-
PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v,
171-
unsigned char* bytes, size_t n,
172-
int little_endian, int is_signed);
173-
174-
/* _PyLong_Format: Convert the long to a string object with given base,
175-
appending a base prefix of 0[box] if base is 2, 8 or 16. */
176-
PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *obj, int base);
177-
178-
PyAPI_FUNC(int) _PyLong_FormatWriter(
179-
_PyUnicodeWriter *writer,
180-
PyObject *obj,
181-
int base,
182-
int alternate);
183-
184-
PyAPI_FUNC(char*) _PyLong_FormatBytesWriter(
185-
_PyBytesWriter *writer,
186-
char *str,
187-
PyObject *obj,
188-
int base,
189-
int alternate);
190-
191-
/* Format the object based on the format_spec, as defined in PEP 3101
192-
(Advanced String Formatting). */
193-
PyAPI_FUNC(int) _PyLong_FormatAdvancedWriter(
194-
_PyUnicodeWriter *writer,
195-
PyObject *obj,
196-
PyObject *format_spec,
197-
Py_ssize_t start,
198-
Py_ssize_t end);
199-
#endif /* Py_LIMITED_API */
20077

20178
/* These aren't really part of the int object, but they're handy. The
20279
functions are in Python/mystrtoul.c.
@@ -205,13 +82,9 @@ PyAPI_FUNC(unsigned long) PyOS_strtoul(const char *, char **, int);
20582
PyAPI_FUNC(long) PyOS_strtol(const char *, char **, int);
20683

20784
#ifndef Py_LIMITED_API
208-
/* For use by the gcd function in mathmodule.c */
209-
PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *);
210-
#endif /* !Py_LIMITED_API */
211-
212-
#ifndef Py_LIMITED_API
213-
PyAPI_FUNC(PyObject *) _PyLong_Rshift(PyObject *, size_t);
214-
PyAPI_FUNC(PyObject *) _PyLong_Lshift(PyObject *, size_t);
85+
# define Py_CPYTHON_LONGOBJECT_H
86+
# include "cpython/longobject.h"
87+
# undef Py_CPYTHON_LONGOBJECT_H
21588
#endif
21689

21790
#ifdef __cplusplus

‎Makefile.pre.in

Copy file name to clipboardExpand all lines: Makefile.pre.in
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,7 @@ PYTHON_HEADERS= \
12101210
$(srcdir)/Include/cpython/initconfig.h \
12111211
$(srcdir)/Include/cpython/listobject.h \
12121212
$(srcdir)/Include/cpython/longintrepr.h \
1213+
$(srcdir)/Include/cpython/longobject.h \
12131214
$(srcdir)/Include/cpython/methodobject.h \
12141215
$(srcdir)/Include/cpython/object.h \
12151216
$(srcdir)/Include/cpython/objimpl.h \

‎Modules/binascii.c

Copy file name to clipboardExpand all lines: Modules/binascii.c
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#define PY_SSIZE_T_CLEAN
5757

5858
#include "Python.h"
59+
#include "pycore_long.h" // _PyLong_DigitValue
5960
#include "pycore_strhex.h" // _Py_strhex_bytes_with_sep()
6061
#ifdef USE_ZLIB_CRC32
6162
# include "zlib.h"

‎Objects/bytesobject.c

Copy file name to clipboardExpand all lines: Objects/bytesobject.c
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "pycore_call.h" // _PyObject_CallNoArgs()
99
#include "pycore_format.h" // F_LJUST
1010
#include "pycore_initconfig.h" // _PyStatus_OK()
11+
#include "pycore_long.h" // _PyLong_DigitValue
1112
#include "pycore_object.h" // _PyObject_GC_TRACK
1213
#include "pycore_pymem.h" // PYMEM_CLEANBYTE
1314
#include "pycore_strhex.h" // _Py_strhex_with_sep()

‎Objects/unicodeobject.c

Copy file name to clipboardExpand all lines: Objects/unicodeobject.c
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4646
#include "pycore_format.h" // F_LJUST
4747
#include "pycore_initconfig.h" // _PyStatus_OK()
4848
#include "pycore_interp.h" // PyInterpreterState.fs_codec
49+
#include "pycore_long.h" // _PyLong_FormatWriter()
4950
#include "pycore_object.h" // _PyObject_GC_TRACK()
5051
#include "pycore_pathconfig.h" // _Py_DumpPathConfig()
5152
#include "pycore_pyerrors.h" // _Py_FatalRefcountError()

‎PCbuild/pythoncore.vcxproj

Copy file name to clipboardExpand all lines: PCbuild/pythoncore.vcxproj
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
<ClInclude Include="..\Include\cpython\initconfig.h" />
141141
<ClInclude Include="..\Include\cpython\listobject.h" />
142142
<ClInclude Include="..\Include\cpython\longintrepr.h" />
143+
<ClInclude Include="..\Include\cpython\longobject.h" />
143144
<ClInclude Include="..\Include\cpython\methodobject.h" />
144145
<ClInclude Include="..\Include\cpython\object.h" />
145146
<ClInclude Include="..\Include\cpython\objimpl.h" />

‎PCbuild/pythoncore.vcxproj.filters

Copy file name to clipboardExpand all lines: PCbuild/pythoncore.vcxproj.filters
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,9 @@
387387
<ClInclude Include="..\Include\cpython\longintrepr.h">
388388
<Filter>Include</Filter>
389389
</ClInclude>
390+
<ClInclude Include="..\Include\cpython\longobject.h">
391+
<Filter>Include</Filter>
392+
</ClInclude>
390393
<ClInclude Include="..\Include\cpython\odictobject.h">
391394
<Filter>Include</Filter>
392395
</ClInclude>

‎Python/formatter_unicode.c

Copy file name to clipboardExpand all lines: Python/formatter_unicode.c
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
of int.__float__, etc., that take and return unicode objects */
44

55
#include "Python.h"
6-
#include "pycore_fileutils.h"
6+
#include "pycore_fileutils.h" // _Py_GetLocaleconvNumeric()
7+
#include "pycore_long.h" // _PyLong_FormatWriter()
78
#include <locale.h>
89

910
/* Raises an exception about an unknown presentation type for this

‎Python/mystrtoul.c

Copy file name to clipboardExpand all lines: Python/mystrtoul.c
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
21
#include "Python.h"
2+
#include "pycore_long.h" // _PyLong_DigitValue
33

44
#if defined(__sgi) && !defined(_SGI_MP_SOURCE)
55
#define _SGI_MP_SOURCE

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.