[PATCH 0/5] patman: Tidy up some hangovers from Python 2

Various functions were used to deal with the differences between Python 2 and 3. These can be removed now that Python 2 is not supported.
Also tidy up the code style in dtb_platdata.py
Simon Glass (5): fdt: Use an Enum for the data type patman: Drop unicode helper functions patman: Drop tools.ToByte() patman: Drop tools.ToChar() and ToChars() dtoc: Tidy up Python style in dtb_platdata
tools/binman/elf.py | 6 +-- tools/binman/etype/fmap.py | 2 +- tools/binman/fdt_test.py | 14 +++--- tools/binman/fmap_util.py | 3 +- tools/dtoc/dtb_platdata.py | 96 ++++++++++++++++++++++---------------- tools/dtoc/fdt.py | 58 +++++++++++++++-------- tools/dtoc/test_dtoc.py | 10 ++-- tools/dtoc/test_fdt.py | 34 +++++++------- tools/patman/func_test.py | 16 +++---- tools/patman/gitutil.py | 3 +- tools/patman/series.py | 4 +- tools/patman/settings.py | 5 +- tools/patman/tools.py | 85 ++------------------------------- 13 files changed, 140 insertions(+), 196 deletions(-)

Use an Enum instead of the current ad-hoc constants, so that there is a data type associated with each 'type' value.
Signed-off-by: Simon Glass sjg@chromium.org ---
tools/binman/fdt_test.py | 14 +++++----- tools/dtoc/dtb_platdata.py | 26 +++++++++--------- tools/dtoc/fdt.py | 54 +++++++++++++++++++++++++------------- tools/dtoc/test_dtoc.py | 10 +++---- tools/dtoc/test_fdt.py | 32 +++++++++++----------- 5 files changed, 77 insertions(+), 59 deletions(-)
diff --git a/tools/binman/fdt_test.py b/tools/binman/fdt_test.py index c491d40e9ee..3e12540f62e 100644 --- a/tools/binman/fdt_test.py +++ b/tools/binman/fdt_test.py @@ -50,37 +50,37 @@ class TestFdt(unittest.TestCase): self.assertEquals('me.bin', val)
prop = node.props['intval'] - self.assertEquals(fdt.TYPE_INT, prop.type) + self.assertEquals(fdt.Type.INT, prop.type) self.assertEquals(3, fdt_util.GetInt(node, 'intval'))
prop = node.props['intarray'] - self.assertEquals(fdt.TYPE_INT, prop.type) + self.assertEquals(fdt.Type.INT, prop.type) self.assertEquals(list, type(prop.value)) self.assertEquals(2, len(prop.value)) self.assertEquals([5, 6], [fdt_util.fdt32_to_cpu(val) for val in prop.value])
prop = node.props['byteval'] - self.assertEquals(fdt.TYPE_BYTE, prop.type) + self.assertEquals(fdt.Type.BYTE, prop.type) self.assertEquals(chr(8), prop.value)
prop = node.props['bytearray'] - self.assertEquals(fdt.TYPE_BYTE, prop.type) + self.assertEquals(fdt.Type.BYTE, prop.type) self.assertEquals(list, type(prop.value)) self.assertEquals(str, type(prop.value[0])) self.assertEquals(3, len(prop.value)) self.assertEquals([chr(1), '#', '4'], prop.value)
prop = node.props['longbytearray'] - self.assertEquals(fdt.TYPE_INT, prop.type) + self.assertEquals(fdt.Type.INT, prop.type) self.assertEquals(0x090a0b0c, fdt_util.GetInt(node, 'longbytearray'))
prop = node.props['stringval'] - self.assertEquals(fdt.TYPE_STRING, prop.type) + self.assertEquals(fdt.Type.STRING, prop.type) self.assertEquals('message2', fdt_util.GetString(node, 'stringval'))
prop = node.props['stringarray'] - self.assertEquals(fdt.TYPE_STRING, prop.type) + self.assertEquals(fdt.Type.STRING, prop.type) self.assertEquals(list, type(prop.value)) self.assertEquals(3, len(prop.value)) self.assertEquals(['another', 'multi-word', 'message'], prop.value) diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index 9b27aecc140..7926fe3a792 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -35,13 +35,13 @@ PROP_IGNORE_LIST = [ 'u-boot,dm-spl', ]
-# C type declarations for the tyues we support +# C type declarations for the types we support TYPE_NAMES = { - fdt.TYPE_INT: 'fdt32_t', - fdt.TYPE_BYTE: 'unsigned char', - fdt.TYPE_STRING: 'const char *', - fdt.TYPE_BOOL: 'bool', - fdt.TYPE_INT64: 'fdt64_t', + fdt.Type.INT: 'fdt32_t', + fdt.Type.BYTE: 'unsigned char', + fdt.Type.STRING: 'const char *', + fdt.Type.BOOL: 'bool', + fdt.Type.INT64: 'fdt64_t', }
STRUCT_PREFIX = 'dtd_' @@ -106,17 +106,17 @@ def get_value(ftype, value): type: Data type (fdt_util) value: Data value, as a string of bytes """ - if ftype == fdt.TYPE_INT: + if ftype == fdt.Type.INT: return '%#x' % fdt_util.fdt32_to_cpu(value) - elif ftype == fdt.TYPE_BYTE: + elif ftype == fdt.Type.BYTE: return '%#x' % tools.ToByte(value[0]) - elif ftype == fdt.TYPE_STRING: + elif ftype == fdt.Type.STRING: # Handle evil ACPI backslashes by adding another backslash before them. # So "\_SB.GPO0" in the device tree effectively stays like that in C return '"%s"' % value.replace('\', '\\') - elif ftype == fdt.TYPE_BOOL: + elif ftype == fdt.Type.BOOL: return 'true' - elif ftype == fdt.TYPE_INT64: + elif ftype == fdt.Type.INT64: return '%#x' % value
def get_compat_name(node): @@ -435,7 +435,7 @@ class DtbPlatdata(object): na, ns = self.get_num_cells(node) total = na + ns
- if reg.type != fdt.TYPE_INT: + if reg.type != fdt.Type.INT: raise ValueError("Node '%s' reg property is not an int" % node.name) if len(reg.value) % total: @@ -445,7 +445,7 @@ class DtbPlatdata(object): reg.na = na reg.ns = ns if na != 1 or ns != 1: - reg.type = fdt.TYPE_INT64 + reg.type = fdt.Type.INT64 i = 0 new_value = [] val = reg.value diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index 03b86773d5f..cb365ca094a 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -5,6 +5,7 @@ # Written by Simon Glass sjg@chromium.org #
+from enum import IntEnum import struct import sys
@@ -22,7 +23,25 @@ from patman import tools # so it is fairly efficient.
# A list of types we support -(TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL, TYPE_INT64) = range(5) +class Type(IntEnum): + (BYTE, INT, STRING, BOOL, INT64) = range(5) + + def is_wider_than(self, other): + """Check if another type is 'wider' than this one + + A wider type is one that holds more information than an earlier one, + similar to the concept of type-widening in C. + + This uses a simple arithmetic comparison, since type values are in order + from narrowest (BYTE) to widest (INT64). + + Args: + other: Other type to compare against + + Return: + True if the other type is wider + """ + return self.value > other.value
def CheckErr(errnum, msg): if errnum: @@ -41,9 +60,9 @@ def BytesToValue(data): Type of data Data, either a single element or a list of elements. Each element is one of: - TYPE_STRING: str/bytes value from the property - TYPE_INT: a byte-swapped integer stored as a 4-byte str/bytes - TYPE_BYTE: a byte stored as a single-byte str/bytes + Type.STRING: str/bytes value from the property + Type.INT: a byte-swapped integer stored as a 4-byte str/bytes + Type.BYTE: a byte stored as a single-byte str/bytes """ data = bytes(data) size = len(data) @@ -63,21 +82,21 @@ def BytesToValue(data): is_string = False if is_string: if count == 1: - return TYPE_STRING, strings[0].decode() + return Type.STRING, strings[0].decode() else: - return TYPE_STRING, [s.decode() for s in strings[:-1]] + return Type.STRING, [s.decode() for s in strings[:-1]] if size % 4: if size == 1: - return TYPE_BYTE, tools.ToChar(data[0]) + return Type.BYTE, tools.ToChar(data[0]) else: - return TYPE_BYTE, [tools.ToChar(ch) for ch in list(data)] + return Type.BYTE, [tools.ToChar(ch) for ch in list(data)] val = [] for i in range(0, size, 4): val.append(data[i:i + 4]) if size == 4: - return TYPE_INT, val[0] + return Type.INT, val[0] else: - return TYPE_INT, val + return Type.INT, val
class Prop: @@ -97,7 +116,7 @@ class Prop: self.bytes = bytes(data) self.dirty = False if not data: - self.type = TYPE_BOOL + self.type = Type.BOOL self.value = True return self.type, self.value = BytesToValue(bytes(data)) @@ -128,9 +147,8 @@ class Prop: update the current property to be like the second, since it is less specific. """ - if newprop.type < self.type: - # Special handling to convert an int into bytes - if self.type == TYPE_INT and newprop.type == TYPE_BYTE: + if self.type.is_wider_than(newprop.type): + if self.type == Type.INT and newprop.type == Type.BYTE: if type(self.value) == list: new_value = [] for val in self.value: @@ -155,11 +173,11 @@ class Prop: Returns: A single value of the given type """ - if type == TYPE_BYTE: + if type == Type.BYTE: return chr(0) - elif type == TYPE_INT: + elif type == Type.INT: return struct.pack('>I', 0); - elif type == TYPE_STRING: + elif type == Type.STRING: return '' else: return True @@ -184,7 +202,7 @@ class Prop: """ self.bytes = struct.pack('>I', val); self.value = self.bytes - self.type = TYPE_INT + self.type = Type.INT self.dirty = True
def SetData(self, bytes): diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index a5836e04b7a..6dd8a5ca473 100755 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -134,13 +134,13 @@ class TestDtoc(unittest.TestCase): def test_get_value(self): """Test operation of get_value() function""" self.assertEqual('0x45', - get_value(fdt.TYPE_INT, struct.pack('>I', 0x45))) + get_value(fdt.Type.INT, struct.pack('>I', 0x45))) self.assertEqual('0x45', - get_value(fdt.TYPE_BYTE, struct.pack('<I', 0x45))) + get_value(fdt.Type.BYTE, struct.pack('<I', 0x45))) self.assertEqual('0x0', - get_value(fdt.TYPE_BYTE, struct.pack('>I', 0x45))) - self.assertEqual('"test"', get_value(fdt.TYPE_STRING, 'test')) - self.assertEqual('true', get_value(fdt.TYPE_BOOL, None)) + get_value(fdt.Type.BYTE, struct.pack('>I', 0x45))) + self.assertEqual('"test"', get_value(fdt.Type.STRING, 'test')) + self.assertEqual('true', get_value(fdt.Type.BOOL, None))
def test_get_compat_name(self): """Test operation of get_compat_name() function""" diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index cfe3e04c7ad..10e7f33a595 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -19,7 +19,7 @@ sys.path.insert(1, os.path.join(our_path, '..')) from dtoc import fdt from dtoc import fdt_util from dtoc.fdt_util import fdt32_to_cpu -from fdt import TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL, BytesToValue +from fdt import Type, BytesToValue import libfdt from patman import command from patman import test_util @@ -127,7 +127,7 @@ class TestFdt(unittest.TestCase):
def testBytesToValue(self): self.assertEqual(BytesToValue(b'this\0is\0'), - (TYPE_STRING, ['this', 'is'])) + (Type.STRING, ['this', 'is']))
class TestNode(unittest.TestCase): """Test operation of the Node class""" @@ -249,46 +249,46 @@ class TestProp(unittest.TestCase): def testMakeProp(self): """Test we can convert all the the types that are supported""" prop = self._ConvertProp('boolval') - self.assertEqual(fdt.TYPE_BOOL, prop.type) + self.assertEqual(Type.BOOL, prop.type) self.assertEqual(True, prop.value)
prop = self._ConvertProp('intval') - self.assertEqual(fdt.TYPE_INT, prop.type) + self.assertEqual(Type.INT, prop.type) self.assertEqual(1, fdt32_to_cpu(prop.value))
prop = self._ConvertProp('intarray') - self.assertEqual(fdt.TYPE_INT, prop.type) + self.assertEqual(Type.INT, prop.type) val = [fdt32_to_cpu(val) for val in prop.value] self.assertEqual([2, 3, 4], val)
prop = self._ConvertProp('byteval') - self.assertEqual(fdt.TYPE_BYTE, prop.type) + self.assertEqual(Type.BYTE, prop.type) self.assertEqual(5, ord(prop.value))
prop = self._ConvertProp('longbytearray') - self.assertEqual(fdt.TYPE_BYTE, prop.type) + self.assertEqual(Type.BYTE, prop.type) val = [ord(val) for val in prop.value] self.assertEqual([9, 10, 11, 12, 13, 14, 15, 16, 17], val)
prop = self._ConvertProp('stringval') - self.assertEqual(fdt.TYPE_STRING, prop.type) + self.assertEqual(Type.STRING, prop.type) self.assertEqual('message', prop.value)
prop = self._ConvertProp('stringarray') - self.assertEqual(fdt.TYPE_STRING, prop.type) + self.assertEqual(Type.STRING, prop.type) self.assertEqual(['multi-word', 'message'], prop.value)
prop = self._ConvertProp('notstring') - self.assertEqual(fdt.TYPE_BYTE, prop.type) + self.assertEqual(Type.BYTE, prop.type) val = [ord(val) for val in prop.value] self.assertEqual([0x20, 0x21, 0x22, 0x10, 0], val)
def testGetEmpty(self): """Tests the GetEmpty() function for the various supported types""" - self.assertEqual(True, fdt.Prop.GetEmpty(fdt.TYPE_BOOL)) - self.assertEqual(chr(0), fdt.Prop.GetEmpty(fdt.TYPE_BYTE)) - self.assertEqual(tools.GetBytes(0, 4), fdt.Prop.GetEmpty(fdt.TYPE_INT)) - self.assertEqual('', fdt.Prop.GetEmpty(fdt.TYPE_STRING)) + self.assertEqual(True, fdt.Prop.GetEmpty(Type.BOOL)) + self.assertEqual(chr(0), fdt.Prop.GetEmpty(Type.BYTE)) + self.assertEqual(tools.GetBytes(0, 4), fdt.Prop.GetEmpty(Type.INT)) + self.assertEqual('', fdt.Prop.GetEmpty(Type.STRING))
def testGetOffset(self): """Test we can get the offset of a property""" @@ -304,13 +304,13 @@ class TestProp(unittest.TestCase): # No action prop2 = node2.props['intval'] prop.Widen(prop2) - self.assertEqual(fdt.TYPE_INT, prop.type) + self.assertEqual(Type.INT, prop.type) self.assertEqual(1, fdt32_to_cpu(prop.value))
# Convert singla value to array prop2 = self.node.props['intarray'] prop.Widen(prop2) - self.assertEqual(fdt.TYPE_INT, prop.type) + self.assertEqual(Type.INT, prop.type) self.assertTrue(isinstance(prop.value, list))
# A 4-byte array looks like a single integer. When widened by a longer

Use an Enum instead of the current ad-hoc constants, so that there is a data type associated with each 'type' value.
Signed-off-by: Simon Glass sjg@chromium.org ---
tools/binman/fdt_test.py | 14 +++++----- tools/dtoc/dtb_platdata.py | 26 +++++++++--------- tools/dtoc/fdt.py | 54 +++++++++++++++++++++++++------------- tools/dtoc/test_dtoc.py | 10 +++---- tools/dtoc/test_fdt.py | 32 +++++++++++----------- 5 files changed, 77 insertions(+), 59 deletions(-)
Applied to u-boot-dm, thanks!

We don't need these now that everything uses Python 3. Remove them and the extra code in GetBytes() and ToBytes() too.
Signed-off-by: Simon Glass sjg@chromium.org ---
tools/binman/etype/fmap.py | 2 +- tools/binman/fmap_util.py | 3 +-- tools/dtoc/dtb_platdata.py | 3 ++- tools/patman/func_test.py | 16 +++++-------- tools/patman/gitutil.py | 3 +-- tools/patman/series.py | 4 +--- tools/patman/settings.py | 5 ++-- tools/patman/tools.py | 47 +++----------------------------------- 8 files changed, 17 insertions(+), 66 deletions(-)
diff --git a/tools/binman/etype/fmap.py b/tools/binman/etype/fmap.py index 3e9b815d119..fe81c6f64a5 100644 --- a/tools/binman/etype/fmap.py +++ b/tools/binman/etype/fmap.py @@ -52,7 +52,7 @@ class Entry_fmap(Entry): if pos is not None: pos -= entry.section.GetRootSkipAtStart() areas.append(fmap_util.FmapArea(pos or 0, entry.size or 0, - tools.FromUnicode(entry.name), 0)) + entry.name, 0))
entries = self.GetImage().GetEntries() areas = [] diff --git a/tools/binman/fmap_util.py b/tools/binman/fmap_util.py index 25fe60a9cc3..b03fc28fbb4 100644 --- a/tools/binman/fmap_util.py +++ b/tools/binman/fmap_util.py @@ -111,8 +111,7 @@ def EncodeFmap(image_size, name, areas): ConvertName(names, params) return struct.pack(fmt, *params)
- values = FmapHeader(FMAP_SIGNATURE, 1, 0, 0, image_size, - tools.FromUnicode(name), len(areas)) + values = FmapHeader(FMAP_SIGNATURE, 1, 0, 0, image_size, name, len(areas)) blob = _FormatBlob(FMAP_HEADER_FORMAT, FMAP_HEADER_NAMES, values) for area in areas: blob += _FormatBlob(FMAP_AREA_FORMAT, FMAP_AREA_NAMES, area) diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index 7926fe3a792..ee98010423c 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -109,7 +109,8 @@ def get_value(ftype, value): if ftype == fdt.Type.INT: return '%#x' % fdt_util.fdt32_to_cpu(value) elif ftype == fdt.Type.BYTE: - return '%#x' % tools.ToByte(value[0]) + ch = value[0] + return '%#x' % ord(ch) if type(ch) == str else ch elif ftype == fdt.Type.STRING: # Handle evil ACPI backslashes by adding another backslash before them. # So "\_SB.GPO0" in the device tree effectively stays like that in C diff --git a/tools/patman/func_test.py b/tools/patman/func_test.py index 810af9c6042..3a229be1ba8 100644 --- a/tools/patman/func_test.py +++ b/tools/patman/func_test.py @@ -199,17 +199,14 @@ class TestFunctional(unittest.TestCase): while 'Cc:' in lines[line]: line += 1 self.assertEqual('To: u-boot@lists.denx.de', lines[line]) - self.assertEqual('Cc: %s' % tools.FromUnicode(stefan), - lines[line + 1]) + self.assertEqual('Cc: %s' % stefan, lines[line + 1]) self.assertEqual('Version: 3', lines[line + 2]) self.assertEqual('Prefix:\t RFC', lines[line + 3]) self.assertEqual('Cover: 4 lines', lines[line + 4]) line += 5 self.assertEqual(' Cc: %s' % fred, lines[line + 0]) - self.assertEqual(' Cc: %s' % tools.FromUnicode(ed), - lines[line + 1]) - self.assertEqual(' Cc: %s' % tools.FromUnicode(mel), - lines[line + 2]) + self.assertEqual(' Cc: %s' % ed, lines[line + 1]) + self.assertEqual(' Cc: %s' % mel, lines[line + 2]) self.assertEqual(' Cc: %s' % rick, lines[line + 3]) expected = ('Git command: git send-email --annotate ' '--in-reply-to="%s" --to "u-boot@lists.denx.de" ' @@ -217,12 +214,11 @@ class TestFunctional(unittest.TestCase): % (in_reply_to, stefan, sys.argv[0], cc_file, cover_fname, ' '.join(args))) line += 4 - self.assertEqual(expected, tools.ToUnicode(lines[line])) + self.assertEqual(expected, lines[line])
- self.assertEqual(('%s %s\0%s' % (args[0], rick, stefan)), - tools.ToUnicode(cc_lines[0])) + self.assertEqual(('%s %s\0%s' % (args[0], rick, stefan)), cc_lines[0]) self.assertEqual(('%s %s\0%s\0%s\0%s' % (args[1], fred, ed, rick, - stefan)), tools.ToUnicode(cc_lines[1])) + stefan)), cc_lines[1])
expected = ''' This is a test of how the cover diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py index 27a0a9fbc1f..1ac5a6aacda 100644 --- a/tools/patman/gitutil.py +++ b/tools/patman/gitutil.py @@ -379,7 +379,6 @@ def BuildEmailList(in_list, tag=None, alias=None, raise_on_error=True): raw += LookupEmail(item, alias, raise_on_error=raise_on_error) result = [] for item in raw: - item = tools.FromUnicode(item) if not item in result: result.append(item) if tag: @@ -490,7 +489,7 @@ def EmailPatches(series, cover_fname, args, dry_run, raise_on_error, cc_fname, if smtp_server: cmd.append('--smtp-server=%s' % smtp_server) if in_reply_to: - cmd.append('--in-reply-to="%s"' % tools.FromUnicode(in_reply_to)) + cmd.append('--in-reply-to="%s"' % in_reply_to) if thread: cmd.append('--thread')
diff --git a/tools/patman/series.py b/tools/patman/series.py index 9f885c89873..76a21683e55 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -268,7 +268,6 @@ class Series(dict): for x in set(cc) & set(settings.bounces): print(col.Color(col.YELLOW, 'Skipping "%s"' % x)) cc = set(cc) - set(settings.bounces) - cc = [tools.FromUnicode(m) for m in cc] if limit is not None: cc = cc[:limit] all_ccs += cc @@ -277,11 +276,10 @@ class Series(dict):
if cover_fname: cover_cc = gitutil.BuildEmailList(self.get('cover_cc', '')) - cover_cc = [tools.FromUnicode(m) for m in cover_cc] cover_cc = list(set(cover_cc + all_ccs)) if limit is not None: cover_cc = cover_cc[:limit] - cc_list = '\0'.join([tools.ToUnicode(x) for x in sorted(cover_cc)]) + cc_list = '\0'.join([x for x in sorted(cover_cc)]) print(cover_fname, cc_list, file=fd)
fd.close() diff --git a/tools/patman/settings.py b/tools/patman/settings.py index 732bd401067..a8fb805793a 100644 --- a/tools/patman/settings.py +++ b/tools/patman/settings.py @@ -111,7 +111,7 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser): val = ConfigParser.SafeConfigParser.get( self, section, option, *args, **kwargs ) - return tools.ToUnicode(val) + return val
def items(self, section, *args, **kwargs): """Extend SafeConfigParser to add project_section to section. @@ -146,8 +146,7 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
item_dict = dict(top_items) item_dict.update(project_items) - return {(tools.ToUnicode(item), tools.ToUnicode(val)) - for item, val in item_dict.items()} + return {(item, val) for item, val in item_dict.items()}
def ReadGitAliases(fname): """Read a git alias file. This is in the form used by git: diff --git a/tools/patman/tools.py b/tools/patman/tools.py index bbb157da873..55ba1e9c985 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -414,8 +414,6 @@ def WriteFile(fname, data, binary=True): def GetBytes(byte, size): """Get a string of bytes of a given size
- This handles the unfortunate different between Python 2 and Python 2. - Args: byte: Numeric byte value to use size: Size of bytes/string to return @@ -423,43 +421,7 @@ def GetBytes(byte, size): Returns: A bytes type with 'byte' repeated 'size' times """ - if sys.version_info[0] >= 3: - data = bytes([byte]) * size - else: - data = chr(byte) * size - return data - -def ToUnicode(val): - """Make sure a value is a unicode string - - This allows some amount of compatibility between Python 2 and Python3. For - the former, it returns a unicode object. - - Args: - val: string or unicode object - - Returns: - unicode version of val - """ - if sys.version_info[0] >= 3: - return val - return val if isinstance(val, unicode) else val.decode('utf-8') - -def FromUnicode(val): - """Make sure a value is a non-unicode string - - This allows some amount of compatibility between Python 2 and Python3. For - the former, it converts a unicode object to a string. - - Args: - val: string or unicode object - - Returns: - non-unicode version of val - """ - if sys.version_info[0] >= 3: - return val - return val if isinstance(val, str) else val.encode('utf-8') + return bytes([byte]) * size
def ToByte(ch): """Convert a character to an ASCII value @@ -506,12 +468,9 @@ def ToBytes(string): string: string to convert
Returns: - Python 3: A bytes type - Python 2: A string type + A bytes type """ - if sys.version_info[0] >= 3: - return string.encode('utf-8') - return string + return string.encode('utf-8')
def ToString(bval): """Convert a bytes type into a str type

We don't need these now that everything uses Python 3. Remove them and the extra code in GetBytes() and ToBytes() too.
Signed-off-by: Simon Glass sjg@chromium.org ---
tools/binman/etype/fmap.py | 2 +- tools/binman/fmap_util.py | 3 +-- tools/dtoc/dtb_platdata.py | 3 ++- tools/patman/func_test.py | 16 +++++-------- tools/patman/gitutil.py | 3 +-- tools/patman/series.py | 4 +--- tools/patman/settings.py | 5 ++-- tools/patman/tools.py | 47 +++----------------------------------- 8 files changed, 17 insertions(+), 66 deletions(-)
Applied to u-boot-dm, thanks!

This is not needed in Python 3. Drop it.
Signed-off-by: Simon Glass sjg@chromium.org ---
tools/binman/elf.py | 6 +++--- tools/dtoc/dtb_platdata.py | 2 +- tools/patman/tools.py | 15 --------------- 3 files changed, 4 insertions(+), 19 deletions(-)
diff --git a/tools/binman/elf.py b/tools/binman/elf.py index 5e566e56cbf..249074a334a 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -158,9 +158,9 @@ def MakeElf(elf_fname, text, data):
# Spilt the text into two parts so that we can make the entry point two # bytes after the start of the text section - text_bytes1 = ['\t.byte\t%#x' % tools.ToByte(byte) for byte in text[:2]] - text_bytes2 = ['\t.byte\t%#x' % tools.ToByte(byte) for byte in text[2:]] - data_bytes = ['\t.byte\t%#x' % tools.ToByte(byte) for byte in data] + text_bytes1 = ['\t.byte\t%#x' % byte for byte in text[:2]] + text_bytes2 = ['\t.byte\t%#x' % byte for byte in text[2:]] + data_bytes = ['\t.byte\t%#x' % byte for byte in data] with open(s_file, 'w') as fd: print('''/* Auto-generated C program to produce an ELF file for testing */
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index ee98010423c..0ef245397a9 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -110,7 +110,7 @@ def get_value(ftype, value): return '%#x' % fdt_util.fdt32_to_cpu(value) elif ftype == fdt.Type.BYTE: ch = value[0] - return '%#x' % ord(ch) if type(ch) == str else ch + return '%#x' % (ord(ch) if type(ch) == str else ch) elif ftype == fdt.Type.STRING: # Handle evil ACPI backslashes by adding another backslash before them. # So "\_SB.GPO0" in the device tree effectively stays like that in C diff --git a/tools/patman/tools.py b/tools/patman/tools.py index 55ba1e9c985..7cd58031e78 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -423,21 +423,6 @@ def GetBytes(byte, size): """ return bytes([byte]) * size
-def ToByte(ch): - """Convert a character to an ASCII value - - This is useful because in Python 2 bytes is an alias for str, but in - Python 3 they are separate types. This function converts the argument to - an ASCII value in either case. - - Args: - ch: A string (Python 2) or byte (Python 3) value - - Returns: - integer ASCII value for ch - """ - return ord(ch) if type(ch) == str else ch - def ToChar(byte): """Convert a byte to a character

This is not needed in Python 3. Drop it.
Signed-off-by: Simon Glass sjg@chromium.org ---
tools/binman/elf.py | 6 +++--- tools/dtoc/dtb_platdata.py | 2 +- tools/patman/tools.py | 15 --------------- 3 files changed, 4 insertions(+), 19 deletions(-)
Applied to u-boot-dm, thanks!

This is useful anymore, since we always want to call chr() in Python 3. Drop it and adjust callers to use chr().
Also drop ToChars() which is no-longer used.
Signed-off-by: Simon Glass sjg@chromium.org ---
tools/dtoc/fdt.py | 8 ++++---- tools/dtoc/test_fdt.py | 2 +- tools/patman/tools.py | 23 ----------------------- 3 files changed, 5 insertions(+), 28 deletions(-)
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index cb365ca094a..4a78c737252 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -87,9 +87,9 @@ def BytesToValue(data): return Type.STRING, [s.decode() for s in strings[:-1]] if size % 4: if size == 1: - return Type.BYTE, tools.ToChar(data[0]) + return Type.BYTE, chr(data[0]) else: - return Type.BYTE, [tools.ToChar(ch) for ch in list(data)] + return Type.BYTE, [chr(ch) for ch in list(data)] val = [] for i in range(0, size, 4): val.append(data[i:i + 4]) @@ -152,9 +152,9 @@ class Prop: if type(self.value) == list: new_value = [] for val in self.value: - new_value += [tools.ToChar(by) for by in val] + new_value += [chr(by) for by in val] else: - new_value = [tools.ToChar(by) for by in self.value] + new_value = [chr(by) for by in self.value] self.value = new_value self.type = newprop.type
diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index 10e7f33a595..dc6943f7337 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -46,7 +46,7 @@ def _GetPropertyValue(dtb, node, prop_name): # Add 12, which is sizeof(struct fdt_property), to get to start of data offset = prop.GetOffset() + 12 data = dtb.GetContents()[offset:offset + len(prop.value)] - return prop, [tools.ToChar(x) for x in data] + return prop, [chr(x) for x in data]
class TestFdt(unittest.TestCase): diff --git a/tools/patman/tools.py b/tools/patman/tools.py index 7cd58031e78..00c7013924d 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -423,29 +423,6 @@ def GetBytes(byte, size): """ return bytes([byte]) * size
-def ToChar(byte): - """Convert a byte to a character - - This is useful because in Python 2 bytes is an alias for str, but in - Python 3 they are separate types. This function converts an ASCII value to - a value with the appropriate type in either case. - - Args: - byte: A byte or str value - """ - return chr(byte) if type(byte) != str else byte - -def ToChars(byte_list): - """Convert a list of bytes to a str/bytes type - - Args: - byte_list: List of ASCII values representing the string - - Returns: - string made by concatenating all the ASCII values - """ - return ''.join([chr(byte) for byte in byte_list]) - def ToBytes(string): """Convert a str type into a bytes type

This is useful anymore, since we always want to call chr() in Python 3. Drop it and adjust callers to use chr().
Also drop ToChars() which is no-longer used.
Signed-off-by: Simon Glass sjg@chromium.org ---
tools/dtoc/fdt.py | 8 ++++---- tools/dtoc/test_fdt.py | 2 +- tools/patman/tools.py | 23 ----------------------- 3 files changed, 5 insertions(+), 28 deletions(-)
Applied to u-boot-dm, thanks!

Update this, mostly to add comments for argument and return types. It is probably still too early to use type hinting since it was introduced in 3.5.
Signed-off-by: Simon Glass sjg@chromium.org ---
tools/dtoc/dtb_platdata.py | 71 ++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 29 deletions(-)
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index 0ef245397a9..6b10eabafb9 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -9,6 +9,8 @@
This supports converting device tree data to C structures definitions and static data. + +See doc/driver-model/of-plat.rst for more informaiton """
import collections @@ -19,9 +21,9 @@ import sys
from dtoc import fdt from dtoc import fdt_util -from patman import tools
-# When we see these properties we ignore them - i.e. do not create a structure member +# When we see these properties we ignore them - i.e. do not create a structure +# member PROP_IGNORE_LIST = [ '#address-cells', '#gpio-cells', @@ -69,9 +71,9 @@ def conv_name_to_c(name): (400ms for 1m calls versus 1000ms for the 're' version).
Args: - name: Name to convert + name (str): Name to convert Return: - String containing the C version of this name + str: String containing the C version of this name """ new = name.replace('@', '_at_') new = new.replace('-', '_') @@ -83,11 +85,11 @@ def tab_to(num_tabs, line): """Append tabs to a line of text to reach a tab stop.
Args: - num_tabs: Tab stop to obtain (0 = column 0, 1 = column 8, etc.) - line: Line of text to append to + num_tabs (int): Tab stop to obtain (0 = column 0, 1 = column 8, etc.) + line (str): Line of text to append to
Returns: - line with the correct number of tabs appeneded. If the line already + str: line with the correct number of tabs appeneded. If the line already extends past that tab stop then a single space is appended. """ if len(line) >= num_tabs * 8: @@ -103,28 +105,31 @@ def get_value(ftype, value): For booleans this return 'true'
Args: - type: Data type (fdt_util) - value: Data value, as a string of bytes + ftype (fdt.Type): Data type (fdt_util) + value (bytes): Data value, as a string of bytes + + Returns: + str: String representation of the value """ if ftype == fdt.Type.INT: return '%#x' % fdt_util.fdt32_to_cpu(value) elif ftype == fdt.Type.BYTE: ch = value[0] - return '%#x' % (ord(ch) if type(ch) == str else ch) + return '%#x' % (ord(ch) if isinstance(ch, str) else ch) elif ftype == fdt.Type.STRING: # Handle evil ACPI backslashes by adding another backslash before them. # So "\_SB.GPO0" in the device tree effectively stays like that in C return '"%s"' % value.replace('\', '\\') elif ftype == fdt.Type.BOOL: return 'true' - elif ftype == fdt.Type.INT64: + else: # ftype == fdt.Type.INT64: return '%#x' % value
def get_compat_name(node): """Get the node's list of compatible string as a C identifiers
Args: - node: Node object to check + node (fdt.Node): Node object to check Return: List of C identifiers for all the compatible strings """ @@ -213,7 +218,7 @@ class DtbPlatdata(object): file.
Args: - fname: Filename to send output to, or '-' for stdout + fname (str): Filename to send output to, or '-' for stdout """ if fname == '-': self._outfile = sys.stdout @@ -224,7 +229,7 @@ class DtbPlatdata(object): """Output a string to the output file
Args: - line: String to output + line (str): String to output """ self._outfile.write(line)
@@ -232,7 +237,7 @@ class DtbPlatdata(object): """Buffer up a string to send later
Args: - line: String to add to our 'buffer' list + line (str): String to add to our 'buffer' list """ self._lines.append(line)
@@ -240,7 +245,7 @@ class DtbPlatdata(object): """Get the contents of the output buffer, and clear it
Returns: - The output buffer, which is then cleared for future use + list(str): The output buffer, which is then cleared for future use """ lines = self._lines self._lines = [] @@ -263,9 +268,14 @@ class DtbPlatdata(object): or not. As an interim measure, use a list of known property names.
Args: - prop: Prop object to check - Return: - Number of argument cells is this is a phandle, else None + prop (fdt.Prop): Prop object to check + node_name (str): Node name, only used for raising an error + Returns: + int or None: Number of argument cells is this is a phandle, + else None + Raises: + ValueError: if the phandle cannot be parsed or the required property + is not present """ if prop.name in ['clocks', 'cd-gpios']: if not isinstance(prop.value, list): @@ -294,7 +304,7 @@ class DtbPlatdata(object): break if not cells: raise ValueError("Node '%s' has no cells property" % - (target.name)) + (target.name)) num_args = fdt_util.fdt32_to_cpu(cells.value) max_args = max(max_args, num_args) args.append(num_args) @@ -404,7 +414,7 @@ class DtbPlatdata(object): """Get the number of cells in addresses and sizes for this node
Args: - node: Node to check + node (fdt.None): Node to check
Returns: Tuple: @@ -440,9 +450,10 @@ class DtbPlatdata(object): raise ValueError("Node '%s' reg property is not an int" % node.name) if len(reg.value) % total: - raise ValueError("Node '%s' reg property has %d cells " - 'which is not a multiple of na + ns = %d + %d)' % - (node.name, len(reg.value), na, ns)) + raise ValueError( + "Node '%s' reg property has %d cells " + 'which is not a multiple of na + ns = %d + %d)' % + (node.name, len(reg.value), na, ns)) reg.na = na reg.ns = ns if na != 1 or ns != 1: @@ -585,7 +596,7 @@ class DtbPlatdata(object): """Output the C code for a node
Args: - node: node to output + node (fdt.Node): node to output """ def _output_list(node, prop): """Output the C code for a devicetree property that holds a list @@ -707,10 +718,12 @@ def run_steps(args, dtb_file, include_disabled, output, warning_disabled=False, """Run all the steps of the dtoc tool
Args: - args: List of non-option arguments provided to the problem - dtb_file: Filename of dtb file to process - include_disabled: True to include disabled nodes - output: Name of output file + args (list): List of non-option arguments provided to the problem + dtb_file (str): Filename of dtb file to process + include_disabled (bool): True to include disabled nodes + output (str): Name of output file + Raises: + ValueError: if args has no command, or an unknown command """ if not args: raise ValueError('Please specify a command: struct, platdata')

Hi Simon,
Thanks for this series. I've tried to test it but I had issues to apply it. I have tried in u-boot, both master and next, and u-boot-dm.
Could you please point me to the right tree/version?
On 9/11/20 00:36, Simon Glass wrote:
Update this, mostly to add comments for argument and return types. It is probably still too early to use type hinting since it was introduced in 3.5.
Signed-off-by: Simon Glass sjg@chromium.org
tools/dtoc/dtb_platdata.py | 71 ++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 29 deletions(-)
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index 0ef245397a9..6b10eabafb9 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -9,6 +9,8 @@
This supports converting device tree data to C structures definitions and static data.
+See doc/driver-model/of-plat.rst for more informaiton
*information
"""
import collections @@ -19,9 +21,9 @@ import sys
from dtoc import fdt from dtoc import fdt_util -from patman import tools
-# When we see these properties we ignore them - i.e. do not create a structure member +# When we see these properties we ignore them - i.e. do not create a structure +# member PROP_IGNORE_LIST = [ '#address-cells', '#gpio-cells', @@ -69,9 +71,9 @@ def conv_name_to_c(name): (400ms for 1m calls versus 1000ms for the 're' version).
Args:
name: Name to convert
name (str): Name to convert Return:
String containing the C version of this name
str: String containing the C version of this name """ new = name.replace('@', '_at_') new = new.replace('-', '_')
@@ -83,11 +85,11 @@ def tab_to(num_tabs, line): """Append tabs to a line of text to reach a tab stop.
Args:
num_tabs: Tab stop to obtain (0 = column 0, 1 = column 8, etc.)
line: Line of text to append to
num_tabs (int): Tab stop to obtain (0 = column 0, 1 = column 8, etc.)
line (str): Line of text to append to Returns:
line with the correct number of tabs appeneded. If the line already
str: line with the correct number of tabs appeneded. If the line already extends past that tab stop then a single space is appended. """ if len(line) >= num_tabs * 8:
@@ -103,28 +105,31 @@ def get_value(ftype, value): For booleans this return 'true'
Args:
type: Data type (fdt_util)
value: Data value, as a string of bytes
ftype (fdt.Type): Data type (fdt_util)
value (bytes): Data value, as a string of bytes
- Returns:
str: String representation of the value """ if ftype == fdt.Type.INT: return '%#x' % fdt_util.fdt32_to_cpu(value) elif ftype == fdt.Type.BYTE: ch = value[0]
return '%#x' % (ord(ch) if type(ch) == str else ch)
return '%#x' % (ord(ch) if isinstance(ch, str) else ch) elif ftype == fdt.Type.STRING: # Handle evil ACPI backslashes by adding another backslash before them. # So "\\_SB.GPO0" in the device tree effectively stays like that in C return '"%s"' % value.replace('\\', '\\\\') elif ftype == fdt.Type.BOOL: return 'true'
- elif ftype == fdt.Type.INT64:
else: # ftype == fdt.Type.INT64: return '%#x' % value
def get_compat_name(node): """Get the node's list of compatible string as a C identifiers
Args:
node: Node object to check
node (fdt.Node): Node object to check Return: List of C identifiers for all the compatible strings """
@@ -213,7 +218,7 @@ class DtbPlatdata(object): file.
Args:
fname: Filename to send output to, or '-' for stdout
fname (str): Filename to send output to, or '-' for stdout """ if fname == '-': self._outfile = sys.stdout
@@ -224,7 +229,7 @@ class DtbPlatdata(object): """Output a string to the output file
Args:
line: String to output
line (str): String to output """ self._outfile.write(line)
@@ -232,7 +237,7 @@ class DtbPlatdata(object): """Buffer up a string to send later
Args:
line: String to add to our 'buffer' list
line (str): String to add to our 'buffer' list """ self._lines.append(line)
@@ -240,7 +245,7 @@ class DtbPlatdata(object): """Get the contents of the output buffer, and clear it
Returns:
The output buffer, which is then cleared for future use
list(str): The output buffer, which is then cleared for future use """ lines = self._lines self._lines = []
@@ -263,9 +268,14 @@ class DtbPlatdata(object): or not. As an interim measure, use a list of known property names.
Args:
prop: Prop object to check
Return:
Number of argument cells is this is a phandle, else None
prop (fdt.Prop): Prop object to check
node_name (str): Node name, only used for raising an error
Returns:
int or None: Number of argument cells is this is a phandle,
else None
Raises:
ValueError: if the phandle cannot be parsed or the required property
is not present """ if prop.name in ['clocks', 'cd-gpios']: if not isinstance(prop.value, list):
@@ -294,7 +304,7 @@ class DtbPlatdata(object): break if not cells: raise ValueError("Node '%s' has no cells property" %
(target.name))
(target.name)) num_args = fdt_util.fdt32_to_cpu(cells.value) max_args = max(max_args, num_args) args.append(num_args)
@@ -404,7 +414,7 @@ class DtbPlatdata(object): """Get the number of cells in addresses and sizes for this node
Args:
node: Node to check
node (fdt.None): Node to check Returns: Tuple:
@@ -440,9 +450,10 @@ class DtbPlatdata(object): raise ValueError("Node '%s' reg property is not an int" % node.name) if len(reg.value) % total:
raise ValueError("Node '%s' reg property has %d cells "
'which is not a multiple of na + ns = %d + %d)' %
(node.name, len(reg.value), na, ns))
raise ValueError(
"Node '%s' reg property has %d cells "
'which is not a multiple of na + ns = %d + %d)' %
(node.name, len(reg.value), na, ns)) reg.na = na reg.ns = ns if na != 1 or ns != 1:
@@ -585,7 +596,7 @@ class DtbPlatdata(object): """Output the C code for a node
Args:
node: node to output
node (fdt.Node): node to output """ def _output_list(node, prop): """Output the C code for a devicetree property that holds a list
@@ -707,10 +718,12 @@ def run_steps(args, dtb_file, include_disabled, output, warning_disabled=False, """Run all the steps of the dtoc tool
Args:
args: List of non-option arguments provided to the problem
dtb_file: Filename of dtb file to process
include_disabled: True to include disabled nodes
output: Name of output file
args (list): List of non-option arguments provided to the problem
dtb_file (str): Filename of dtb file to process
include_disabled (bool): True to include disabled nodes
output (str): Name of output file
- Raises:
ValueError: if args has no command, or an unknown command """ if not args: raise ValueError('Please specify a command: struct, platdata')
Regards,
Walter

Hi Simon,
Thanks for this series. I've tried to test it but I had issues to apply it. I have tried in u-boot, both master and next, and u-boot-dm.
Could you please point me to the right tree/version?
On 9/11/20 00:36, Simon Glass wrote:
Update this, mostly to add comments for argument and return types. It is probably still too early to use type hinting since it was introduced in 3.5.
Signed-off-by: Simon Glass sjg@chromium.org
tools/dtoc/dtb_platdata.py | 71 ++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 29 deletions(-)
Applied to u-boot-dm, thanks!

Hi Walter,
On Thu, 12 Nov 2020 at 20:43, Walter Lozano walter.lozano@collabora.com wrote:
Hi Simon,
Thanks for this series. I've tried to test it but I had issues to apply it. I have tried in u-boot, both master and next, and u-boot-dm.
Could you please point me to the right tree/version?
Sorry I missed this email...it is in u-boot-dm/miscb-working
But now it is in dm/next
I am on the trail of a series to instantiate devices in dt_pladata.c a bit like the tiny series. I'm not sure when I'll get more time for it, but hopefully will have patches out in a few weeks. If you'd like to see WIP let me know, but it is a bit rough.
Regards, Simon
participants (2)
-
Simon Glass
-
Walter Lozano