Hello.
Because Linux distributions started with dropping Python 2 recently, I
tried to prepare patches to make DTC Python 3 compatible.
I've made possible to specify Python executable via an environment
variable (with Python 2 as default) and all necessary changes to make
all tests pass with both Pythons.
Let me know if you find something wrong or if I can do something more.
Have a nice day!
Lumír
>From 4f40affb87a29ba4924dc67a557db1de94b90cc8 Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@xxxxxxxxxx>
Date: Tue, 10 Jul 2018 09:08:07 +0200
Subject: [PATCH 5/5] pylibfdt: Change how passing tests are recognized
When some warning appears in test result, "ok" is still
at the end of the line but without three dots.
Signed-off-by: Lumir Balhar <lbalhar@xxxxxxxxxx>
---
tests/run_tests.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 715fa19..0b537e6 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -903,7 +903,7 @@ pylibfdt_tests () {
# and the summary line for total tests (e.g. 'Ran 17 tests in 0.002s').
# We could add pass + fail to get total tests, but this provides a useful
# sanity check.
- pass_count=$(grep "\.\.\. ok$" $TMP | wc -l)
+ pass_count=$(grep "ok$" $TMP | wc -l)
fail_count=$(grep "^ERROR: " $TMP | wc -l)
total_tests=$(sed -n 's/^Ran \([0-9]*\) tests.*$/\1/p' $TMP)
cat $TMP
--
2.17.1
>From f85f0f352ffef6c2e62af703bd7e18641670d1ec Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pviktori@xxxxxxxxxx>
Date: Mon, 9 Jul 2018 14:59:30 +0200
Subject: [PATCH 4/5] pylibfdt: Test fdt.setprop take bytes on Python 3, add
error handling
Signed-off-by: Petr Viktorin <pviktori@xxxxxxxxxx>
---
pylibfdt/libfdt.i | 4 ++++
tests/pylibfdt_tests.py | 12 +++++++-----
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/pylibfdt/libfdt.i b/pylibfdt/libfdt.i
index 9c0dcdc..da8d56b 100644
--- a/pylibfdt/libfdt.i
+++ b/pylibfdt/libfdt.i
@@ -759,6 +759,10 @@ typedef uint32_t fdt32_t;
/* typemap used for fdt_setprop() */
%typemap(in) (const void *val) {
%#if PY_VERSION_HEX >= 0x03000000
+ if (!PyBytes_Check($input)) {
+ SWIG_exception_fail(SWIG_TypeError, "bytes expected in method '" "$symname"
+ "', argument " "$argnum"" of type '" "$type""'");
+ }
$1 = PyBytes_AsString($input);
%#else
$1 = PyString_AsString($input); /* char *str */
diff --git a/tests/pylibfdt_tests.py b/tests/pylibfdt_tests.py
index e1204f8..348cb09 100644
--- a/tests/pylibfdt_tests.py
+++ b/tests/pylibfdt_tests.py
@@ -67,6 +67,8 @@ TEST_VALUE64_1H = 0xdeadbeef
TEST_VALUE64_1L = 0x01abcdef
TEST_VALUE64_1 = (TEST_VALUE64_1H << 32) | TEST_VALUE64_1L
+TEST_BYTES_1 = b'hello world'
+
TEST_STRING_1 = 'hello world'
TEST_STRING_2 = 'hi world'
try:
@@ -413,21 +415,21 @@ class PyLibfdtTests(unittest.TestCase):
def testSetProp(self):
"""Test that we can update and create properties"""
node = self.fdt.path_offset('/subnode@1')
- self.fdt.setprop(node, 'compatible', TEST_STRING_1)
- self.assertEquals(TEST_STRING_1, self.fdt.getprop(node, 'compatible'))
+ self.fdt.setprop(node, 'compatible', TEST_BYTES_1)
+ self.assertEquals(TEST_BYTES_1, self.fdt.getprop(node, 'compatible'))
# Check that this property is missing, and that we don't have space to
# add it
self.assertEquals(-libfdt.NOTFOUND,
self.fdt.getprop(node, 'missing', QUIET_NOTFOUND))
self.assertEquals(-libfdt.NOSPACE,
- self.fdt.setprop(node, 'missing', TEST_STRING_1,
+ self.fdt.setprop(node, 'missing', TEST_BYTES_1,
quiet=(libfdt.NOSPACE,)))
# Expand the device tree so we now have room
self.fdt.resize(self.fdt.totalsize() + 50)
- self.fdt.setprop(node, 'missing', TEST_STRING_1)
- self.assertEquals(TEST_STRING_1, self.fdt.getprop(node, 'missing'))
+ self.fdt.setprop(node, 'missing', TEST_BYTES_1)
+ self.assertEquals(TEST_BYTES_1, self.fdt.getprop(node, 'missing'))
def testSetPropU32(self):
"""Test that we can update and create integer properties"""
--
2.17.1
>From 232e19b954a6482c2eac99776c94ad2f9a06b5d1 Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@xxxxxxxxxx>
Date: Mon, 9 Jul 2018 12:41:13 +0200
Subject: [PATCH 3/5] pylibfdt: Fix comparison of return value.
In Python 2, an empty list is always higher than zero but in
Python 3 these types cannot be compared.
Signed-off-by: Lumir Balhar <lbalhar@xxxxxxxxxx>
---
pylibfdt/libfdt.i | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pylibfdt/libfdt.i b/pylibfdt/libfdt.i
index 88d443d..9c0dcdc 100644
--- a/pylibfdt/libfdt.i
+++ b/pylibfdt/libfdt.i
@@ -124,7 +124,7 @@ def check_err(val, quiet=()):
Raises
FdtException if val < 0
"""
- if val < 0:
+ if isinstance(val, int) and val < 0:
if -val not in quiet:
raise FdtException(val)
return val
--
2.17.1
>From 79d0b8ea7fbe08a9c8cf0945a40371fa3fc1e360 Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@xxxxxxxxxx>
Date: Mon, 9 Jul 2018 12:40:09 +0200
Subject: [PATCH 2/5] pylibfdt: Proper handling of bytes/unicode strings and
octal literals
Signed-off-by: Lumir Balhar <lbalhar@xxxxxxxxxx>
---
pylibfdt/libfdt.i | 14 +++++++++++---
tests/pylibfdt_tests.py | 17 ++++++++++-------
2 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/pylibfdt/libfdt.i b/pylibfdt/libfdt.i
index aed5390..88d443d 100644
--- a/pylibfdt/libfdt.i
+++ b/pylibfdt/libfdt.i
@@ -624,7 +624,7 @@ class Fdt:
Raises:
FdtException if no parent found or other error occurs
"""
- val = val.encode('utf-8') + '\0'
+ val = val.encode('utf-8') + b'\0'
return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name,
val, len(val)), quiet)
@@ -749,12 +749,20 @@ typedef uint32_t fdt32_t;
if (!$1)
$result = Py_None;
else
- $result = Py_BuildValue("s#", $1, *arg4);
+ %#if PY_VERSION_HEX >= 0x03000000
+ $result = Py_BuildValue("y#", $1, *arg4);
+ %#else
+ $result = Py_BuildValue("s#", $1, *arg4);
+ %#endif
}
/* typemap used for fdt_setprop() */
%typemap(in) (const void *val) {
- $1 = PyString_AsString($input); /* char *str */
+ %#if PY_VERSION_HEX >= 0x03000000
+ $1 = PyBytes_AsString($input);
+ %#else
+ $1 = PyString_AsString($input); /* char *str */
+ %#endif
}
/* typemaps used for fdt_next_node() */
diff --git a/tests/pylibfdt_tests.py b/tests/pylibfdt_tests.py
index 9f3e55a..e1204f8 100644
--- a/tests/pylibfdt_tests.py
+++ b/tests/pylibfdt_tests.py
@@ -69,7 +69,10 @@ TEST_VALUE64_1 = (TEST_VALUE64_1H << 32) | TEST_VALUE64_1L
TEST_STRING_1 = 'hello world'
TEST_STRING_2 = 'hi world'
-TEST_STRING_3 = u'unicode ' + unichr(467)
+try:
+ TEST_STRING_3 = u'unicode ' + unichr(467)
+except NameError:
+ TEST_STRING_3 = u'unicode ' + chr(467)
def get_err(err_code):
@@ -92,7 +95,7 @@ def _ReadFdt(fname):
Returns:
Fdt bytearray suitable for passing to libfdt functions
"""
- return libfdt.Fdt(open(fname).read())
+ return libfdt.Fdt(open(fname, mode='rb').read())
class PyLibfdtTests(unittest.TestCase):
"""Test class for pylibfdt
@@ -131,7 +134,7 @@ class PyLibfdtTests(unittest.TestCase):
def testBadFdt(self):
"""Check that a filename provided accidentally is not accepted"""
with self.assertRaises(FdtException) as e:
- fdt = libfdt.Fdt('a string')
+ fdt = libfdt.Fdt(b'a string')
self.assertEquals(e.exception.err, -libfdt.BADMAGIC)
def testSubnodeOffset(self):
@@ -206,7 +209,7 @@ class PyLibfdtTests(unittest.TestCase):
poffset = self.fdt.first_property_offset(root)
prop = self.fdt.get_property_by_offset(poffset)
self.assertEquals(prop.name, 'compatible')
- self.assertEquals(prop, 'test_tree1\0')
+ self.assertEquals(prop, b'test_tree1\0')
with self.assertRaises(FdtException) as e:
self.fdt.get_property_by_offset(-2)
@@ -219,7 +222,7 @@ class PyLibfdtTests(unittest.TestCase):
"""Check that we can read the contents of a property by name"""
root = self.fdt.path_offset('/')
value = self.fdt.getprop(root, "compatible")
- self.assertEquals(value, 'test_tree1\0')
+ self.assertEquals(value, b'test_tree1\0')
self.assertEquals(-libfdt.NOTFOUND, self.fdt.getprop(root, 'missing',
QUIET_NOTFOUND))
@@ -229,7 +232,7 @@ class PyLibfdtTests(unittest.TestCase):
node = self.fdt.path_offset('/subnode@1/subsubnode')
value = self.fdt.getprop(node, "compatible")
- self.assertEquals(value, 'subsubnode1\0subsubnode\0')
+ self.assertEquals(value, b'subsubnode1\0subsubnode\0')
def testStrError(self):
"""Check that we can get an error string"""
@@ -389,7 +392,7 @@ class PyLibfdtTests(unittest.TestCase):
self.assertEquals(2, self.fdt.num_mem_rsv())
self.assertEquals([ 0xdeadbeef00000000, 0x100000],
self.fdt.get_mem_rsv(0))
- self.assertEquals([123456789, 010000], self.fdt.get_mem_rsv(1))
+ self.assertEquals([123456789, 0o10000], self.fdt.get_mem_rsv(1))
def testEmpty(self):
"""Test that we can create an empty tree"""
--
2.17.1
>From 8d8ac00ff197ff0ef6b1564bc866da09afc3c108 Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@xxxxxxxxxx>
Date: Mon, 9 Jul 2018 12:38:59 +0200
Subject: [PATCH 1/5] pylibfdt: Allow switch to Python 3 via environment
variable PYTHON
Python 2 is still the default but it can be changed by
setting environment variable PYTHON before build/test.
Signed-off-by: Lumir Balhar <lbalhar@xxxxxxxxxx>
---
Makefile | 3 ++-
pylibfdt/Makefile.pylibfdt | 4 ++--
tests/Makefile.tests | 6 +++---
tests/run_tests.sh | 2 +-
4 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/Makefile b/Makefile
index 6d55e13..c84eb66 100644
--- a/Makefile
+++ b/Makefile
@@ -24,6 +24,7 @@ BISON = bison
LEX = flex
SWIG = swig
PKG_CONFIG ?= pkg-config
+PYTHON ?= python2
INSTALL = /usr/bin/install
INSTALL_PROGRAM = $(INSTALL)
@@ -133,7 +134,7 @@ all: $(BIN) libfdt
# We need both Python and swig to build/install pylibfdt.
# This builds the given make ${target} if those deps are found.
check_python_deps = \
- if $(PKG_CONFIG) --cflags python2 >/dev/null 2>&1; then \
+ if $(PKG_CONFIG) --cflags $(PYTHON) >/dev/null 2>&1; then \
if which swig >/dev/null 2>&1; then \
can_build=yes; \
fi; \
diff --git a/pylibfdt/Makefile.pylibfdt b/pylibfdt/Makefile.pylibfdt
index 9507d3d..a05984c 100644
--- a/pylibfdt/Makefile.pylibfdt
+++ b/pylibfdt/Makefile.pylibfdt
@@ -8,13 +8,13 @@ PYMODULE = $(PYLIBFDT_objdir)/_libfdt.so
define run_setup
SOURCES="$(1)" CPPFLAGS="$(CPPFLAGS)" OBJDIR="$(PYLIBFDT_objdir)"
VERSION="$(dtc_version)"
- $(PYLIBFDT_objdir)/setup.py --quiet $(2)
+ $(PYTHON) $(PYLIBFDT_objdir)/setup.py --quiet $(2)
endef
$(PYMODULE): $(PYLIBFDT_srcs)
@$(VECHO) PYMOD $@
$(call run_setup, $^, build_ext --inplace)
- mv _libfdt.so $@
+ mv _libfdt.*so $@
install_pylibfdt: $(PYMODULE)
$(VECHO) INSTALL-PYLIB; \
diff --git a/tests/Makefile.tests b/tests/Makefile.tests
index 2c2c4fd..554c840 100644
--- a/tests/Makefile.tests
+++ b/tests/Makefile.tests
@@ -76,13 +76,13 @@ tests_clean:
rm -f $(TESTS_CLEANFILES)
check: tests ${TESTS_BIN} $(TESTS_PYLIBFDT)
- cd $(TESTS_PREFIX); ./run_tests.sh
+ cd $(TESTS_PREFIX); PYTHON=$(PYTHON) ./run_tests.sh
checkm: tests ${TESTS_BIN} $(TESTS_PYLIBFDT)
- cd $(TESTS_PREFIX); ./run_tests.sh -m 2>&1 | tee vglog.$$$$
+ cd $(TESTS_PREFIX); PYTHON=$(PYTHON) ./run_tests.sh -m 2>&1 | tee vglog.$$$$
checkv: tests ${TESTS_BIN} $(TESTS_PYLIBFDT)
- cd $(TESTS_PREFIX); ./run_tests.sh -v
+ cd $(TESTS_PREFIX); PYTHON=$(PYTHON) ./run_tests.sh -v
ifneq ($(DEPTARGETS),)
-include $(TESTS_DEPFILES)
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index cf87066..715fa19 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -897,7 +897,7 @@ fdtoverlay_tests() {
pylibfdt_tests () {
run_dtc_test -I dts -O dtb -o test_props.dtb test_props.dts
TMP=/tmp/tests.stderr.$$
- python pylibfdt_tests.py -v 2> $TMP
+ $PYTHON pylibfdt_tests.py -v 2> $TMP
# Use the 'ok' message meaning the test passed, 'ERROR' meaning it failed
# and the summary line for total tests (e.g. 'Ran 17 tests in 0.002s').
--
2.17.1