[PATCH] dtc and Python 3

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



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


[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux