Skip to content

Commit

Permalink
pythongh-115754: Export Py_None, Py_False, Py_True as symbols
Browse files Browse the repository at this point in the history
In the limited C API and the stable ABI, implement Py_None, Py_False
and Py_True constants are symbols.
  • Loading branch information
vstinner committed Feb 21, 2024
1 parent 10fc467 commit a5e6e52
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 1 deletion.
8 changes: 7 additions & 1 deletion Include/boolobject.h
Expand Up @@ -17,9 +17,15 @@ extern "C" {
PyAPI_DATA(PyLongObject) _Py_FalseStruct;
PyAPI_DATA(PyLongObject) _Py_TrueStruct;

/* Use these macros */
// Export symbols in the stable ABI
PyAPI_DATA(PyLongObject*) Py_False;
PyAPI_DATA(PyLongObject*) Py_True;

#ifndef Py_LIMITED_API
// Implement Py_False and Py_True as macros in the non-limited C API
#define Py_False _PyObject_CAST(&_Py_FalseStruct)
#define Py_True _PyObject_CAST(&_Py_TrueStruct)
#endif

// Test if an object is the True singleton, the same as "x is True" in Python.
PyAPI_FUNC(int) Py_IsTrue(PyObject *x);
Expand Down
7 changes: 7 additions & 0 deletions Include/object.h
Expand Up @@ -1070,7 +1070,14 @@ _Py_NoneStruct is an object of undefined type which can be used in contexts
where NULL (nil) is not suitable (since NULL often means 'error').
*/
PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */

// Export the symbol in the stable ABI
PyAPI_DATA(PyObject*) Py_None;

#ifndef Py_LIMITED_API
// Implement Py_None as a macro in the non-limited C API
#define Py_None (&_Py_NoneStruct)
#endif

// Test if an object is the None singleton, the same as "x is None" in Python.
PyAPI_FUNC(int) Py_IsNone(PyObject *x);
Expand Down
10 changes: 10 additions & 0 deletions Lib/test/test_stable_abi_ctypes.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

@@ -0,0 +1,6 @@
In the limited C API and the stable ABI, implement ``Py_None``, ``Py_False``
and ``Py_True`` constants are symbols, rather than implementing them as
macros. So they can be loaded by dlopen/dlsym in an embedded in Python,
rather than having to reimplement these macros manually. In the non-limited
C API, these constants are still implemented as macros. Patch by Victor
Stinner.
7 changes: 7 additions & 0 deletions Objects/boolobject.c
Expand Up @@ -225,3 +225,10 @@ struct _longobject _Py_TrueStruct = {
{ 1 }
}
};

// Stable ABI: export symbols

#undef Py_False
#undef Py_True
PyLongObject *Py_False = _Py_CAST(PyLongObject*, &_Py_FalseStruct);
PyLongObject *Py_True = _Py_CAST(PyLongObject*, &_Py_TrueStruct);
5 changes: 5 additions & 0 deletions Objects/object.c
Expand Up @@ -2970,3 +2970,8 @@ _Py_SetRefcnt(PyObject *ob, Py_ssize_t refcnt)
{
Py_SET_REFCNT(ob, refcnt);
}

#undef Py_None

// Export the symbol in the stable ABI
PyObject *Py_None = &_Py_NoneStruct;

0 comments on commit a5e6e52

Please sign in to comment.