]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-112026: Restore removed private C API (#112115)
authorVictor Stinner <vstinner@python.org>
Wed, 15 Nov 2023 16:38:31 +0000 (17:38 +0100)
committerGitHub <noreply@github.com>
Wed, 15 Nov 2023 16:38:31 +0000 (16:38 +0000)
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()

20 files changed:
Include/cpython/abstract.h
Include/cpython/complexobject.h
Include/cpython/dictobject.h
Include/cpython/longintrepr.h
Include/cpython/longobject.h
Include/cpython/object.h
Include/cpython/pyhash.h
Include/cpython/pystate.h
Include/cpython/unicodeobject.h
Include/internal/pycore_call.h
Include/internal/pycore_complexobject.h
Include/internal/pycore_dict.h
Include/internal/pycore_identifier.h
Include/internal/pycore_long.h
Include/internal/pycore_pyhash.h
Include/internal/pycore_pystate.h
Include/internal/pycore_unicodeobject.h
Include/object.h
Misc/NEWS.d/next/C API/2023-11-15-16-07-57.gh-issue-112026.bnr8dd.rst [new file with mode: 0644]
Objects/dictobject.c

index 1f495f19df280b128b067293c348f361ecec6d11..4e7b7a46703a6d08a3d73b16d1bfb7e164d53afb 100644 (file)
@@ -2,6 +2,28 @@
 #  error "this header file must not be included directly"
 #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) ============================= */
 
 // 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);
 
+// 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
    dict, which may be NULL if there are no keyword arguments. */
 PyAPI_FUNC(PyObject *) PyObject_VectorcallDict(
index b524ec42c24371cbd10a938664d0811fe89c48d6..fbdc6a91fe895c0f7af0bff6a3836a1991709c20 100644 (file)
@@ -7,6 +7,16 @@ typedef struct {
     double imag;
 } 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 */
 
 /*
index 64753849d320612dbabc7a9c6945bd230252eb27..91ddc081e2d0136a16dd6d4baee79b05350c3879 100644 (file)
@@ -32,6 +32,9 @@ typedef struct {
     PyDictValues *ma_values;
 } PyDictObject;
 
+PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
+                                                 Py_hash_t hash);
+
 PyAPI_FUNC(PyObject *) PyDict_SetDefault(
     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(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
+
 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(PyObject *) _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value);
index fb82f83dc50e427183b2032f352ecd2d694e4e65..f5ccbb704e8bb8ecae80856d73c27a9e76498c6d 100644 (file)
@@ -89,6 +89,16 @@ struct _longobject {
     _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
  * if user code didn't need them inlined. */
index ab885cf5ad03fd0d5f8b9152af0dda781764dd54..fd1be29ed397d181bfd67cc155742b20a9c599f6 100644 (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(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
    base 256, and return a Python int with the same numeric value.
    If n is 0, the integer is 0.  Else:
index ede394d9673d7e1d3da2125496ca12464722957a..762e8a3b86ee1e535fec4b1162580797ff31e975 100644 (file)
@@ -14,6 +14,44 @@ PyAPI_FUNC(Py_ssize_t) _PyInterpreterState_GetRefTotal(PyInterpreterState *);
 #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 {
     /* Number implementations must check *both*
        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) _PyObject_Dump(PyObject *);
 
+PyAPI_FUNC(PyObject*) _PyObject_GetAttrId(PyObject *, _Py_Identifier *);
+
 PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
 PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *);
 PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *);
index 62ae6084bbcf533fc34adbdbe29b0c03ccbf051c..6f7113daa5fe4de8c701e0df301a970831c681d7 100644 (file)
@@ -2,6 +2,28 @@
 #  error "this header file must not be included directly"
 #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 */
 typedef struct {
     Py_hash_t (*const hash)(const void *, Py_ssize_t);
index 4fad4c60abbafe89d2dbefaac614a624c0fea37b..7f2378ae76fe5c31d992544705459857a0db2e7c 100644 (file)
@@ -247,6 +247,11 @@ PyAPI_FUNC(void) PyThreadState_LeaveTracing(PyThreadState *tstate);
    The function returns 1 if _PyGILState_check_enabled is non-zero. */
 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.
    Don't use unless you know what you are doing! */
 PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void);
index cd56a6a74acf51d1633dfe2d08d42e82e83a33d2..d9b54bce83202daf4297e5009caafcf0e22eb018 100644 (file)
@@ -9,6 +9,7 @@
 Py_DEPRECATED(3.13) typedef wchar_t PY_UNICODE_TYPE;
 Py_DEPRECATED(3.13) typedef wchar_t Py_UNICODE;
 
+
 /* --- Internal Unicode Operations ---------------------------------------- */
 
 // 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));
 }
 
+
 /* --- Unicode Type ------------------------------------------------------- */
 
 /* 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) \
     PyUnicode_MAX_CHAR_VALUE(_PyObject_CAST(op))
 
+
 /* === Public API ========================================================= */
 
 /* 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,
     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 ---------------------------------------- */
 
 /* 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);
 
+// Alias kept for backward compatibility
+#define _PyUnicode_AsString PyUnicode_AsUTF8
+
+
 /* === Characters Type APIs =============================================== */
 
 /* 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_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*);
index 8846155b38defb73610605d83a69c1f3171cd417..c92028a01299e2d8090b37fe85947678579aca3e 100644 (file)
@@ -31,18 +31,6 @@ PyAPI_FUNC(PyObject*) _Py_CheckFunctionResult(
     PyObject *result,
     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(
     PyThreadState *tstate,
     PyObject *callable,
@@ -75,13 +63,6 @@ PyAPI_FUNC(PyObject*) _PyObject_CallMethod(
     PyObject *name,
     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(
     PyObject *obj,
     _Py_Identifier *name,
index a6fee9d23f3a9f20bafe5a275ac70b987ca7f66e..54713536eedc462ce82400fd0fa0767dd9c0751d 100644 (file)
@@ -10,16 +10,6 @@ extern "C" {
 
 #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
    (Advanced String Formatting). */
 extern int _PyComplex_FormatAdvancedWriter(
index 89f30a452c0c643fb8d35d19d89f29a923de85c0..d96870e9197bbf0d8000da7eae5a4bb2efee20b0 100644 (file)
@@ -19,9 +19,6 @@ extern int _PyDict_DelItemIf(PyObject *mp, PyObject *key,
                              int (*predicate)(PyObject *value));
 
 // "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
 PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key,
                                           PyObject *item, Py_hash_t hash);
@@ -44,8 +41,6 @@ extern int _PyDict_HasOnlyStringKeys(PyObject *mp);
 
 extern void _PyDict_MaybeUntrack(PyObject *mp);
 
-extern PyObject* _PyDict_NewPresized(Py_ssize_t minused);
-
 // Export for '_ctypes' shared extension
 PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *);
 
index 0e015a40c831f47836986d2273537250cbced5be..cda28810a48196227bcb54bf5028f18e6bb34e42 100644 (file)
@@ -10,42 +10,8 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #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* _PyObject_LookupSpecialId(PyObject *, _Py_Identifier *);
-extern PyObject* _PyObject_GetAttrId(PyObject *, _Py_Identifier *);
 extern int _PyObject_SetAttrId(PyObject *, _Py_Identifier *, PyObject *);
 
 #ifdef __cplusplus
index c4ef6eff37b19948876d60fc26c0840117c20f69..ec27df9e416c58c295cae351bce338fcb4ff7951 100644 (file)
@@ -47,24 +47,6 @@ extern "C" {
 # error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold."
 #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
 // 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.
index 78bf0c7d07eb105ecb77186ac6e666bca63d68ab..c3b72d90de3a694c29feb07db07c394c7d21972b 100644 (file)
@@ -5,35 +5,12 @@
 #  error "this header requires Py_BUILD_CORE define"
 #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
 extern Py_hash_t _Py_HashPointerRaw(const void*);
 
 // Export for '_datetime' shared extension
 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
  *
  * memory layout on 64 bit systems
index 7135b1e966feb5b6c6897fed6e575423472360f2..7fa952e371d7b46bd457381e0b0e65191ffd029d 100644 (file)
@@ -191,11 +191,6 @@ extern void _PyThreadState_DeleteExcept(PyThreadState *tstate);
 // Export for '_testinternalcapi' shared extension
 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
    thread id to that thread's current exception.
 */
index 23e2670d3a36afa50ff3da44dab7ed6ae5eeabb1..a0d00af92e0f5d744cd3995b19eecc2ea95b3b4a 100644 (file)
@@ -73,122 +73,6 @@ extern Py_UCS4 _PyUnicode_FindMaxChar (
 
 /* --- _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
    (Advanced String Formatting). */
 extern int _PyUnicode_FormatAdvancedWriter(
@@ -366,11 +250,6 @@ extern Py_ssize_t _PyUnicode_InsertThousandsGrouping(
 
 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
    and where the hash values are equal (i.e. a very probable match) */
 extern int _PyUnicode_EQ(PyObject *, PyObject *);
index f6693562d211c5f93f7808b44dbe263f8d1a6a17..061b5093fb1a350bdf804ad0d3d217da17d86043 100644 (file)
@@ -112,6 +112,9 @@ check by comparing the reference count field to the immortality reference count.
 #define _Py_IMMORTAL_REFCNT_LOCAL UINT32_MAX
 #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
 // C-API expectation that the refcnt will be set to 1.
 #if defined(Py_NOGIL)
diff --git a/Misc/NEWS.d/next/C API/2023-11-15-16-07-57.gh-issue-112026.bnr8dd.rst b/Misc/NEWS.d/next/C API/2023-11-15-16-07-57.gh-issue-112026.bnr8dd.rst
new file mode 100644 (file)
index 0000000..5dbbde8
--- /dev/null
@@ -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.
index d3d16c59f0ea7c7840c906696f5930d20b2d6fd5..556c74db6f6a23cbf9e274b906b54edc40529856 100644 (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_ceval.h"         // _PyEval_GetBuiltin()
 #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_object.h"        // _PyObject_GC_TRACK(), _PyDebugAllocatorStats()
 #include "pycore_pyerrors.h"      // _PyErr_GetRaisedException()