Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commitb16ff9a

Browse files
authored
Add Py_GetConstant() and Py_GetConstantBorrowed() (#87)
1 parent7000d0e commitb16ff9a

File tree

4 files changed

+177
-0
lines changed

4 files changed

+177
-0
lines changed

‎docs/api.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,15 @@ Python 3.12
192192
193193
Not available on PyPy.
194194
195+
..c:function:: PyObject*Py_GetConstant(unsigned int constant_id)
196+
197+
See `Py_GetConstant() documentation <https://docs.python.org/dev/c-api/object.html#c.Py_GetConstant>`__.
198+
199+
.. c:function:: PyObject* Py_GetConstantBorrowed(unsigned int constant_id)
200+
201+
See `Py_GetConstantBorrowed() documentation <https://docs.python.org/dev/c-api/object.html#c.Py_GetConstantBorrowed>`__.
202+
203+
195204
Not supported:
196205
197206
* ``PyDict_AddWatcher()``, ``PyDict_Watch()``.

‎docs/changelog.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
Changelog
22
=========
33

4+
* 2024-03-21: Add functions:
5+
6+
* ``Py_GetConstant()``
7+
* ``Py_GetConstantBorrowed()``
8+
49
* 2024-03-09: Add hash constants:
510

611
* ``PyHASH_BITS``

‎pythoncapi_compat.h

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,83 @@ static inline int PyTime_PerfCounter(PyTime_t *result)
12091209
#endif
12101210

12111211

1212+
// gh-111545 added Py_GetConstant() and Py_GetConstantBorrowed()
1213+
// to Python 3.13.0a6
1214+
#if PY_VERSION_HEX < 0x030D00A6
1215+
1216+
#definePy_CONSTANT_NONE0
1217+
#definePy_CONSTANT_FALSE1
1218+
#definePy_CONSTANT_TRUE2
1219+
#definePy_CONSTANT_ELLIPSIS3
1220+
#definePy_CONSTANT_NOT_IMPLEMENTED4
1221+
#definePy_CONSTANT_ZERO5
1222+
#definePy_CONSTANT_ONE6
1223+
#definePy_CONSTANT_EMPTY_STR7
1224+
#definePy_CONSTANT_EMPTY_BYTES8
1225+
#definePy_CONSTANT_EMPTY_TUPLE9
1226+
1227+
staticinline PyObject*Py_GetConstant(unsignedint constant_id)
1228+
{
1229+
static PyObject* constants[Py_CONSTANT_EMPTY_TUPLE +1] = {NULL};
1230+
1231+
if (constants[Py_CONSTANT_NONE] ==NULL) {
1232+
constants[Py_CONSTANT_NONE] = Py_None;
1233+
constants[Py_CONSTANT_FALSE] = Py_False;
1234+
constants[Py_CONSTANT_TRUE] = Py_True;
1235+
constants[Py_CONSTANT_ELLIPSIS] = Py_Ellipsis;
1236+
constants[Py_CONSTANT_NOT_IMPLEMENTED] = Py_NotImplemented;
1237+
1238+
constants[Py_CONSTANT_ZERO] =PyLong_FromLong(0);
1239+
if (constants[Py_CONSTANT_ZERO] ==NULL) {
1240+
goto fatal_error;
1241+
}
1242+
1243+
constants[Py_CONSTANT_ONE] =PyLong_FromLong(1);
1244+
if (constants[Py_CONSTANT_ONE] ==NULL) {
1245+
goto fatal_error;
1246+
}
1247+
1248+
constants[Py_CONSTANT_EMPTY_STR] =PyUnicode_FromStringAndSize("",0);
1249+
if (constants[Py_CONSTANT_EMPTY_STR] ==NULL) {
1250+
goto fatal_error;
1251+
}
1252+
1253+
constants[Py_CONSTANT_EMPTY_BYTES] =PyBytes_FromStringAndSize("",0);
1254+
if (constants[Py_CONSTANT_EMPTY_BYTES] ==NULL) {
1255+
goto fatal_error;
1256+
}
1257+
1258+
constants[Py_CONSTANT_EMPTY_TUPLE] =PyTuple_New(0);
1259+
if (constants[Py_CONSTANT_EMPTY_TUPLE] ==NULL) {
1260+
goto fatal_error;
1261+
}
1262+
// goto dance to avoid compiler warnings about Py_FatalError()
1263+
goto init_done;
1264+
1265+
fatal_error:
1266+
// This case should never happen
1267+
Py_FatalError("Py_GetConstant() failed to get constants");
1268+
}
1269+
1270+
init_done:
1271+
if (constant_id <= Py_CONSTANT_EMPTY_TUPLE) {
1272+
returnPy_NewRef(constants[constant_id]);
1273+
}
1274+
else {
1275+
PyErr_BadInternalCall();
1276+
returnNULL;
1277+
}
1278+
}
1279+
1280+
staticinline PyObject*Py_GetConstantBorrowed(unsignedint constant_id)
1281+
{
1282+
PyObject *obj =Py_GetConstant(constant_id);
1283+
Py_XDECREF(obj);
1284+
return obj;
1285+
}
1286+
#endif
1287+
1288+
12121289
#ifdef __cplusplus
12131290
}
12141291
#endif

‎tests/test_pythoncapi_compat_cext.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,6 +1573,91 @@ test_time(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
15731573
#endif
15741574

15751575

1576+
staticvoid
1577+
check_get_constant(PyObject* (*get_constant)(unsignedint),intborrowed)
1578+
{
1579+
#defineCLEAR(var) if (!borrowed) { Py_DECREF(var); }
1580+
1581+
PyObject*obj,*expected;
1582+
1583+
// Py_CONSTANT_NONE
1584+
obj=get_constant(Py_CONSTANT_NONE);
1585+
assert(obj==Py_None);
1586+
CLEAR(obj);
1587+
1588+
// Py_CONSTANT_FALSE
1589+
obj=get_constant(Py_CONSTANT_FALSE);
1590+
assert(obj=Py_False);
1591+
CLEAR(obj);
1592+
1593+
// Py_CONSTANT_TRUE
1594+
obj=get_constant(Py_CONSTANT_TRUE);
1595+
assert(obj==Py_True);
1596+
CLEAR(obj);
1597+
1598+
// Py_CONSTANT_ELLIPSIS
1599+
obj=get_constant(Py_CONSTANT_ELLIPSIS);
1600+
assert(obj==Py_Ellipsis);
1601+
CLEAR(obj);
1602+
1603+
// Py_CONSTANT_NOT_IMPLEMENTED
1604+
obj=get_constant(Py_CONSTANT_NOT_IMPLEMENTED);
1605+
assert(obj==Py_NotImplemented);
1606+
CLEAR(obj);
1607+
1608+
// Py_CONSTANT_ZERO
1609+
obj=get_constant(Py_CONSTANT_ZERO);
1610+
expected=PyLong_FromLong(0);
1611+
assert(expected!=NULL);
1612+
assert(Py_TYPE(obj)==&PyLong_Type);
1613+
assert(PyObject_RichCompareBool(obj,expected,Py_EQ)==1);
1614+
CLEAR(obj);
1615+
Py_DECREF(expected);
1616+
1617+
// Py_CONSTANT_ONE
1618+
obj=get_constant(Py_CONSTANT_ONE);
1619+
expected=PyLong_FromLong(1);
1620+
assert(expected!=NULL);
1621+
assert(Py_TYPE(obj)==&PyLong_Type);
1622+
assert(PyObject_RichCompareBool(obj,expected,Py_EQ)==1);
1623+
CLEAR(obj);
1624+
Py_DECREF(expected);
1625+
1626+
// Py_CONSTANT_EMPTY_STR
1627+
obj=get_constant(Py_CONSTANT_EMPTY_STR);
1628+
assert(Py_TYPE(obj)==&PyUnicode_Type);
1629+
#ifPY_VERSION_HEX >=0x03030000
1630+
assert(PyUnicode_GetLength(obj)==0);
1631+
#else
1632+
assert(PyUnicode_GetSize(obj)==0);
1633+
#endif
1634+
CLEAR(obj);
1635+
1636+
// Py_CONSTANT_EMPTY_BYTES
1637+
obj=get_constant(Py_CONSTANT_EMPTY_BYTES);
1638+
assert(Py_TYPE(obj)==&PyBytes_Type);
1639+
assert(PyBytes_Size(obj)==0);
1640+
CLEAR(obj);
1641+
1642+
// Py_CONSTANT_EMPTY_TUPLE
1643+
obj=get_constant(Py_CONSTANT_EMPTY_TUPLE);
1644+
assert(Py_TYPE(obj)==&PyTuple_Type);
1645+
assert(PyTuple_Size(obj)==0);
1646+
CLEAR(obj);
1647+
1648+
#undef CLEAR
1649+
}
1650+
1651+
1652+
staticPyObject*
1653+
test_get_constant(PyObject*Py_UNUSED(module),PyObject*Py_UNUSED(args))
1654+
{
1655+
check_get_constant(Py_GetConstant,0);
1656+
check_get_constant(Py_GetConstantBorrowed,1);
1657+
Py_RETURN_NONE;
1658+
}
1659+
1660+
15761661
staticstructPyMethodDefmethods[]= {
15771662
{"test_object",test_object,METH_NOARGS,_Py_NULL},
15781663
{"test_py_is",test_py_is,METH_NOARGS,_Py_NULL},
@@ -1609,6 +1694,7 @@ static struct PyMethodDef methods[] = {
16091694
#ifdefTEST_PYTIME
16101695
{"test_time",test_time,METH_NOARGS,_Py_NULL},
16111696
#endif
1697+
{"test_get_constant",test_get_constant,METH_NOARGS,_Py_NULL},
16121698
{_Py_NULL,_Py_NULL,0,_Py_NULL}
16131699
};
16141700

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp