mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
gh-115754: Add Py_GetConstant() function (#116883)
Add Py_GetConstant() and Py_GetConstantBorrowed() functions. In the limited C API version 3.13, getting Py_None, Py_False, Py_True, Py_Ellipsis and Py_NotImplemented singletons is now implemented as function calls at the stable ABI level to hide implementation details. Getting these constants still return borrowed references. Add _testlimitedcapi/object.c and test_capi/test_object.py to test Py_GetConstant() and Py_GetConstantBorrowed() functions.
This commit is contained in:
parent
5a76d1be8e
commit
8bea6c411d
22 changed files with 312 additions and 6 deletions
|
@ -14,6 +14,7 @@
|
|||
#include "pycore_memoryobject.h" // _PyManagedBuffer_Type
|
||||
#include "pycore_namespace.h" // _PyNamespace_Type
|
||||
#include "pycore_object.h" // PyAPI_DATA() _Py_SwappedOp definition
|
||||
#include "pycore_long.h" // _PyLong_GetZero()
|
||||
#include "pycore_optimizer.h" // _PyUOpExecutor_Type, _PyUOpOptimizer_Type, ...
|
||||
#include "pycore_pyerrors.h" // _PyErr_Occurred()
|
||||
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
|
||||
|
@ -2991,3 +2992,53 @@ _Py_SetRefcnt(PyObject *ob, Py_ssize_t refcnt)
|
|||
{
|
||||
Py_SET_REFCNT(ob, refcnt);
|
||||
}
|
||||
|
||||
|
||||
static PyObject* constants[] = {
|
||||
&_Py_NoneStruct, // Py_CONSTANT_NONE
|
||||
(PyObject*)(&_Py_FalseStruct), // Py_CONSTANT_FALSE
|
||||
(PyObject*)(&_Py_TrueStruct), // Py_CONSTANT_TRUE
|
||||
&_Py_EllipsisObject, // Py_CONSTANT_ELLIPSIS
|
||||
&_Py_NotImplementedStruct, // Py_CONSTANT_NOT_IMPLEMENTED
|
||||
NULL, // Py_CONSTANT_ZERO
|
||||
NULL, // Py_CONSTANT_ONE
|
||||
NULL, // Py_CONSTANT_EMPTY_STR
|
||||
NULL, // Py_CONSTANT_EMPTY_BYTES
|
||||
NULL, // Py_CONSTANT_EMPTY_TUPLE
|
||||
};
|
||||
|
||||
void
|
||||
_Py_GetConstant_Init(void)
|
||||
{
|
||||
constants[Py_CONSTANT_ZERO] = _PyLong_GetZero();
|
||||
constants[Py_CONSTANT_ONE] = _PyLong_GetOne();
|
||||
constants[Py_CONSTANT_EMPTY_STR] = PyUnicode_New(0, 0);
|
||||
constants[Py_CONSTANT_EMPTY_BYTES] = PyBytes_FromStringAndSize(NULL, 0);
|
||||
constants[Py_CONSTANT_EMPTY_TUPLE] = PyTuple_New(0);
|
||||
#ifndef NDEBUG
|
||||
for (size_t i=0; i < Py_ARRAY_LENGTH(constants); i++) {
|
||||
assert(constants[i] != NULL);
|
||||
assert(_Py_IsImmortal(constants[i]));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
PyObject*
|
||||
Py_GetConstant(unsigned int constant_id)
|
||||
{
|
||||
if (constant_id < Py_ARRAY_LENGTH(constants)) {
|
||||
return constants[constant_id];
|
||||
}
|
||||
else {
|
||||
PyErr_BadInternalCall();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PyObject*
|
||||
Py_GetConstantBorrowed(unsigned int constant_id)
|
||||
{
|
||||
// All constants are immortal
|
||||
return Py_GetConstant(constant_id);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue