gh-112026: Restore removed private C API (#112115)

Restore removed private C API functions, macros and structures which
have no simple replacement for now:

* _PyDict_GetItem_KnownHash()
* _PyDict_NewPresized()
* _PyHASH_BITS
* _PyHASH_IMAG
* _PyHASH_INF
* _PyHASH_MODULUS
* _PyHASH_MULTIPLIER
* _PyLong_Copy()
* _PyLong_FromDigits()
* _PyLong_New()
* _PyLong_Sign()
* _PyObject_CallMethodId()
* _PyObject_CallMethodNoArgs()
* _PyObject_CallMethodOneArg()
* _PyObject_CallOneArg()
* _PyObject_EXTRA_INIT
* _PyObject_FastCallDict()
* _PyObject_GetAttrId()
* _PyObject_Vectorcall()
* _PyObject_VectorcallMethod()
* _PyStack_AsDict()
* _PyThread_CurrentFrames()
* _PyUnicodeWriter structure
* _PyUnicodeWriter_Dealloc()
* _PyUnicodeWriter_Finish()
* _PyUnicodeWriter_Init()
* _PyUnicodeWriter_Prepare()
* _PyUnicodeWriter_PrepareKind()
* _PyUnicodeWriter_WriteASCIIString()
* _PyUnicodeWriter_WriteChar()
* _PyUnicodeWriter_WriteLatin1String()
* _PyUnicodeWriter_WriteStr()
* _PyUnicodeWriter_WriteSubstring()
* _PyUnicode_AsString()
* _PyUnicode_FromId()
* _PyVectorcall_Function()
* _Py_HashDouble()
* _Py_HashPointer()
* _Py_IDENTIFIER()
* _Py_c_abs()
* _Py_c_diff()
* _Py_c_neg()
* _Py_c_pow()
* _Py_c_prod()
* _Py_c_quot()
* _Py_c_sum()
* _Py_static_string()
* _Py_static_string_init()
This commit is contained in:
Victor Stinner 2023-11-15 17:38:31 +01:00 committed by GitHub
parent b338ffa4bc
commit 58469244be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 315 additions and 236 deletions

View File

@ -2,6 +2,28 @@
# error "this header file must not be included directly" # error "this header file must not be included directly"
#endif #endif
/* === Object Protocol ================================================== */
/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
as the method name. */
PyAPI_FUNC(PyObject*) _PyObject_CallMethodId(
PyObject *obj,
_Py_Identifier *name,
const char *format, ...);
/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
format to a Python dictionary ("kwargs" dict).
The type of kwnames keys is not checked. The final function getting
arguments is responsible to check if all keys are strings, for example using
PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
Duplicate keys are merged using the last value. If duplicate keys must raise
an exception, the caller is responsible to implement an explicit keys on
kwnames. */
PyAPI_FUNC(PyObject*) _PyStack_AsDict(PyObject *const *values, PyObject *kwnames);
/* === Vectorcall protocol (PEP 590) ============================= */ /* === Vectorcall protocol (PEP 590) ============================= */
// PyVectorcall_NARGS() is exported as a function for the stable ABI. // PyVectorcall_NARGS() is exported as a function for the stable ABI.
@ -16,6 +38,16 @@ _PyVectorcall_NARGS(size_t n)
PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable); PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable);
// Backwards compatibility aliases (PEP 590) for API that was provisional
// in Python 3.8
#define _PyObject_Vectorcall PyObject_Vectorcall
#define _PyObject_VectorcallMethod PyObject_VectorcallMethod
#define _PyObject_FastCallDict PyObject_VectorcallDict
#define _PyVectorcall_Function PyVectorcall_Function
#define _PyObject_CallOneArg PyObject_CallOneArg
#define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs
#define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg
/* Same as PyObject_Vectorcall except that keyword arguments are passed as /* Same as PyObject_Vectorcall except that keyword arguments are passed as
dict, which may be NULL if there are no keyword arguments. */ dict, which may be NULL if there are no keyword arguments. */
PyAPI_FUNC(PyObject *) PyObject_VectorcallDict( PyAPI_FUNC(PyObject *) PyObject_VectorcallDict(

View File

@ -7,6 +7,16 @@ typedef struct {
double imag; double imag;
} Py_complex; } Py_complex;
// Operations on complex numbers.
PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex);
PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex);
PyAPI_FUNC(double) _Py_c_abs(Py_complex);
/* Complex object interface */ /* Complex object interface */
/* /*

View File

@ -32,6 +32,9 @@ typedef struct {
PyDictValues *ma_values; PyDictValues *ma_values;
} PyDictObject; } PyDictObject;
PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
Py_hash_t hash);
PyAPI_FUNC(PyObject *) PyDict_SetDefault( PyAPI_FUNC(PyObject *) PyDict_SetDefault(
PyObject *mp, PyObject *key, PyObject *defaultobj); PyObject *mp, PyObject *key, PyObject *defaultobj);
@ -46,6 +49,8 @@ static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) {
PyAPI_FUNC(int) PyDict_ContainsString(PyObject *mp, const char *key); PyAPI_FUNC(int) PyDict_ContainsString(PyObject *mp, const char *key);
PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
PyAPI_FUNC(int) PyDict_Pop(PyObject *dict, PyObject *key, PyObject **result); PyAPI_FUNC(int) PyDict_Pop(PyObject *dict, PyObject *key, PyObject **result);
PyAPI_FUNC(int) PyDict_PopString(PyObject *dict, const char *key, PyObject **result); PyAPI_FUNC(int) PyDict_PopString(PyObject *dict, const char *key, PyObject **result);
PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value); PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value);

View File

@ -89,6 +89,16 @@ struct _longobject {
_PyLongValue long_value; _PyLongValue long_value;
}; };
PyAPI_FUNC(PyLongObject*) _PyLong_New(Py_ssize_t);
// Return a copy of src.
PyAPI_FUNC(PyObject*) _PyLong_Copy(PyLongObject *src);
PyAPI_FUNC(PyLongObject*) _PyLong_FromDigits(
int negative,
Py_ssize_t digit_count,
digit *digits);
/* Inline some internals for speed. These should be in pycore_long.h /* Inline some internals for speed. These should be in pycore_long.h
* if user code didn't need them inlined. */ * if user code didn't need them inlined. */

View File

@ -7,6 +7,11 @@ PyAPI_FUNC(PyObject*) PyLong_FromUnicodeObject(PyObject *u, int base);
PyAPI_FUNC(int) PyUnstable_Long_IsCompact(const PyLongObject* op); PyAPI_FUNC(int) PyUnstable_Long_IsCompact(const PyLongObject* op);
PyAPI_FUNC(Py_ssize_t) PyUnstable_Long_CompactValue(const PyLongObject* op); PyAPI_FUNC(Py_ssize_t) PyUnstable_Long_CompactValue(const PyLongObject* op);
// _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.
// There are no error cases.
PyAPI_FUNC(int) _PyLong_Sign(PyObject *v);
/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in /* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in
base 256, and return a Python int with the same numeric value. base 256, and return a Python int with the same numeric value.
If n is 0, the integer is 0. Else: If n is 0, the integer is 0. Else:

View File

@ -14,6 +14,44 @@ PyAPI_FUNC(Py_ssize_t) _PyInterpreterState_GetRefTotal(PyInterpreterState *);
#endif #endif
/********************* String Literals ****************************************/
/* This structure helps managing static strings. The basic usage goes like this:
Instead of doing
r = PyObject_CallMethod(o, "foo", "args", ...);
do
_Py_IDENTIFIER(foo);
...
r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...);
PyId_foo is a static variable, either on block level or file level. On first
usage, the string "foo" is interned, and the structures are linked. On interpreter
shutdown, all strings are released.
Alternatively, _Py_static_string allows choosing the variable name.
_PyUnicode_FromId returns a borrowed reference to the interned string.
_PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*.
*/
typedef struct _Py_Identifier {
const char* string;
// Index in PyInterpreterState.unicode.ids.array. It is process-wide
// unique and must be initialized to -1.
Py_ssize_t index;
} _Py_Identifier;
#ifndef Py_BUILD_CORE
// For now we are keeping _Py_IDENTIFIER for continued use
// in non-builtin extensions (and naughty PyPI modules).
#define _Py_static_string_init(value) { .string = (value), .index = -1 }
#define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value)
#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname)
#endif /* !Py_BUILD_CORE */
typedef struct { typedef struct {
/* Number implementations must check *both* /* Number implementations must check *both*
arguments for proper type and implement the necessary conversions arguments for proper type and implement the necessary conversions
@ -238,6 +276,8 @@ PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
PyAPI_FUNC(void) _Py_BreakPoint(void); PyAPI_FUNC(void) _Py_BreakPoint(void);
PyAPI_FUNC(void) _PyObject_Dump(PyObject *); PyAPI_FUNC(void) _PyObject_Dump(PyObject *);
PyAPI_FUNC(PyObject*) _PyObject_GetAttrId(PyObject *, _Py_Identifier *);
PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *); PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *);
PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *); PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *);

View File

@ -2,6 +2,28 @@
# error "this header file must not be included directly" # error "this header file must not be included directly"
#endif #endif
/* Prime multiplier used in string and various other hashes. */
#define _PyHASH_MULTIPLIER 1000003UL /* 0xf4243 */
/* Parameters used for the numeric hash implementation. See notes for
_Py_HashDouble in Python/pyhash.c. Numeric hashes are based on
reduction modulo the prime 2**_PyHASH_BITS - 1. */
#if SIZEOF_VOID_P >= 8
# define _PyHASH_BITS 61
#else
# define _PyHASH_BITS 31
#endif
#define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1)
#define _PyHASH_INF 314159
#define _PyHASH_IMAG _PyHASH_MULTIPLIER
/* Helpers for hash functions */
PyAPI_FUNC(Py_hash_t) _Py_HashDouble(PyObject *, double);
PyAPI_FUNC(Py_hash_t) _Py_HashPointer(const void*);
/* hash function definition */ /* hash function definition */
typedef struct { typedef struct {
Py_hash_t (*const hash)(const void *, Py_ssize_t); Py_hash_t (*const hash)(const void *, Py_ssize_t);

View File

@ -247,6 +247,11 @@ PyAPI_FUNC(void) PyThreadState_LeaveTracing(PyThreadState *tstate);
The function returns 1 if _PyGILState_check_enabled is non-zero. */ The function returns 1 if _PyGILState_check_enabled is non-zero. */
PyAPI_FUNC(int) PyGILState_Check(void); PyAPI_FUNC(int) PyGILState_Check(void);
/* The implementation of sys._current_frames() Returns a dict mapping
thread id to that thread's current frame.
*/
PyAPI_FUNC(PyObject*) _PyThread_CurrentFrames(void);
/* Routines for advanced debuggers, requested by David Beazley. /* Routines for advanced debuggers, requested by David Beazley.
Don't use unless you know what you are doing! */ Don't use unless you know what you are doing! */
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void); PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void);

View File

@ -9,6 +9,7 @@
Py_DEPRECATED(3.13) typedef wchar_t PY_UNICODE_TYPE; Py_DEPRECATED(3.13) typedef wchar_t PY_UNICODE_TYPE;
Py_DEPRECATED(3.13) typedef wchar_t Py_UNICODE; Py_DEPRECATED(3.13) typedef wchar_t Py_UNICODE;
/* --- Internal Unicode Operations ---------------------------------------- */ /* --- Internal Unicode Operations ---------------------------------------- */
// Static inline functions to work with surrogates // Static inline functions to work with surrogates
@ -43,6 +44,7 @@ static inline Py_UCS4 Py_UNICODE_LOW_SURROGATE(Py_UCS4 ch) {
return (0xDC00 + (ch & 0x3FF)); return (0xDC00 + (ch & 0x3FF));
} }
/* --- Unicode Type ------------------------------------------------------- */ /* --- Unicode Type ------------------------------------------------------- */
/* ASCII-only strings created through PyUnicode_New use the PyASCIIObject /* ASCII-only strings created through PyUnicode_New use the PyASCIIObject
@ -375,6 +377,7 @@ static inline Py_UCS4 PyUnicode_MAX_CHAR_VALUE(PyObject *op)
#define PyUnicode_MAX_CHAR_VALUE(op) \ #define PyUnicode_MAX_CHAR_VALUE(op) \
PyUnicode_MAX_CHAR_VALUE(_PyObject_CAST(op)) PyUnicode_MAX_CHAR_VALUE(_PyObject_CAST(op))
/* === Public API ========================================================= */ /* === Public API ========================================================= */
/* With PEP 393, this is the recommended way to allocate a new unicode object. /* With PEP 393, this is the recommended way to allocate a new unicode object.
@ -440,6 +443,123 @@ PyAPI_FUNC(PyObject*) PyUnicode_FromKindAndData(
const void *buffer, const void *buffer,
Py_ssize_t size); Py_ssize_t size);
/* --- _PyUnicodeWriter API ----------------------------------------------- */
typedef struct {
PyObject *buffer;
void *data;
int kind;
Py_UCS4 maxchar;
Py_ssize_t size;
Py_ssize_t pos;
/* minimum number of allocated characters (default: 0) */
Py_ssize_t min_length;
/* minimum character (default: 127, ASCII) */
Py_UCS4 min_char;
/* If non-zero, overallocate the buffer (default: 0). */
unsigned char overallocate;
/* If readonly is 1, buffer is a shared string (cannot be modified)
and size is set to 0. */
unsigned char readonly;
} _PyUnicodeWriter ;
// Initialize a Unicode writer.
//
// By default, the minimum buffer size is 0 character and overallocation is
// disabled. Set min_length, min_char and overallocate attributes to control
// the allocation of the buffer.
PyAPI_FUNC(void)
_PyUnicodeWriter_Init(_PyUnicodeWriter *writer);
/* Prepare the buffer to write 'length' characters
with the specified maximum character.
Return 0 on success, raise an exception and return -1 on error. */
#define _PyUnicodeWriter_Prepare(WRITER, LENGTH, MAXCHAR) \
(((MAXCHAR) <= (WRITER)->maxchar \
&& (LENGTH) <= (WRITER)->size - (WRITER)->pos) \
? 0 \
: (((LENGTH) == 0) \
? 0 \
: _PyUnicodeWriter_PrepareInternal((WRITER), (LENGTH), (MAXCHAR))))
/* Don't call this function directly, use the _PyUnicodeWriter_Prepare() macro
instead. */
PyAPI_FUNC(int)
_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer,
Py_ssize_t length, Py_UCS4 maxchar);
/* Prepare the buffer to have at least the kind KIND.
For example, kind=PyUnicode_2BYTE_KIND ensures that the writer will
support characters in range U+000-U+FFFF.
Return 0 on success, raise an exception and return -1 on error. */
#define _PyUnicodeWriter_PrepareKind(WRITER, KIND) \
((KIND) <= (WRITER)->kind \
? 0 \
: _PyUnicodeWriter_PrepareKindInternal((WRITER), (KIND)))
/* Don't call this function directly, use the _PyUnicodeWriter_PrepareKind()
macro instead. */
PyAPI_FUNC(int)
_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer,
int kind);
/* Append a Unicode character.
Return 0 on success, raise an exception and return -1 on error. */
PyAPI_FUNC(int)
_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer,
Py_UCS4 ch
);
/* Append a Unicode string.
Return 0 on success, raise an exception and return -1 on error. */
PyAPI_FUNC(int)
_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer,
PyObject *str /* Unicode string */
);
/* Append a substring of a Unicode string.
Return 0 on success, raise an exception and return -1 on error. */
PyAPI_FUNC(int)
_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer,
PyObject *str, /* Unicode string */
Py_ssize_t start,
Py_ssize_t end
);
/* Append an ASCII-encoded byte string.
Return 0 on success, raise an exception and return -1 on error. */
PyAPI_FUNC(int)
_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer,
const char *str, /* ASCII-encoded byte string */
Py_ssize_t len /* number of bytes, or -1 if unknown */
);
/* Append a latin1-encoded byte string.
Return 0 on success, raise an exception and return -1 on error. */
PyAPI_FUNC(int)
_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer,
const char *str, /* latin1-encoded byte string */
Py_ssize_t len /* length in bytes */
);
/* Get the value of the writer as a Unicode string. Clear the
buffer of the writer. Raise an exception and return NULL
on error. */
PyAPI_FUNC(PyObject *)
_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer);
/* Deallocate memory of a writer (clear its internal buffer). */
PyAPI_FUNC(void)
_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer);
/* --- Manage the default encoding ---------------------------------------- */ /* --- Manage the default encoding ---------------------------------------- */
/* Returns a pointer to the default encoding (UTF-8) of the /* Returns a pointer to the default encoding (UTF-8) of the
@ -457,6 +577,10 @@ PyAPI_FUNC(PyObject*) PyUnicode_FromKindAndData(
PyAPI_FUNC(const char *) PyUnicode_AsUTF8(PyObject *unicode); PyAPI_FUNC(const char *) PyUnicode_AsUTF8(PyObject *unicode);
// Alias kept for backward compatibility
#define _PyUnicode_AsString PyUnicode_AsUTF8
/* === Characters Type APIs =============================================== */ /* === Characters Type APIs =============================================== */
/* These should not be used directly. Use the Py_UNICODE_IS* and /* These should not be used directly. Use the Py_UNICODE_IS* and
@ -570,3 +694,10 @@ static inline int Py_UNICODE_ISALNUM(Py_UCS4 ch) {
|| Py_UNICODE_ISDIGIT(ch) || Py_UNICODE_ISDIGIT(ch)
|| Py_UNICODE_ISNUMERIC(ch)); || Py_UNICODE_ISNUMERIC(ch));
} }
/* === Misc functions ===================================================== */
// Return an interned Unicode object for an Identifier; may fail if there is no
// memory.
PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*);

View File

@ -31,18 +31,6 @@ PyAPI_FUNC(PyObject*) _Py_CheckFunctionResult(
PyObject *result, PyObject *result,
const char *where); const char *where);
/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
format to a Python dictionary ("kwargs" dict).
The type of kwnames keys is not checked. The final function getting
arguments is responsible to check if all keys are strings, for example using
PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
Duplicate keys are merged using the last value. If duplicate keys must raise
an exception, the caller is responsible to implement an explicit keys on
kwnames. */
extern PyObject* _PyStack_AsDict(PyObject *const *values, PyObject *kwnames);
extern PyObject* _PyObject_Call_Prepend( extern PyObject* _PyObject_Call_Prepend(
PyThreadState *tstate, PyThreadState *tstate,
PyObject *callable, PyObject *callable,
@ -75,13 +63,6 @@ PyAPI_FUNC(PyObject*) _PyObject_CallMethod(
PyObject *name, PyObject *name,
const char *format, ...); const char *format, ...);
/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
as the method name. */
extern PyObject* _PyObject_CallMethodId(
PyObject *obj,
_Py_Identifier *name,
const char *format, ...);
extern PyObject* _PyObject_CallMethodIdObjArgs( extern PyObject* _PyObject_CallMethodIdObjArgs(
PyObject *obj, PyObject *obj,
_Py_Identifier *name, _Py_Identifier *name,

View File

@ -10,16 +10,6 @@ extern "C" {
#include "pycore_unicodeobject.h" // _PyUnicodeWriter #include "pycore_unicodeobject.h" // _PyUnicodeWriter
// Operations on complex numbers.
// Export functions for 'cmath' shared extension.
PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex);
PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex);
PyAPI_FUNC(double) _Py_c_abs(Py_complex);
/* Format the object based on the format_spec, as defined in PEP 3101 /* Format the object based on the format_spec, as defined in PEP 3101
(Advanced String Formatting). */ (Advanced String Formatting). */
extern int _PyComplex_FormatAdvancedWriter( extern int _PyComplex_FormatAdvancedWriter(

View File

@ -19,9 +19,6 @@ extern int _PyDict_DelItemIf(PyObject *mp, PyObject *key,
int (*predicate)(PyObject *value)); int (*predicate)(PyObject *value));
// "KnownHash" variants // "KnownHash" variants
// Export for '_testinternalcapi' shared extension
PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
Py_hash_t hash);
// Export for '_asyncio' shared extension // Export for '_asyncio' shared extension
PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key, PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key,
PyObject *item, Py_hash_t hash); PyObject *item, Py_hash_t hash);
@ -44,8 +41,6 @@ extern int _PyDict_HasOnlyStringKeys(PyObject *mp);
extern void _PyDict_MaybeUntrack(PyObject *mp); extern void _PyDict_MaybeUntrack(PyObject *mp);
extern PyObject* _PyDict_NewPresized(Py_ssize_t minused);
// Export for '_ctypes' shared extension // Export for '_ctypes' shared extension
PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *); PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *);

View File

@ -10,42 +10,8 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define" # error "this header requires Py_BUILD_CORE define"
#endif #endif
/* This structure helps managing static strings. The basic usage goes like this:
Instead of doing
r = PyObject_CallMethod(o, "foo", "args", ...);
do
_Py_IDENTIFIER(foo);
...
r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...);
PyId_foo is a static variable, either on block level or file level. On first
usage, the string "foo" is interned, and the structures are linked. On interpreter
shutdown, all strings are released.
Alternatively, _Py_static_string allows choosing the variable name.
_PyUnicode_FromId returns a borrowed reference to the interned string.
_PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*.
*/
typedef struct _Py_Identifier {
const char* string;
// Index in PyInterpreterState.unicode.ids.array. It is process-wide
// unique and must be initialized to -1.
Py_ssize_t index;
} _Py_Identifier;
// For now we are keeping _Py_IDENTIFIER for continued use
// in non-builtin extensions (and naughty PyPI modules).
#define _Py_static_string_init(value) { .string = (value), .index = -1 }
#define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value)
#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname)
extern PyObject* _PyType_LookupId(PyTypeObject *, _Py_Identifier *); extern PyObject* _PyType_LookupId(PyTypeObject *, _Py_Identifier *);
extern PyObject* _PyObject_LookupSpecialId(PyObject *, _Py_Identifier *); extern PyObject* _PyObject_LookupSpecialId(PyObject *, _Py_Identifier *);
extern PyObject* _PyObject_GetAttrId(PyObject *, _Py_Identifier *);
extern int _PyObject_SetAttrId(PyObject *, _Py_Identifier *, PyObject *); extern int _PyObject_SetAttrId(PyObject *, _Py_Identifier *, PyObject *);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -47,24 +47,6 @@ extern "C" {
# error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold." # error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold."
#endif #endif
extern PyLongObject* _PyLong_New(Py_ssize_t);
// Return a copy of src.
extern PyObject* _PyLong_Copy(PyLongObject *src);
// Export for '_decimal' shared extension
PyAPI_FUNC(PyLongObject*) _PyLong_FromDigits(
int negative,
Py_ssize_t digit_count,
digit *digits);
// _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.
// There are no error cases.
//
// Export for '_pickle' shared extension.
PyAPI_FUNC(int) _PyLong_Sign(PyObject *v);
// _PyLong_NumBits. Return the number of bits needed to represent the // _PyLong_NumBits. Return the number of bits needed to represent the
// absolute value of a long. For example, this returns 1 for 1 and -1, 2 // absolute value of a long. For example, this returns 1 for 1 and -1, 2
// for 2 and -2, and 2 for 3 and -3. It returns 0 for 0. // for 2 and -2, and 2 for 3 and -3. It returns 0 for 0.

View File

@ -5,35 +5,12 @@
# error "this header requires Py_BUILD_CORE define" # error "this header requires Py_BUILD_CORE define"
#endif #endif
/* Helpers for hash functions */
extern Py_hash_t _Py_HashDouble(PyObject *, double);
// Export for '_decimal' shared extension
PyAPI_FUNC(Py_hash_t) _Py_HashPointer(const void*);
// Similar to _Py_HashPointer(), but don't replace -1 with -2 // Similar to _Py_HashPointer(), but don't replace -1 with -2
extern Py_hash_t _Py_HashPointerRaw(const void*); extern Py_hash_t _Py_HashPointerRaw(const void*);
// Export for '_datetime' shared extension // Export for '_datetime' shared extension
PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t); PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t);
/* Prime multiplier used in string and various other hashes. */
#define _PyHASH_MULTIPLIER 1000003UL /* 0xf4243 */
/* Parameters used for the numeric hash implementation. See notes for
_Py_HashDouble in Python/pyhash.c. Numeric hashes are based on
reduction modulo the prime 2**_PyHASH_BITS - 1. */
#if SIZEOF_VOID_P >= 8
# define _PyHASH_BITS 61
#else
# define _PyHASH_BITS 31
#endif
#define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1)
#define _PyHASH_INF 314159
#define _PyHASH_IMAG _PyHASH_MULTIPLIER
/* Hash secret /* Hash secret
* *
* memory layout on 64 bit systems * memory layout on 64 bit systems

View File

@ -191,11 +191,6 @@ extern void _PyThreadState_DeleteExcept(PyThreadState *tstate);
// Export for '_testinternalcapi' shared extension // Export for '_testinternalcapi' shared extension
PyAPI_FUNC(PyObject*) _PyThreadState_GetDict(PyThreadState *tstate); PyAPI_FUNC(PyObject*) _PyThreadState_GetDict(PyThreadState *tstate);
/* The implementation of sys._current_frames() Returns a dict mapping
thread id to that thread's current frame.
*/
extern PyObject* _PyThread_CurrentFrames(void);
/* The implementation of sys._current_exceptions() Returns a dict mapping /* The implementation of sys._current_exceptions() Returns a dict mapping
thread id to that thread's current exception. thread id to that thread's current exception.
*/ */

View File

@ -73,122 +73,6 @@ extern Py_UCS4 _PyUnicode_FindMaxChar (
/* --- _PyUnicodeWriter API ----------------------------------------------- */ /* --- _PyUnicodeWriter API ----------------------------------------------- */
typedef struct {
PyObject *buffer;
void *data;
int kind;
Py_UCS4 maxchar;
Py_ssize_t size;
Py_ssize_t pos;
/* minimum number of allocated characters (default: 0) */
Py_ssize_t min_length;
/* minimum character (default: 127, ASCII) */
Py_UCS4 min_char;
/* If non-zero, overallocate the buffer (default: 0). */
unsigned char overallocate;
/* If readonly is 1, buffer is a shared string (cannot be modified)
and size is set to 0. */
unsigned char readonly;
} _PyUnicodeWriter ;
// Initialize a Unicode writer.
//
// By default, the minimum buffer size is 0 character and overallocation is
// disabled. Set min_length, min_char and overallocate attributes to control
// the allocation of the buffer.
//
// Export the _PyUnicodeWriter API for '_multibytecodec' shared extension.
PyAPI_FUNC(void)
_PyUnicodeWriter_Init(_PyUnicodeWriter *writer);
/* Prepare the buffer to write 'length' characters
with the specified maximum character.
Return 0 on success, raise an exception and return -1 on error. */
#define _PyUnicodeWriter_Prepare(WRITER, LENGTH, MAXCHAR) \
(((MAXCHAR) <= (WRITER)->maxchar \
&& (LENGTH) <= (WRITER)->size - (WRITER)->pos) \
? 0 \
: (((LENGTH) == 0) \
? 0 \
: _PyUnicodeWriter_PrepareInternal((WRITER), (LENGTH), (MAXCHAR))))
/* Don't call this function directly, use the _PyUnicodeWriter_Prepare() macro
instead. */
PyAPI_FUNC(int)
_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer,
Py_ssize_t length, Py_UCS4 maxchar);
/* Prepare the buffer to have at least the kind KIND.
For example, kind=PyUnicode_2BYTE_KIND ensures that the writer will
support characters in range U+000-U+FFFF.
Return 0 on success, raise an exception and return -1 on error. */
#define _PyUnicodeWriter_PrepareKind(WRITER, KIND) \
((KIND) <= (WRITER)->kind \
? 0 \
: _PyUnicodeWriter_PrepareKindInternal((WRITER), (KIND)))
/* Don't call this function directly, use the _PyUnicodeWriter_PrepareKind()
macro instead. */
PyAPI_FUNC(int)
_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer,
int kind);
/* Append a Unicode character.
Return 0 on success, raise an exception and return -1 on error. */
PyAPI_FUNC(int)
_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer,
Py_UCS4 ch
);
/* Append a Unicode string.
Return 0 on success, raise an exception and return -1 on error. */
PyAPI_FUNC(int)
_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer,
PyObject *str /* Unicode string */
);
/* Append a substring of a Unicode string.
Return 0 on success, raise an exception and return -1 on error. */
PyAPI_FUNC(int)
_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer,
PyObject *str, /* Unicode string */
Py_ssize_t start,
Py_ssize_t end
);
/* Append an ASCII-encoded byte string.
Return 0 on success, raise an exception and return -1 on error. */
PyAPI_FUNC(int)
_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer,
const char *str, /* ASCII-encoded byte string */
Py_ssize_t len /* number of bytes, or -1 if unknown */
);
/* Append a latin1-encoded byte string.
Return 0 on success, raise an exception and return -1 on error. */
PyAPI_FUNC(int)
_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer,
const char *str, /* latin1-encoded byte string */
Py_ssize_t len /* length in bytes */
);
/* Get the value of the writer as a Unicode string. Clear the
buffer of the writer. Raise an exception and return NULL
on error. */
PyAPI_FUNC(PyObject *)
_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer);
/* Deallocate memory of a writer (clear its internal buffer). */
PyAPI_FUNC(void)
_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer);
/* Format the object based on the format_spec, as defined in PEP 3101 /* Format the object based on the format_spec, as defined in PEP 3101
(Advanced String Formatting). */ (Advanced String Formatting). */
extern int _PyUnicode_FormatAdvancedWriter( extern int _PyUnicode_FormatAdvancedWriter(
@ -366,11 +250,6 @@ extern Py_ssize_t _PyUnicode_InsertThousandsGrouping(
extern PyObject* _PyUnicode_FormatLong(PyObject *, int, int, int); extern PyObject* _PyUnicode_FormatLong(PyObject *, int, int, int);
// Return an interned Unicode object for an Identifier; may fail if there is no
// memory.
// Export for '_testembed' program.
PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*);
/* Fast equality check when the inputs are known to be exact unicode types /* Fast equality check when the inputs are known to be exact unicode types
and where the hash values are equal (i.e. a very probable match) */ and where the hash values are equal (i.e. a very probable match) */
extern int _PyUnicode_EQ(PyObject *, PyObject *); extern int _PyUnicode_EQ(PyObject *, PyObject *);

View File

@ -112,6 +112,9 @@ check by comparing the reference count field to the immortality reference count.
#define _Py_IMMORTAL_REFCNT_LOCAL UINT32_MAX #define _Py_IMMORTAL_REFCNT_LOCAL UINT32_MAX
#endif #endif
// Kept for backward compatibility. It was needed by Py_TRACE_REFS build.
#define _PyObject_EXTRA_INIT
// Make all internal uses of PyObject_HEAD_INIT immortal while preserving the // Make all internal uses of PyObject_HEAD_INIT immortal while preserving the
// C-API expectation that the refcnt will be set to 1. // C-API expectation that the refcnt will be set to 1.
#if defined(Py_NOGIL) #if defined(Py_NOGIL)

View File

@ -0,0 +1,51 @@
Restore removed private C API functions, macros and structures which have no
simple replacement for now:
* _PyDict_GetItem_KnownHash()
* _PyDict_NewPresized()
* _PyHASH_BITS
* _PyHASH_IMAG
* _PyHASH_INF
* _PyHASH_MODULUS
* _PyHASH_MULTIPLIER
* _PyLong_Copy()
* _PyLong_FromDigits()
* _PyLong_New()
* _PyLong_Sign()
* _PyObject_CallMethodId()
* _PyObject_CallMethodNoArgs()
* _PyObject_CallMethodOneArg()
* _PyObject_CallOneArg()
* _PyObject_EXTRA_INIT
* _PyObject_FastCallDict()
* _PyObject_GetAttrId()
* _PyObject_Vectorcall()
* _PyObject_VectorcallMethod()
* _PyStack_AsDict()
* _PyThread_CurrentFrames()
* _PyUnicodeWriter structure
* _PyUnicodeWriter_Dealloc()
* _PyUnicodeWriter_Finish()
* _PyUnicodeWriter_Init()
* _PyUnicodeWriter_Prepare()
* _PyUnicodeWriter_PrepareKind()
* _PyUnicodeWriter_WriteASCIIString()
* _PyUnicodeWriter_WriteChar()
* _PyUnicodeWriter_WriteLatin1String()
* _PyUnicodeWriter_WriteStr()
* _PyUnicodeWriter_WriteSubstring()
* _PyUnicode_AsString()
* _PyUnicode_FromId()
* _PyVectorcall_Function()
* _Py_IDENTIFIER()
* _Py_c_abs()
* _Py_c_diff()
* _Py_c_neg()
* _Py_c_pow()
* _Py_c_prod()
* _Py_c_quot()
* _Py_c_sum()
* _Py_static_string()
* _Py_static_string_init()
Patch by Victor Stinner.

View File

@ -117,7 +117,7 @@ As a consequence of this, split keys have a maximum size of 16.
#include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_ceval.h" // _PyEval_GetBuiltin()
#include "pycore_code.h" // stats #include "pycore_code.h" // stats
#include "pycore_dict.h" // PyDictKeysObject #include "pycore_dict.h" // export _PyDict_SizeOf()
#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
#include "pycore_object.h" // _PyObject_GC_TRACK(), _PyDebugAllocatorStats() #include "pycore_object.h" // _PyObject_GC_TRACK(), _PyDebugAllocatorStats()
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException() #include "pycore_pyerrors.h" // _PyErr_GetRaisedException()