Skip to content

Commit

Permalink
Properly fix Python 3.13 stable ABI linking
Browse files Browse the repository at this point in the history
This fixes vim#15460 properly. There was an attempt to fix it in v9.1.0668,
but it did it by manually copy and pasting definitions from Python 3.13
headers, which is problematic as it makes Vim dependent on low-level
implementation details which are subject to change. That change also
pulls in dependencies to private APIs (`_Py_IncRef`) which is a very bad
idea as the next version of Python could very well remove that.

The core issue was simply that `Py_INCREF` and similar functions are not
part of the stable API. We are supposed to be using `Py_IncRef` instead
which performs null-check (similar to `Py_XINCREF`) and is available as
a linkable function. We simply need to call it instead of the macro.
We simply remap `Py_INCREF` (and friends) to the function version in
limited API similar to how we mapped other functions.
  • Loading branch information
ychin committed Sep 9, 2024
1 parent 701c863 commit bfbce37
Showing 1 changed file with 18 additions and 34 deletions.
52 changes: 18 additions & 34 deletions src/if_python3.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,16 +219,9 @@ static HINSTANCE hinstPy3 = 0; // Instance of python.dll
# define PyObject_GetItem py3_PyObject_GetItem
# define PyObject_IsTrue py3_PyObject_IsTrue
# define PyModule_GetDict py3_PyModule_GetDict
# if defined(USE_LIMITED_API) \
&& (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))
# undef Py_INCREF
# if Py_LIMITED_API+0 >= 0x030a00A7
# define _Py_IncRef py3__Py_IncRef
# define Py_INCREF _Py_IncRef
# else
# define Py_IncRef py3_Py_IncRef
# define Py_INCREF Py_IncRef
# endif
# ifdef USE_LIMITED_API
# define Py_IncRef py3_Py_IncRef
# define Py_DecRef py3_Py_DecRef
# endif
# ifdef USE_LIMITED_API
# define Py_CompileString py3_Py_CompileString
Expand Down Expand Up @@ -402,14 +395,9 @@ static void (*py3_Py_Finalize)(void);
static void (*py3_PyErr_SetString)(PyObject *, const char *);
static void (*py3_PyErr_SetObject)(PyObject *, PyObject *);
static int (*py3_PyErr_ExceptionMatches)(PyObject *);
# if defined(USE_LIMITED_API) \
&& (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))
# if Py_LIMITED_API+0 >= 0x030a00A7
# define _Py_IncRef py3__Py_IncRef
static void (*py3__Py_IncRef)(PyObject *);
# else
# ifdef USE_LIMITED_API
static void (*py3_Py_IncRef)(PyObject *);
# endif
static void (*py3_Py_DecRef)(PyObject *);
# endif
# ifdef USE_LIMITED_API
static PyObject* (*py3_Py_CompileString)(const char *, const char *, int);
Expand Down Expand Up @@ -618,13 +606,9 @@ static struct
{"PyErr_SetString", (PYTHON_PROC*)&py3_PyErr_SetString},
{"PyErr_SetObject", (PYTHON_PROC*)&py3_PyErr_SetObject},
{"PyErr_ExceptionMatches", (PYTHON_PROC*)&py3_PyErr_ExceptionMatches},
# if defined(USE_LIMITED_API) \
&& (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))
# if Py_LIMITED_API+0 >= 0x030a00A7
{"_Py_IncRef", (PYTHON_PROC*)&py3__Py_IncRef},
# else
# ifdef USE_LIMITED_API
{"Py_IncRef", (PYTHON_PROC*)&py3_Py_IncRef},
# endif
{"Py_DecRef", (PYTHON_PROC*)&py3_Py_DecRef},
# endif
# ifdef USE_LIMITED_API
{"Py_CompileString", (PYTHON_PROC*)&py3_Py_CompileString},
Expand Down Expand Up @@ -802,18 +786,18 @@ py3__Py_XDECREF(PyObject *op)
# define Py_XDECREF(op) py3__Py_XDECREF(_PyObject_CAST(op))
# endif

# if defined(USE_LIMITED_API) \
&& (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))
static inline void
py3__Py_XINCREF(PyObject *op)
{
if (op != NULL)
{
Py_INCREF(op);
}
}
# ifdef USE_LIMITED_API
// Use stable versions of inc/dec ref. Note that these always null-check and
// therefore there's no difference between XINCREF and INCREF.
# undef Py_XINCREF
# define Py_XINCREF(op) py3__Py_XINCREF(_PyObject_CAST(op))
# define Py_XINCREF(obj) Py_IncRef((PyObject *)obj)
# undef Py_INCREF
# define Py_INCREF(obj) Py_IncRef((PyObject *)obj)

# undef Py_DECREF
# define Py_DECREF(obj) Py_DecRef((PyObject *)obj)
# undef Py_XDECREF
# define Py_XDECREF(obj) Py_DecRef((PyObject *)obj)
# endif

# if PY_VERSION_HEX >= 0x030900b0
Expand Down

0 comments on commit bfbce37

Please sign in to comment.