mirror of
https://github.com/kdave/btrfs-progs
synced 2025-04-07 09:41:29 +00: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 SubvolumeIterator_type;
|
||||||
extern PyTypeObject QgroupInherit_type;
|
extern PyTypeObject QgroupInherit_type;
|
||||||
|
|
||||||
/*
|
|
||||||
* Helpers for path arguments based on posixmodule.c in CPython.
|
|
||||||
*/
|
|
||||||
struct path_arg {
|
struct path_arg {
|
||||||
bool allow_fd;
|
bool allow_fd;
|
||||||
char *path;
|
|
||||||
int fd;
|
int fd;
|
||||||
|
char *path;
|
||||||
Py_ssize_t length;
|
Py_ssize_t length;
|
||||||
PyObject *object;
|
PyObject *object;
|
||||||
PyObject *cleanup;
|
PyObject *bytes;
|
||||||
};
|
};
|
||||||
int path_converter(PyObject *o, void *p);
|
int path_converter(PyObject *o, void *p);
|
||||||
void path_cleanup(struct path_arg *path);
|
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)
|
int path_converter(PyObject *o, void *p)
|
||||||
{
|
{
|
||||||
struct path_arg *path = 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) {
|
if (o == NULL) {
|
||||||
path_cleanup(p);
|
path_cleanup(p);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
path->object = path->cleanup = NULL;
|
|
||||||
Py_INCREF(o);
|
|
||||||
|
|
||||||
path->fd = -1;
|
path->fd = -1;
|
||||||
|
path->path = NULL;
|
||||||
|
path->length = 0;
|
||||||
|
path->bytes = NULL;
|
||||||
|
if (path->allow_fd && PyIndex_Check(o)) {
|
||||||
|
PyObject *fd_obj;
|
||||||
|
int overflow;
|
||||||
|
long fd;
|
||||||
|
|
||||||
is_index = path->allow_fd && PyIndex_Check(o);
|
fd_obj = PyNumber_Index(o);
|
||||||
is_bytes = PyBytes_Check(o);
|
if (!fd_obj)
|
||||||
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;
|
return 0;
|
||||||
is_bytes = PyBytes_Check(o);
|
fd = PyLong_AsLongAndOverflow(fd_obj, &overflow);
|
||||||
is_unicode = PyUnicode_Check(o);
|
Py_DECREF(fd_obj);
|
||||||
}
|
if (fd == -1 && PyErr_Occurred())
|
||||||
|
return 0;
|
||||||
if (is_unicode) {
|
if (overflow > 0 || fd > INT_MAX) {
|
||||||
if (!PyUnicode_FSConverter(o, &bytes))
|
PyErr_SetString(PyExc_OverflowError, "fd is greater than maximum");
|
||||||
goto err;
|
return 0;
|
||||||
} else if (is_bytes) {
|
}
|
||||||
bytes = o;
|
if (fd < 0) {
|
||||||
Py_INCREF(bytes);
|
PyErr_SetString(PyExc_ValueError, "fd is negative");
|
||||||
} else if (is_index) {
|
return 0;
|
||||||
if (!fd_converter(o, &path->fd))
|
}
|
||||||
goto err;
|
path->fd = fd;
|
||||||
path->path = NULL;
|
|
||||||
goto out;
|
|
||||||
} else {
|
} else {
|
||||||
err_format:
|
if (!PyUnicode_FSConverter(o, &path->bytes)) {
|
||||||
PyErr_Format(PyExc_TypeError, "expected %s, not %s",
|
path->object = path->bytes = NULL;
|
||||||
path->allow_fd ? "string, bytes, os.PathLike, or integer" :
|
return 0;
|
||||||
"string, bytes, or os.PathLike",
|
}
|
||||||
Py_TYPE(o)->tp_name);
|
path->path = PyBytes_AS_STRING(path->bytes);
|
||||||
goto err;
|
path->length = PyBytes_GET_SIZE(path->bytes);
|
||||||
}
|
}
|
||||||
|
Py_INCREF(o);
|
||||||
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 = tmp;
|
|
||||||
if (bytes == o)
|
|
||||||
Py_DECREF(bytes);
|
|
||||||
else
|
|
||||||
path->cleanup = bytes;
|
|
||||||
path->fd = -1;
|
|
||||||
|
|
||||||
out:
|
|
||||||
path->length = length;
|
|
||||||
path->object = o;
|
path->object = o;
|
||||||
return Py_CLEANUP_SUPPORTED;
|
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)
|
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)
|
void path_cleanup(struct path_arg *path)
|
||||||
{
|
{
|
||||||
|
Py_CLEAR(path->bytes);
|
||||||
Py_CLEAR(path->object);
|
Py_CLEAR(path->object);
|
||||||
Py_CLEAR(path->cleanup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef btrfsutil_methods[] = {
|
static PyMethodDef btrfsutil_methods[] = {
|
||||||
|
Loading…
Reference in New Issue
Block a user