Skip to content

Commit 5002f4d

Browse files
committed
gh-115754: Export Py_None, Py_False, Py_True as symbols
In the limited C API and the stable ABI, implement Py_None, Py_False, Py_True, Py_Ellipsis and Py_NotImplemented constants are symbols.
1 parent 5f7df88 commit 5002f4d

File tree

12 files changed

+101
-1
lines changed

12 files changed

+101
-1
lines changed

Doc/data/stable_abi.dat

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/boolobject.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@ extern "C" {
1717
PyAPI_DATA(PyLongObject) _Py_FalseStruct;
1818
PyAPI_DATA(PyLongObject) _Py_TrueStruct;
1919

20-
/* Use these macros */
20+
// Export symbols in the stable ABI
21+
PyAPI_DATA(PyLongObject*) Py_False;
22+
PyAPI_DATA(PyLongObject*) Py_True;
23+
24+
#ifndef Py_LIMITED_API
25+
// Implement Py_False and Py_True as macros in the non-limited C API
2126
#define Py_False _PyObject_CAST(&_Py_FalseStruct)
2227
#define Py_True _PyObject_CAST(&_Py_TrueStruct)
28+
#endif
2329

2430
// Test if an object is the True singleton, the same as "x is True" in Python.
2531
PyAPI_FUNC(int) Py_IsTrue(PyObject *x);

Include/object.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,14 @@ _Py_NoneStruct is an object of undefined type which can be used in contexts
10701070
where NULL (nil) is not suitable (since NULL often means 'error').
10711071
*/
10721072
PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */
1073+
1074+
// Export the symbol in the stable ABI
1075+
PyAPI_DATA(PyObject*) Py_None;
1076+
1077+
#ifndef Py_LIMITED_API
1078+
// Implement Py_None as a macro in the non-limited C API
10731079
#define Py_None (&_Py_NoneStruct)
1080+
#endif
10741081

10751082
// Test if an object is the None singleton, the same as "x is None" in Python.
10761083
PyAPI_FUNC(int) Py_IsNone(PyObject *x);
@@ -1084,7 +1091,14 @@ Py_NotImplemented is a singleton used to signal that an operation is
10841091
not implemented for a given type combination.
10851092
*/
10861093
PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */
1094+
1095+
// Export the symbol in the stable ABI
1096+
PyAPI_DATA(PyObject*) Py_NotImplemented;
1097+
1098+
#ifndef Py_LIMITED_API
1099+
// Implement Py_NotImplemented as a macro in the non-limited C API
10871100
#define Py_NotImplemented (&_Py_NotImplementedStruct)
1101+
#endif
10881102

10891103
/* Macro for returning Py_NotImplemented from a function */
10901104
#define Py_RETURN_NOTIMPLEMENTED return Py_NotImplemented

Include/sliceobject.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ extern "C" {
88

99
PyAPI_DATA(PyObject) _Py_EllipsisObject; /* Don't use this directly */
1010

11+
// Export the symbol in the stable ABI
12+
PyAPI_DATA(PyObject*) Py_Ellipsis;
13+
14+
#ifndef Py_LIMITED_API
15+
// Implement Py_Ellipsis as a macro in the non-limited C API
1116
#define Py_Ellipsis (&_Py_EllipsisObject)
17+
#endif
1218

1319
/* Slice object interface */
1420

Lib/test/test_stable_abi_ctypes.py

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
In the limited C API and the stable ABI, implement ``Py_None``, ``Py_False``
2+
``Py_True``, ``Py_Ellipsis`` and ``Py_NotImplemented`` constants are symbols,
3+
rather than implementing them as macros. So they can be loaded by dlopen/dlsym
4+
in an embedded in Python, rather than having to reimplement these macros
5+
manually. In the non-limited C API, these constants are still implemented as
6+
macros. Patch by Victor Stinner.

Misc/stable_abi.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,3 +2496,13 @@
24962496
[typedef.PyCFunctionFastWithKeywords]
24972497
added = '3.13'
24982498
# "abi-only" since 3.10. (Same story as PyCFunctionFast.)
2499+
[data.Py_False]
2500+
added = '3.13'
2501+
[data.Py_True]
2502+
added = '3.13'
2503+
[data.Py_None]
2504+
added = '3.13'
2505+
[data.Py_Ellipsis]
2506+
added = '3.13'
2507+
[data.Py_NotImplemented]
2508+
added = '3.13'

Objects/boolobject.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,10 @@ struct _longobject _Py_TrueStruct = {
225225
{ 1 }
226226
}
227227
};
228+
229+
// Stable ABI: export symbols
230+
231+
#undef Py_False
232+
#undef Py_True
233+
PyLongObject *Py_False = _Py_CAST(PyLongObject*, &_Py_FalseStruct);
234+
PyLongObject *Py_True = _Py_CAST(PyLongObject*, &_Py_TrueStruct);

Objects/object.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2970,3 +2970,10 @@ _Py_SetRefcnt(PyObject *ob, Py_ssize_t refcnt)
29702970
{
29712971
Py_SET_REFCNT(ob, refcnt);
29722972
}
2973+
2974+
2975+
// Export symbols in the stable ABI
2976+
#undef Py_None
2977+
#undef Py_NotImplemented
2978+
PyObject *Py_None = &_Py_NoneStruct;
2979+
PyObject *Py_NotImplemented = &_Py_NotImplementedStruct;

Objects/sliceobject.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,3 +721,8 @@ PyTypeObject PySlice_Type = {
721721
0, /* tp_alloc */
722722
slice_new, /* tp_new */
723723
};
724+
725+
726+
// Export the symbol in the stable ABI
727+
#undef Py_Ellipsis
728+
PyObject *Py_Ellipsis = &_Py_EllipsisObject;

0 commit comments

Comments
 (0)