From 822123856980f84562406cc7bd1d4d6c2b8bc184 Mon Sep 17 00:00:00 2001 From: Brandon Maier Date: Mon, 18 Mar 2024 18:24:19 +0000 Subject: [PATCH] pylibfdt: fix get_mem_rsv for newer Python versions The test for get_mem_rsv fails on newer versions of Python with the following error. > Traceback (most recent call last): > File "/__w/dtc/dtc/tests/pylibfdt_tests.py", line 421, in testReserveMap > self.assertEqual([ 0xdeadbeef00000000, 0x100000], > AssertionError: Lists differ: [16045690981097406464, 1048576] != [0, 16045690981097406464, 1048576] > > First differing element 0: > 16045690981097406464 > 0 > > Second list contains 1 additional elements. > First extra element 2: > 1048576 > > - [16045690981097406464, 1048576] > + [0, 16045690981097406464, 1048576] > ? +++ It appears this is because the PyTuple_GET_SIZE() function that was used to build the fdt_get_mem_rsv() return value has changed. It now is returning a non-zero value when it's passed an integer, which causes the SWIG wrapper to append the returned arguments to the return error rather then ignore them. This is valid behaviour per Python's documentation, which says it will "Return the size of the tuple p, which must be non-NULL and point to a tuple; no error checking is performed"[1]. As passing an integer is not a tuple, its return value is undefined. Fix this issue on older and newer versions by avoiding PyTuple_GET_SIZE() entirely. Always append the arguments to the list, and instead use the wrapper python function to check the first argument and then splice the last two arguments as the return value. [1] https://docs.python.org/3/c-api/tuple.html#c.PyTuple_GET_SIZE Signed-off-by: Brandon Maier Signed-off-by: David Gibson --- pylibfdt/libfdt.i | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/pylibfdt/libfdt.i b/pylibfdt/libfdt.i index 0b50983..bbc91ad 100644 --- a/pylibfdt/libfdt.i +++ b/pylibfdt/libfdt.i @@ -295,7 +295,9 @@ class FdtRo(object): Returns: Number of memory reserve-map records """ - return check_err(fdt_get_mem_rsv(self._fdt, index), quiet) + val = fdt_get_mem_rsv(self._fdt, index) + check_err(val[0], quiet) + return val[1:] def subnode_offset(self, parentoffset, name, quiet=()): """Get the offset of a named subnode @@ -1188,12 +1190,7 @@ typedef uint32_t fdt32_t; %typemap(argout) uint64_t * { PyObject *val = PyLong_FromUnsignedLongLong(*arg$argnum); - if (!result) { - if (PyTuple_GET_SIZE(resultobj) == 0) - resultobj = val; - else - resultobj = SWIG_Python_AppendOutput(resultobj, val); - } + resultobj = SWIG_Python_AppendOutput(resultobj, val); } %include "cstring.i"