Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-106320: Remove private PyLong C API functions #108429

Merged
merged 1 commit into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 1 addition & 69 deletions Include/cpython/longobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,7 @@ PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *);
PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *);
PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *);

/* _PyLong_Frexp returns a double x and an exponent e such that the
true value is approximately equal to x * 2**e. e is >= 0. x is
0.0 if and only if the input is 0 (in which case, e and x are both
zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is
possible if the number of bits doesn't fit into a Py_ssize_t, sets
OverflowError and returns -1.0 for x, 0 for e. */
PyAPI_FUNC(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e);

PyAPI_FUNC(PyObject *) PyLong_FromUnicodeObject(PyObject *u, int base);
PyAPI_FUNC(PyObject *) _PyLong_FromBytes(const char *, Py_ssize_t, int);
PyAPI_FUNC(PyObject*) PyLong_FromUnicodeObject(PyObject *u, int base);

/* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0.
v must not be NULL, and must be a normalized long.
Expand All @@ -36,65 +27,6 @@ PyAPI_FUNC(int) _PyLong_Sign(PyObject *v);
*/
PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v);

/* _PyLong_DivmodNear. Given integers a and b, compute the nearest
integer q to the exact quotient a / b, rounding to the nearest even integer
in the case of a tie. Return (q, r), where r = a - q*b. The remainder r
will satisfy abs(r) <= abs(b)/2, with equality possible only if q is
even.
*/
PyAPI_FUNC(PyObject *) _PyLong_DivmodNear(PyObject *, PyObject *);

/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in
base 256, and return a Python int with the same numeric value.
If n is 0, the integer is 0. Else:
If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB;
else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the
LSB.
If is_signed is 0/false, view the bytes as a non-negative integer.
If is_signed is 1/true, view the bytes as a 2's-complement integer,
non-negative if bit 0x80 of the MSB is clear, negative if set.
Error returns:
+ Return NULL with the appropriate exception set if there's not
enough memory to create the Python int.
*/
PyAPI_FUNC(PyObject *) _PyLong_FromByteArray(
const unsigned char* bytes, size_t n,
int little_endian, int is_signed);

/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long
v to a base-256 integer, stored in array bytes. Normally return 0,
return -1 on error.
If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at
bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and
the LSB at bytes[n-1].
If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes
are filled and there's nothing special about bit 0x80 of the MSB.
If is_signed is 1/true, bytes is filled with the 2's-complement
representation of v's value. Bit 0x80 of the MSB is the sign bit.
Error returns (-1):
+ is_signed is 0 and v < 0. TypeError is set in this case, and bytes
isn't altered.
+ n isn't big enough to hold the full mathematical value of v. For
example, if is_signed is 0 and there are more digits in the v than
fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of
being large enough to hold a sign bit. OverflowError is set in this
case, but bytes holds the least-significant n bytes of the true value.
*/
PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v,
unsigned char* bytes, size_t n,
int little_endian, int is_signed);

/* _PyLong_Format: Convert the long to a string object with given base,
appending a base prefix of 0[box] if base is 2, 8 or 16. */
PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *obj, int base);

/* For use by the gcd function in mathmodule.c */
PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *);

PyAPI_FUNC(PyObject *) _PyLong_Rshift(PyObject *, size_t);
PyAPI_FUNC(PyObject *) _PyLong_Lshift(PyObject *, size_t);


PyAPI_FUNC(int) PyUnstable_Long_IsCompact(const PyLongObject* op);
PyAPI_FUNC(Py_ssize_t) PyUnstable_Long_CompactValue(const PyLongObject* op);

84 changes: 81 additions & 3 deletions Include/internal/pycore_long.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,87 @@ static inline PyObject* _PyLong_FromUnsignedChar(unsigned char i)
return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i];
}

extern PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
extern PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);
extern PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right);
// _PyLong_Frexp returns a double x and an exponent e such that the
// true value is approximately equal to x * 2**e. e is >= 0. x is
// 0.0 if and only if the input is 0 (in which case, e and x are both
// zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is
// possible if the number of bits doesn't fit into a Py_ssize_t, sets
// OverflowError and returns -1.0 for x, 0 for e.
//
// Export for 'math' shared extension
PyAPI_DATA(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e);

extern PyObject* _PyLong_FromBytes(const char *, Py_ssize_t, int);

// _PyLong_DivmodNear. Given integers a and b, compute the nearest
// integer q to the exact quotient a / b, rounding to the nearest even integer
// in the case of a tie. Return (q, r), where r = a - q*b. The remainder r
// will satisfy abs(r) <= abs(b)/2, with equality possible only if q is
// even.
//
// Export for '_datetime' shared extension.
PyAPI_DATA(PyObject*) _PyLong_DivmodNear(PyObject *, PyObject *);

// _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in
// base 256, and return a Python int with the same numeric value.
// If n is 0, the integer is 0. Else:
// If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB;
// else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the
// LSB.
// If is_signed is 0/false, view the bytes as a non-negative integer.
// If is_signed is 1/true, view the bytes as a 2's-complement integer,
// non-negative if bit 0x80 of the MSB is clear, negative if set.
// Error returns:
// + Return NULL with the appropriate exception set if there's not
// enough memory to create the Python int.
//
// Export for '_multibytecodec' shared extension.
PyAPI_DATA(PyObject*) _PyLong_FromByteArray(
const unsigned char* bytes, size_t n,
int little_endian, int is_signed);

// _PyLong_AsByteArray: Convert the least-significant 8*n bits of long
// v to a base-256 integer, stored in array bytes. Normally return 0,
// return -1 on error.
// If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at
// bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and
// the LSB at bytes[n-1].
// If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes
// are filled and there's nothing special about bit 0x80 of the MSB.
// If is_signed is 1/true, bytes is filled with the 2's-complement
// representation of v's value. Bit 0x80 of the MSB is the sign bit.
// Error returns (-1):
// + is_signed is 0 and v < 0. TypeError is set in this case, and bytes
// isn't altered.
// + n isn't big enough to hold the full mathematical value of v. For
// example, if is_signed is 0 and there are more digits in the v than
// fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of
// being large enough to hold a sign bit. OverflowError is set in this
// case, but bytes holds the least-significant n bytes of the true value.
//
// Export for '_struct' shared extension.
PyAPI_DATA(int) _PyLong_AsByteArray(PyLongObject* v,
unsigned char* bytes, size_t n,
int little_endian, int is_signed);

// _PyLong_Format: Convert the long to a string object with given base,
// appending a base prefix of 0[box] if base is 2, 8 or 16.
// Export for '_tkinter' shared extension.
PyAPI_DATA(PyObject*) _PyLong_Format(PyObject *obj, int base);

// For use by the math.gcd() function.
// Export for 'math' shared extension.
PyAPI_DATA(PyObject*) _PyLong_GCD(PyObject *, PyObject *);

// Export for 'math' shared extension
PyAPI_DATA(PyObject*) _PyLong_Rshift(PyObject *, size_t);

// Export for 'math' shared extension
PyAPI_DATA(PyObject*) _PyLong_Lshift(PyObject *, size_t);

extern PyObject* _PyLong_Add(PyLongObject *left, PyLongObject *right);
extern PyObject* _PyLong_Multiply(PyLongObject *left, PyLongObject *right);
extern PyObject* _PyLong_Subtract(PyLongObject *left, PyLongObject *right);

// Export for 'binascii' shared extension.
PyAPI_DATA(unsigned char) _PyLong_DigitValue[256];
Expand Down
5 changes: 3 additions & 2 deletions Modules/_io/_iomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
*/

#include "Python.h"
#include "_iomodule.h"
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_pystate.h" // _PyInterpreterState_GET()

#include "_iomodule.h"

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
Expand Down
1 change: 1 addition & 0 deletions Modules/_pickle.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "Python.h"
#include "pycore_bytesobject.h" // _PyBytesWriter
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
#include "pycore_long.h" // _PyLong_AsByteArray()
#include "pycore_moduleobject.h" // _PyModule_GetState()
#include "pycore_object.h" // _PyNone_Type
#include "pycore_pystate.h" // _PyThreadState_GET()
Expand Down
2 changes: 1 addition & 1 deletion Modules/_randommodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@
#endif

#include "Python.h"
#include "pycore_long.h" // _PyLong_AsByteArray()
#include "pycore_moduleobject.h" // _PyModule_GetState()
#include "pycore_pylifecycle.h" // _PyOS_URandomNonblock()
#include "pycore_runtime.h"
#ifdef HAVE_PROCESS_H
# include <process.h> // getpid()
#endif
Expand Down
5 changes: 5 additions & 0 deletions Modules/_sqlite/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@
* 3. This notice may not be removed or altered from any source distribution.
*/

#ifndef Py_BUILD_CORE_BUILTIN
# define Py_BUILD_CORE_MODULE 1
#endif

#include "module.h"
#include "pycore_long.h" // _PyLong_AsByteArray()
#include "connection.h"

// Returns non-NULL if a new exception should be raised
Expand Down
1 change: 1 addition & 0 deletions Modules/_struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "Python.h"
#include "pycore_bytesobject.h" // _PyBytesWriter
#include "pycore_long.h" // _PyLong_AsByteArray()
#include "pycore_moduleobject.h" // _PyModule_GetState()

#include <ctype.h>
Expand Down
3 changes: 2 additions & 1 deletion Modules/arraymodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
#endif

#include "Python.h"
#include "pycore_bytesobject.h" // _PyBytes_Repeat
#include "pycore_call.h" // _PyObject_CallMethod()
#include "pycore_long.h" // _PyLong_FromByteArray()
#include "pycore_moduleobject.h" // _PyModule_GetState()
#include "pycore_bytesobject.h" // _PyBytes_Repeat

#include <stddef.h> // offsetof()
#include <stdbool.h>
Expand Down
1 change: 1 addition & 0 deletions Modules/cjkcodecs/multibytecodec.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#endif

#include "Python.h"
#include "pycore_long.h" // _PyLong_FromByteArray()

#include "multibytecodec.h"
#include "clinic/multibytecodec.c.h"
Expand Down
5 changes: 3 additions & 2 deletions Python/hamt.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#include "Python.h"

#include "pycore_bitutils.h" // _Py_popcount32
#include "pycore_bitutils.h" // _Py_popcount32()
#include "pycore_hamt.h"
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_long.h" // _PyLong_Format()
#include "pycore_object.h" // _PyObject_GC_TRACK()

#include <stddef.h> // offsetof()

/*
Expand Down
Loading