mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git
synced 2024-11-23 12:14:24 +08:00
libbtrfsutil: python: fix build on Python 3.13
Python 3.13, currently in beta, removed the internal _PyObject_LookupSpecial function. The libbtrfsutil Python bindings use it in the path_converter() function because it was based on internal path_converter() function in CPython [1]. This is causing build failures on Fedora Rawhide [2] and Gentoo [3]. Replace path_converter() with a version that only uses public functions based on the one in drgn [4]. 1:d9efa45d74/Modules/posixmodule.c (L1253)
2: https://bugzilla.redhat.com/show_bug.cgi?id=2245650 3: https://github.com/kdave/btrfs-progs/issues/838 4:9ad29fd864/libdrgn/python/util.c (L81)
Issue: #838 Reported-by: Neal Gompa <neal@gompa.dev> Reported-by: Sam James <sam@gentoo.org> Reviewed-by: Neal Gompa <neal@gompa.dev> Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
c5ee9301c6
commit
d0ab8f55a5
@ -40,16 +40,13 @@ extern PyTypeObject SubvolumeInfo_type;
|
||||
extern PyTypeObject SubvolumeIterator_type;
|
||||
extern PyTypeObject QgroupInherit_type;
|
||||
|
||||
/*
|
||||
* Helpers for path arguments based on posixmodule.c in CPython.
|
||||
*/
|
||||
struct path_arg {
|
||||
bool allow_fd;
|
||||
char *path;
|
||||
int fd;
|
||||
char *path;
|
||||
Py_ssize_t length;
|
||||
PyObject *object;
|
||||
PyObject *cleanup;
|
||||
PyObject *bytes;
|
||||
};
|
||||
int path_converter(PyObject *o, void *p);
|
||||
void path_cleanup(struct path_arg *path);
|
||||
|
@ -44,85 +44,48 @@ static int fd_converter(PyObject *o, void *p)
|
||||
int path_converter(PyObject *o, void *p)
|
||||
{
|
||||
struct path_arg *path = p;
|
||||
int is_index, is_bytes, is_unicode;
|
||||
PyObject *bytes = NULL;
|
||||
Py_ssize_t length = 0;
|
||||
char *tmp;
|
||||
|
||||
if (o == NULL) {
|
||||
path_cleanup(p);
|
||||
return 1;
|
||||
}
|
||||
|
||||
path->object = path->cleanup = NULL;
|
||||
Py_INCREF(o);
|
||||
|
||||
path->fd = -1;
|
||||
|
||||
is_index = path->allow_fd && PyIndex_Check(o);
|
||||
is_bytes = PyBytes_Check(o);
|
||||
is_unicode = PyUnicode_Check(o);
|
||||
|
||||
if (!is_index && !is_bytes && !is_unicode) {
|
||||
_Py_IDENTIFIER(__fspath__);
|
||||
PyObject *func;
|
||||
|
||||
func = _PyObject_LookupSpecial(o, &PyId___fspath__);
|
||||
if (func == NULL)
|
||||
goto err_format;
|
||||
Py_DECREF(o);
|
||||
o = PyObject_CallFunctionObjArgs(func, NULL);
|
||||
Py_DECREF(func);
|
||||
if (o == NULL)
|
||||
return 0;
|
||||
is_bytes = PyBytes_Check(o);
|
||||
is_unicode = PyUnicode_Check(o);
|
||||
}
|
||||
|
||||
if (is_unicode) {
|
||||
if (!PyUnicode_FSConverter(o, &bytes))
|
||||
goto err;
|
||||
} else if (is_bytes) {
|
||||
bytes = o;
|
||||
Py_INCREF(bytes);
|
||||
} else if (is_index) {
|
||||
if (!fd_converter(o, &path->fd))
|
||||
goto err;
|
||||
path->path = NULL;
|
||||
goto out;
|
||||
path->length = 0;
|
||||
path->bytes = NULL;
|
||||
if (path->allow_fd && PyIndex_Check(o)) {
|
||||
PyObject *fd_obj;
|
||||
int overflow;
|
||||
long fd;
|
||||
|
||||
fd_obj = PyNumber_Index(o);
|
||||
if (!fd_obj)
|
||||
return 0;
|
||||
fd = PyLong_AsLongAndOverflow(fd_obj, &overflow);
|
||||
Py_DECREF(fd_obj);
|
||||
if (fd == -1 && PyErr_Occurred())
|
||||
return 0;
|
||||
if (overflow > 0 || fd > INT_MAX) {
|
||||
PyErr_SetString(PyExc_OverflowError, "fd is greater than maximum");
|
||||
return 0;
|
||||
}
|
||||
if (fd < 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "fd is negative");
|
||||
return 0;
|
||||
}
|
||||
path->fd = fd;
|
||||
} else {
|
||||
err_format:
|
||||
PyErr_Format(PyExc_TypeError, "expected %s, not %s",
|
||||
path->allow_fd ? "string, bytes, os.PathLike, or integer" :
|
||||
"string, bytes, or os.PathLike",
|
||||
Py_TYPE(o)->tp_name);
|
||||
goto err;
|
||||
if (!PyUnicode_FSConverter(o, &path->bytes)) {
|
||||
path->object = path->bytes = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
length = PyBytes_GET_SIZE(bytes);
|
||||
tmp = PyBytes_AS_STRING(bytes);
|
||||
if ((size_t)length != strlen(tmp)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"path has embedded nul character");
|
||||
goto err;
|
||||
path->path = PyBytes_AS_STRING(path->bytes);
|
||||
path->length = PyBytes_GET_SIZE(path->bytes);
|
||||
}
|
||||
|
||||
path->path = tmp;
|
||||
if (bytes == o)
|
||||
Py_DECREF(bytes);
|
||||
else
|
||||
path->cleanup = bytes;
|
||||
path->fd = -1;
|
||||
|
||||
out:
|
||||
path->length = length;
|
||||
Py_INCREF(o);
|
||||
path->object = o;
|
||||
return Py_CLEANUP_SUPPORTED;
|
||||
|
||||
err:
|
||||
Py_XDECREF(o);
|
||||
Py_XDECREF(bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject *list_from_uint64_array(const uint64_t *arr, size_t n)
|
||||
@ -150,8 +113,8 @@ PyObject *list_from_uint64_array(const uint64_t *arr, size_t n)
|
||||
|
||||
void path_cleanup(struct path_arg *path)
|
||||
{
|
||||
Py_CLEAR(path->bytes);
|
||||
Py_CLEAR(path->object);
|
||||
Py_CLEAR(path->cleanup);
|
||||
}
|
||||
|
||||
static PyMethodDef btrfsutil_methods[] = {
|
||||
|
Loading…
Reference in New Issue
Block a user