openSUSE / libsolv

Library for solving packages and reading repositories
http://en.opensuse.org/openSUSE:Libzypp_satsolver
Other
509 stars 151 forks source link

bindings: Fix building with Python 3.13 #551

Closed jan-kolarik closed 4 months ago

jan-kolarik commented 5 months ago

Use PyObject_Call instead of the deprecated PyEval_CallObject as this function is to be removed in Python 3.13.

See https://docs.python.org/3.13/whatsnew/3.13.html#id11.

Currently, libsolv fails to build with Python 3.13.0a1.

/builddir/build/BUILD/libsolv-0.7.25/redhat-linux-build/bindings/python/solv_python.c:4734:24: error: implicit declaration of function ‘PyEval_CallObject’; did you mean ‘PyObject_CallObject’? [-Werror=implicit-function-declaration]
 4734 |     PyObject *result = PyEval_CallObject((PyObject *)d, args);
      |                        ^~~~~~~~~~~~~~~~~
      |                        PyObject_CallObject
mlschroe commented 4 months ago

We still need to be able to build against python-2, so there needs to be some if statements...

jan-kolarik commented 4 months ago

We still need to be able to build against python-2, so there needs to be some if statements...

I am not sure about all supported Python versions, but it seems the same signature is at least in Python 2.7: https://docs.python.org/2/c-api/object.html#c.PyObject_Call.

mlschroe commented 4 months ago

Mmm, true. Maybe we should use PyObject_CallObject()?

mlschroe commented 4 months ago

I found the following history in one of the python issues:

PyEval_CallObject() was added at Jan 12 1995 (05360cd616ae). PyObject_CallObject(), PyObject_CallFunction() and PyObject_CallMethod() were added with Include/abstract.h at Jul 18 1995 (d5398acafa2c) and implemented in terms of PyEval_CallObject(). PyEval_CallObjectWithKeywords() was added few minutes later (0261bf5b3819). PyObject_Call() was added at Aug 02 2001 (09df3254b49d) as a simple wrapper around tp_call. PyObject_CallFunction() and PyObject_CallMethod() were reimplemented in terms of PyObject_Call() at Aug 16 2002 (255d1d3e66a3).

jan-kolarik commented 4 months ago

I found the following history in one of the python issues:

PyEval_CallObject() was added at Jan 12 1995 (05360cd616ae). PyObject_CallObject(), PyObject_CallFunction() and PyObject_CallMethod() were added with Include/abstract.h at Jul 18 1995 (d5398acafa2c) and implemented in terms of PyEval_CallObject(). PyEval_CallObjectWithKeywords() was added few minutes later (0261bf5b3819). PyObject_Call() was added at Aug 02 2001 (09df3254b49d) as a simple wrapper around tp_call. PyObject_CallFunction() and PyObject_CallMethod() were reimplemented in terms of PyObject_Call() at Aug 16 2002 (255d1d3e66a3).

And in the last one there is the interesting message:

Squash a few calls to the hideously expensive PyObject_CallObject(o,a)
-- replace then with slightly faster PyObject_Call(o,a,NULL).  (The
difference is that the latter requires a to be a tuple; the former
allows other values and wraps them in a tuple if necessary; it
involves two more levels of C function calls to accomplish all that.)
jan-kolarik commented 4 months ago

But I am no expert in any of these, I am completely fine with any fix to make the Python 3.13 builds succeed.

mlschroe commented 4 months ago

ok, ok, I changed it to always use PyObject_Call (as it is available since python 2.2. and we always construct the args tupel). Thanks!