Deadparrot C library: provide old removed C API functions to new Python versions


In 2020, I wrote the pythoncapi-compat project for forward compatibility: make the code compatible with “future” or “incoming” Python versions. You modify your code and it becomes forward compatible (and remains backward compatible).

I wrote a new deadparrot project for the backward compatibility: C library providing removed C API functions to new Python versions. For example, it provides PyEval_InitThreads() removed in Python 3.13 and PyUnicode_GetMax() removed in Python 3.10.

There is no need to modify the C code of your C extension, the API stays the same (thanks to macros which uses the new DeadPy name of the removed function). You just have to link your C extension to libdeadparrot.

This project doesn’t cover all cases. For example, it doesn’t handle removed and changed structure members. For example, PyThreadState.tick_counter member was removed in Python 3.4, and Py_REFCNT(obj) = refcnt; fails with a build error on Python 3.10 and newer.

The idea is only to reduce the quantity of needed changes to run an old unmaintained C extensions on recent Python versions.

What do you think? Does it solve any issue? Is it useful?


1 Like

If we (you) have to maintain these anyway, why not have them in CPython itself?
Installing an extra C dependency seems like an unnecessary hoop for users to jump through – for no good reason that I can see.

We do need a better way to make it easy to avoid these in new code. (See capi-workgroup/api-evolution#24 for a proposal.) But removal of no-op/no-maintenance functions like PyEval_InitThreads makes no-sense to me.

To be clear, I’m not talking about cases where API is removed because it makes no sense any more, can’t be implemented easily, is a real maintenance burden or has a significant security risk. But libdeadparrot isn’t likely to help with much of those.


I’m curious: why not just a single project covering both needs?

pythoncapi-compat is a header file, tooling to use newer API, and tests.

deadparrot is a shared library and tests. The implementation is different, for example it uses CMake to build the libdeadparrot shared library.

Maybe at some point, both approaches and both projects can converge. For now, I prefer to have separated projects.

Deadparrot README file lists removed functions since Python 3.0, the list is quite long. Removing C API functions is just a fact, it happens for various reasons, sometimes backed by PEPs. I’m not here to argue if we should remove or not functions. I’m here to discuss a practical solution when functions are removed and C extensions cannot be easily updated.