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 5846924

Browse filesBrowse files
authored
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()
1 parent b338ffa commit 5846924
Copy full SHA for 5846924
Expand file treeCollapse file tree

20 files changed

+315
-236
lines changed

‎Include/cpython/abstract.h

Copy file name to clipboardExpand all lines: Include/cpython/abstract.h
+32Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,28 @@
22
# error "this header file must not be included directly"
33
#endif
44

5+
/* === Object Protocol ================================================== */
6+
7+
/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
8+
as the method name. */
9+
PyAPI_FUNC(PyObject*) _PyObject_CallMethodId(
10+
PyObject *obj,
11+
_Py_Identifier *name,
12+
const char *format, ...);
13+
14+
/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
15+
format to a Python dictionary ("kwargs" dict).
16+
17+
The type of kwnames keys is not checked. The final function getting
18+
arguments is responsible to check if all keys are strings, for example using
19+
PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
20+
21+
Duplicate keys are merged using the last value. If duplicate keys must raise
22+
an exception, the caller is responsible to implement an explicit keys on
23+
kwnames. */
24+
PyAPI_FUNC(PyObject*) _PyStack_AsDict(PyObject *const *values, PyObject *kwnames);
25+
26+
527
/* === Vectorcall protocol (PEP 590) ============================= */
628

729
// PyVectorcall_NARGS() is exported as a function for the stable ABI.
@@ -16,6 +38,16 @@ _PyVectorcall_NARGS(size_t n)
1638

1739
PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable);
1840

41+
// Backwards compatibility aliases (PEP 590) for API that was provisional
42+
// in Python 3.8
43+
#define _PyObject_Vectorcall PyObject_Vectorcall
44+
#define _PyObject_VectorcallMethod PyObject_VectorcallMethod
45+
#define _PyObject_FastCallDict PyObject_VectorcallDict
46+
#define _PyVectorcall_Function PyVectorcall_Function
47+
#define _PyObject_CallOneArg PyObject_CallOneArg
48+
#define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs
49+
#define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg
50+
1951
/* Same as PyObject_Vectorcall except that keyword arguments are passed as
2052
dict, which may be NULL if there are no keyword arguments. */
2153
PyAPI_FUNC(PyObject *) PyObject_VectorcallDict(

‎Include/cpython/complexobject.h

Copy file name to clipboardExpand all lines: Include/cpython/complexobject.h
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ typedef struct {
77
double imag;
88
} Py_complex;
99

10+
// Operations on complex numbers.
11+
PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex);
12+
PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex);
13+
PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex);
14+
PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex);
15+
PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex);
16+
PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex);
17+
PyAPI_FUNC(double) _Py_c_abs(Py_complex);
18+
19+
1020
/* Complex object interface */
1121

1222
/*

‎Include/cpython/dictobject.h

Copy file name to clipboardExpand all lines: Include/cpython/dictobject.h
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ typedef struct {
3232
PyDictValues *ma_values;
3333
} PyDictObject;
3434

35+
PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
36+
Py_hash_t hash);
37+
3538
PyAPI_FUNC(PyObject *) PyDict_SetDefault(
3639
PyObject *mp, PyObject *key, PyObject *defaultobj);
3740

@@ -46,6 +49,8 @@ static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) {
4649

4750
PyAPI_FUNC(int) PyDict_ContainsString(PyObject *mp, const char *key);
4851

52+
PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
53+
4954
PyAPI_FUNC(int) PyDict_Pop(PyObject *dict, PyObject *key, PyObject **result);
5055
PyAPI_FUNC(int) PyDict_PopString(PyObject *dict, const char *key, PyObject **result);
5156
PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value);

‎Include/cpython/longintrepr.h

Copy file name to clipboardExpand all lines: Include/cpython/longintrepr.h
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,16 @@ struct _longobject {
8989
_PyLongValue long_value;
9090
};
9191

92+
PyAPI_FUNC(PyLongObject*) _PyLong_New(Py_ssize_t);
93+
94+
// Return a copy of src.
95+
PyAPI_FUNC(PyObject*) _PyLong_Copy(PyLongObject *src);
96+
97+
PyAPI_FUNC(PyLongObject*) _PyLong_FromDigits(
98+
int negative,
99+
Py_ssize_t digit_count,
100+
digit *digits);
101+
92102

93103
/* Inline some internals for speed. These should be in pycore_long.h
94104
* if user code didn't need them inlined. */

‎Include/cpython/longobject.h

Copy file name to clipboardExpand all lines: Include/cpython/longobject.h
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ PyAPI_FUNC(PyObject*) PyLong_FromUnicodeObject(PyObject *u, int base);
77
PyAPI_FUNC(int) PyUnstable_Long_IsCompact(const PyLongObject* op);
88
PyAPI_FUNC(Py_ssize_t) PyUnstable_Long_CompactValue(const PyLongObject* op);
99

10+
// _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0.
11+
// v must not be NULL, and must be a normalized long.
12+
// There are no error cases.
13+
PyAPI_FUNC(int) _PyLong_Sign(PyObject *v);
14+
1015
/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in
1116
base 256, and return a Python int with the same numeric value.
1217
If n is 0, the integer is 0. Else:

‎Include/cpython/object.h

Copy file name to clipboardExpand all lines: Include/cpython/object.h
+40Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,44 @@ PyAPI_FUNC(Py_ssize_t) _PyInterpreterState_GetRefTotal(PyInterpreterState *);
1414
#endif
1515

1616

17+
/********************* String Literals ****************************************/
18+
/* This structure helps managing static strings. The basic usage goes like this:
19+
Instead of doing
20+
21+
r = PyObject_CallMethod(o, "foo", "args", ...);
22+
23+
do
24+
25+
_Py_IDENTIFIER(foo);
26+
...
27+
r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...);
28+
29+
PyId_foo is a static variable, either on block level or file level. On first
30+
usage, the string "foo" is interned, and the structures are linked. On interpreter
31+
shutdown, all strings are released.
32+
33+
Alternatively, _Py_static_string allows choosing the variable name.
34+
_PyUnicode_FromId returns a borrowed reference to the interned string.
35+
_PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*.
36+
*/
37+
typedef struct _Py_Identifier {
38+
const char* string;
39+
// Index in PyInterpreterState.unicode.ids.array. It is process-wide
40+
// unique and must be initialized to -1.
41+
Py_ssize_t index;
42+
} _Py_Identifier;
43+
44+
#ifndef Py_BUILD_CORE
45+
// For now we are keeping _Py_IDENTIFIER for continued use
46+
// in non-builtin extensions (and naughty PyPI modules).
47+
48+
#define _Py_static_string_init(value) { .string = (value), .index = -1 }
49+
#define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value)
50+
#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname)
51+
52+
#endif /* !Py_BUILD_CORE */
53+
54+
1755
typedef struct {
1856
/* Number implementations must check *both*
1957
arguments for proper type and implement the necessary conversions
@@ -238,6 +276,8 @@ PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
238276
PyAPI_FUNC(void) _Py_BreakPoint(void);
239277
PyAPI_FUNC(void) _PyObject_Dump(PyObject *);
240278

279+
PyAPI_FUNC(PyObject*) _PyObject_GetAttrId(PyObject *, _Py_Identifier *);
280+
241281
PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
242282
PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *);
243283
PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *);

‎Include/cpython/pyhash.h

Copy file name to clipboardExpand all lines: Include/cpython/pyhash.h
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,28 @@
22
# error "this header file must not be included directly"
33
#endif
44

5+
/* Prime multiplier used in string and various other hashes. */
6+
#define _PyHASH_MULTIPLIER 1000003UL /* 0xf4243 */
7+
8+
/* Parameters used for the numeric hash implementation. See notes for
9+
_Py_HashDouble in Python/pyhash.c. Numeric hashes are based on
10+
reduction modulo the prime 2**_PyHASH_BITS - 1. */
11+
12+
#if SIZEOF_VOID_P >= 8
13+
# define _PyHASH_BITS 61
14+
#else
15+
# define _PyHASH_BITS 31
16+
#endif
17+
18+
#define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1)
19+
#define _PyHASH_INF 314159
20+
#define _PyHASH_IMAG _PyHASH_MULTIPLIER
21+
22+
/* Helpers for hash functions */
23+
PyAPI_FUNC(Py_hash_t) _Py_HashDouble(PyObject *, double);
24+
PyAPI_FUNC(Py_hash_t) _Py_HashPointer(const void*);
25+
26+
527
/* hash function definition */
628
typedef struct {
729
Py_hash_t (*const hash)(const void *, Py_ssize_t);

‎Include/cpython/pystate.h

Copy file name to clipboardExpand all lines: Include/cpython/pystate.h
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,11 @@ PyAPI_FUNC(void) PyThreadState_LeaveTracing(PyThreadState *tstate);
247247
The function returns 1 if _PyGILState_check_enabled is non-zero. */
248248
PyAPI_FUNC(int) PyGILState_Check(void);
249249

250+
/* The implementation of sys._current_frames() Returns a dict mapping
251+
thread id to that thread's current frame.
252+
*/
253+
PyAPI_FUNC(PyObject*) _PyThread_CurrentFrames(void);
254+
250255
/* Routines for advanced debuggers, requested by David Beazley.
251256
Don't use unless you know what you are doing! */
252257
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void);

‎Include/cpython/unicodeobject.h

Copy file name to clipboardExpand all lines: Include/cpython/unicodeobject.h
+131Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
Py_DEPRECATED(3.13) typedef wchar_t PY_UNICODE_TYPE;
1010
Py_DEPRECATED(3.13) typedef wchar_t Py_UNICODE;
1111

12+
1213
/* --- Internal Unicode Operations ---------------------------------------- */
1314

1415
// Static inline functions to work with surrogates
@@ -43,6 +44,7 @@ static inline Py_UCS4 Py_UNICODE_LOW_SURROGATE(Py_UCS4 ch) {
4344
return (0xDC00 + (ch & 0x3FF));
4445
}
4546

47+
4648
/* --- Unicode Type ------------------------------------------------------- */
4749

4850
/* ASCII-only strings created through PyUnicode_New use the PyASCIIObject
@@ -375,6 +377,7 @@ static inline Py_UCS4 PyUnicode_MAX_CHAR_VALUE(PyObject *op)
375377
#define PyUnicode_MAX_CHAR_VALUE(op) \
376378
PyUnicode_MAX_CHAR_VALUE(_PyObject_CAST(op))
377379

380+
378381
/* === Public API ========================================================= */
379382

380383
/* With PEP 393, this is the recommended way to allocate a new unicode object.
@@ -440,6 +443,123 @@ PyAPI_FUNC(PyObject*) PyUnicode_FromKindAndData(
440443
const void *buffer,
441444
Py_ssize_t size);
442445

446+
447+
/* --- _PyUnicodeWriter API ----------------------------------------------- */
448+
449+
typedef struct {
450+
PyObject *buffer;
451+
void *data;
452+
int kind;
453+
Py_UCS4 maxchar;
454+
Py_ssize_t size;
455+
Py_ssize_t pos;
456+
457+
/* minimum number of allocated characters (default: 0) */
458+
Py_ssize_t min_length;
459+
460+
/* minimum character (default: 127, ASCII) */
461+
Py_UCS4 min_char;
462+
463+
/* If non-zero, overallocate the buffer (default: 0). */
464+
unsigned char overallocate;
465+
466+
/* If readonly is 1, buffer is a shared string (cannot be modified)
467+
and size is set to 0. */
468+
unsigned char readonly;
469+
} _PyUnicodeWriter ;
470+
471+
// Initialize a Unicode writer.
472+
//
473+
// By default, the minimum buffer size is 0 character and overallocation is
474+
// disabled. Set min_length, min_char and overallocate attributes to control
475+
// the allocation of the buffer.
476+
PyAPI_FUNC(void)
477+
_PyUnicodeWriter_Init(_PyUnicodeWriter *writer);
478+
479+
/* Prepare the buffer to write 'length' characters
480+
with the specified maximum character.
481+
482+
Return 0 on success, raise an exception and return -1 on error. */
483+
#define _PyUnicodeWriter_Prepare(WRITER, LENGTH, MAXCHAR) \
484+
(((MAXCHAR) <= (WRITER)->maxchar \
485+
&& (LENGTH) <= (WRITER)->size - (WRITER)->pos) \
486+
? 0 \
487+
: (((LENGTH) == 0) \
488+
? 0 \
489+
: _PyUnicodeWriter_PrepareInternal((WRITER), (LENGTH), (MAXCHAR))))
490+
491+
/* Don't call this function directly, use the _PyUnicodeWriter_Prepare() macro
492+
instead. */
493+
PyAPI_FUNC(int)
494+
_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer,
495+
Py_ssize_t length, Py_UCS4 maxchar);
496+
497+
/* Prepare the buffer to have at least the kind KIND.
498+
For example, kind=PyUnicode_2BYTE_KIND ensures that the writer will
499+
support characters in range U+000-U+FFFF.
500+
501+
Return 0 on success, raise an exception and return -1 on error. */
502+
#define _PyUnicodeWriter_PrepareKind(WRITER, KIND) \
503+
((KIND) <= (WRITER)->kind \
504+
? 0 \
505+
: _PyUnicodeWriter_PrepareKindInternal((WRITER), (KIND)))
506+
507+
/* Don't call this function directly, use the _PyUnicodeWriter_PrepareKind()
508+
macro instead. */
509+
PyAPI_FUNC(int)
510+
_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer,
511+
int kind);
512+
513+
/* Append a Unicode character.
514+
Return 0 on success, raise an exception and return -1 on error. */
515+
PyAPI_FUNC(int)
516+
_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer,
517+
Py_UCS4 ch
518+
);
519+
520+
/* Append a Unicode string.
521+
Return 0 on success, raise an exception and return -1 on error. */
522+
PyAPI_FUNC(int)
523+
_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer,
524+
PyObject *str /* Unicode string */
525+
);
526+
527+
/* Append a substring of a Unicode string.
528+
Return 0 on success, raise an exception and return -1 on error. */
529+
PyAPI_FUNC(int)
530+
_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer,
531+
PyObject *str, /* Unicode string */
532+
Py_ssize_t start,
533+
Py_ssize_t end
534+
);
535+
536+
/* Append an ASCII-encoded byte string.
537+
Return 0 on success, raise an exception and return -1 on error. */
538+
PyAPI_FUNC(int)
539+
_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer,
540+
const char *str, /* ASCII-encoded byte string */
541+
Py_ssize_t len /* number of bytes, or -1 if unknown */
542+
);
543+
544+
/* Append a latin1-encoded byte string.
545+
Return 0 on success, raise an exception and return -1 on error. */
546+
PyAPI_FUNC(int)
547+
_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer,
548+
const char *str, /* latin1-encoded byte string */
549+
Py_ssize_t len /* length in bytes */
550+
);
551+
552+
/* Get the value of the writer as a Unicode string. Clear the
553+
buffer of the writer. Raise an exception and return NULL
554+
on error. */
555+
PyAPI_FUNC(PyObject *)
556+
_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer);
557+
558+
/* Deallocate memory of a writer (clear its internal buffer). */
559+
PyAPI_FUNC(void)
560+
_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer);
561+
562+
443563
/* --- Manage the default encoding ---------------------------------------- */
444564

445565
/* Returns a pointer to the default encoding (UTF-8) of the
@@ -457,6 +577,10 @@ PyAPI_FUNC(PyObject*) PyUnicode_FromKindAndData(
457577

458578
PyAPI_FUNC(const char *) PyUnicode_AsUTF8(PyObject *unicode);
459579

580+
// Alias kept for backward compatibility
581+
#define _PyUnicode_AsString PyUnicode_AsUTF8
582+
583+
460584
/* === Characters Type APIs =============================================== */
461585

462586
/* 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) {
570694
|| Py_UNICODE_ISDIGIT(ch)
571695
|| Py_UNICODE_ISNUMERIC(ch));
572696
}
697+
698+
699+
/* === Misc functions ===================================================== */
700+
701+
// Return an interned Unicode object for an Identifier; may fail if there is no
702+
// memory.
703+
PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*);

0 commit comments

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