
# HG changeset patch # User Zachary T Welch zach@mandolincreekfarm.com # Fake Node ID 9d36a35567b1e336c031255a40c4999d74aa9ecb
Fix pylint issues in bitwise.py (#159)
diff --git a/chirp/bitwise.py b/chirp/bitwise.py index 39efe8f..d70292f 100644 --- a/chirp/bitwise.py +++ b/chirp/bitwise.py @@ -57,6 +57,10 @@ # as integers directly (for int types). Strings and BCD arrays # behave as expected.
+""" +Parse raw data into a python structure defined by a memory layout. +""" + import struct import os import logging @@ -73,19 +77,22 @@ class ParseError(Exception):
def format_binary(nbits, value, pad=8): + """Format some bits in binary @value into a string, padded out to @pad.""" s = "" - for i in range(0, nbits): + for _ in range(0, nbits): s = "%i%s" % (value & 0x01, s) value >>= 1 return "%s%s" % ((pad - len(s)) * ".", s)
def bits_between(start, end): + """Return a bitmask from start to end.""" bits = (1 << (end - start)) - 1 return bits << start
def pp(structure, level=0): + """Pretty print the given @structure, indented with @level spaces.""" for i in structure: if isinstance(i, list): pp(i, level+2) @@ -135,7 +142,8 @@ def set_string(char_array, string): array_copy(char_array, list(string))
-class DataElement: +class DataElement(object): + """Abstract class for encapsulating a piece of data.""" _size = 1
def __init__(self, data, offset, count=1): @@ -144,38 +152,49 @@ class DataElement: self._count = count
def size(self): + """Return the size of this element in bits.""" return self._size * 8
def get_offset(self): + """Return the offset into the data block.""" return self._offset
- def _get_value(self, data): - raise Exception("Not implemented") + def _get_value(self, dummy): + """Return the value, implemented by subclass.""" + raise Exception("Not implemented for %s" % self.__class__)
def get_value(self): + """Return the parsed value.""" value = self._data[self._offset:self._offset + self._size] return self._get_value(value)
- def set_value(self, value): + def set_value(self, dummy): + """Set the value, implemented by subclass.""" raise Exception("Not implemented for %s" % self.__class__)
def get_raw(self): + """Return the raw binary value.""" return self._data[self._offset:self._offset+self._size]
def set_raw(self, data): + """Set the raw binary value.""" self._data[self._offset] = data[:self._size]
def __getattr__(self, name): + """Return the named attribute, implemented by subclass.""" raise AttributeError("Unknown attribute %s in %s" % (name, self.__class__))
def __repr__(self): + """Return a printable representation of this element.""" return "(%s:%i bytes @ %04x)" % (self.__class__.__name__, self._size, self._offset)
class arrayDataElement(DataElement): + """Encapsulate array element.""" + def __repr__(self): if isinstance(self.__items[0], bcdDataElement): return "%i:[(%i)]" % (len(self.__items), int(self)) @@ -189,16 +208,19 @@ class arrayDataElement(DataElement): return s
def __init__(self, offset): + super(self.__class__, self).__init__(None, offset, 0) self.__items = [] - self._offset = offset
def append(self, item): + """Append a data element to the array.""" self.__items.append(item)
def get_value(self): + """Return the list of data elements.""" return list(self.__items)
def get_raw(self): + """Return the raw binary value of the array.""" return "".join([item.get_raw() for item in self.__items])
def __setitem__(self, index, val): @@ -263,6 +285,7 @@ class arrayDataElement(DataElement): self.__items[i].set_value(value[i])
def index(self, value): + """Return the index of the first data element with the given @value.""" index = 0 for i in self.__items: if i.get_value() == value: @@ -274,6 +297,7 @@ class arrayDataElement(DataElement): return iter(self.__items)
def items(self): + """Generate list of items.""" index = 0 for item in self.__items: yield (str(index), item) @@ -287,6 +311,7 @@ class arrayDataElement(DataElement):
class intDataElement(DataElement): + """Represent a integer data element.""" def __repr__(self): fmt = "0x%%0%iX" % (self._size * 2) return fmt % int(self) @@ -415,6 +440,7 @@ class intDataElement(DataElement):
class u8DataElement(intDataElement): + """Represent a 1-byte unsigned integer.""" _size = 1
def _get_value(self, data): @@ -425,6 +451,7 @@ class u8DataElement(intDataElement):
class u16DataElement(intDataElement): + """Represent a 2-byte big-endian unsigned integer.""" _size = 2 _endianess = ">"
@@ -437,10 +464,12 @@ class u16DataElement(intDataElement):
class ul16DataElement(u16DataElement): + """Represent a 2-byte little-endian unsigned integer.""" _endianess = "<"
class u24DataElement(intDataElement): + """Represent a 3-byte big-endian unsigned integer.""" _size = 3 _endianess = ">"
@@ -461,10 +490,12 @@ class u24DataElement(intDataElement):
class ul24DataElement(u24DataElement): + """Represent a 3-byte little-endian unsigned integer.""" _endianess = "<"
class u32DataElement(intDataElement): + """Represent a 4-byte big-endian unsigned integer.""" _size = 4 _endianess = ">"
@@ -477,10 +508,12 @@ class u32DataElement(intDataElement):
class ul32DataElement(u32DataElement): + """Represent a 4-byte little-endian unsigned integer.""" _endianess = "<"
class i8DataElement(u8DataElement): + """Represent a 1-byte signed integer.""" _size = 1
def _get_value(self, data): @@ -491,6 +524,7 @@ class i8DataElement(u8DataElement):
class i16DataElement(intDataElement): + """Represent a 2-byte big-endian signed integer.""" _size = 2 _endianess = ">"
@@ -503,10 +537,12 @@ class i16DataElement(intDataElement):
class il16DataElement(i16DataElement): + """Represent a 2-byte little-endian signed integer.""" _endianess = "<"
class i24DataElement(intDataElement): + """Represent a 3-byte big-endian signed integer.""" _size = 3 _endianess = ">"
@@ -527,10 +563,12 @@ class i24DataElement(intDataElement):
class il24DataElement(i24DataElement): + """Represent a 3-byte little-endian signed integer.""" _endianess = "<"
class i32DataElement(intDataElement): + """Represent a 4-byte big-endian signed integer.""" _size = 4 _endianess = ">"
@@ -543,10 +581,12 @@ class i32DataElement(intDataElement):
class il32DataElement(i32DataElement): + """Represent a 4-byte little-endian signed integer.""" _endianess = "<"
class charDataElement(DataElement): + """Represent a character.""" _size = 1
def __str__(self): @@ -563,17 +603,21 @@ class charDataElement(DataElement):
class bcdDataElement(DataElement): + """Represent a binary-coded decimal data element.""" def __int__(self): tens, ones = self.get_value() return (tens * 10) + ones
def set_bits(self, mask): + """Set the bits specified in the given @mask.""" self._data[self._offset] = ord(self._data[self._offset]) | int(mask)
def clr_bits(self, mask): + """Clear the bits specified in the given @mask.""" self._data[self._offset] = ord(self._data[self._offset]) & ~int(mask)
def get_bits(self, mask): + """Retrieve the bits specified in the given @mask.""" return ord(self._data[self._offset]) & int(mask)
def set_raw(self, data): @@ -595,14 +639,17 @@ class bcdDataElement(DataElement):
class lbcdDataElement(bcdDataElement): + """Represent a little-endian binary-coded decimal data element.""" _size = 1
class bbcdDataElement(bcdDataElement): + """Represent a big-endian binary-coded decimal data element.""" _size = 1
class bitDataElement(intDataElement): + """Represent a bitwise data element.""" _nbits = 0 _shift = 0 _subgen = u8DataElement # Default to a byte @@ -632,6 +679,7 @@ class bitDataElement(intDataElement):
class structDataElement(DataElement): + """Represent a structure.""" def __repr__(self): s = "struct {" + os.linesep for prop in self._keys: @@ -695,13 +743,11 @@ class structDataElement(DataElement):
def size(self): size = 0 - for name, gen in self._generators.items(): + for _, gen in self._generators.items(): if not isinstance(gen, list): gen = [gen]
- i = 0 for el in gen: - i += 1 size += el.size() return size
@@ -709,21 +755,23 @@ class structDataElement(DataElement): size = self.size() / 8 return self._data[self._offset:self._offset+size]
- def set_raw(self, buffer): - if len(buffer) != (self.size() / 8): + def set_raw(self, buf): + if len(buf) != (self.size() / 8): raise ValueError("Struct size mismatch during set_raw()") - self._data[self._offset] = buffer + self._data[self._offset] = buf
def __iter__(self): for item in self._generators.values(): yield item
def items(self): + """Generate the list of items.""" for key in self._keys: yield key, self._generators[key]
-class Processor: +class Processor(object): + """Parse some data according to a memory layout."""
_types = { "u8": u8DataElement, @@ -749,14 +797,17 @@ class Processor: self._offset = offset self._obj = None self._user_types = {} + self._generators = None
def do_symbol(self, symdef, gen): + """Parse a symbol.""" name = symdef[1] self._generators[name] = gen
def do_bitfield(self, dtype, bitfield): - bytes = self._types[dtype](self._data, 0).size() / 8 - bitsleft = bytes * 8 + """Parse a bitfield.""" + fbytes = self._types[dtype](self._data, 0).size() / 8 + bitsleft = fbytes * 8
for _bitdef, defn in bitfield: name = defn[0][1] @@ -765,6 +816,7 @@ class Processor: raise ParseError("Invalid bitfield spec")
class bitDE(bitDataElement): + """A bitwise data element, @bits wide located at @bitsleft.""" _nbits = bits _shift = bitsleft _subgen = self._types[dtype] @@ -773,22 +825,25 @@ class Processor: bitsleft -= bits
if bitsleft: - LOG.warn("WARNING: %i trailing bits unaccounted for in %s" % - (bitsleft, bitfield)) + LOG.warn("WARNING: %i trailing bits unaccounted for in %s", + bitsleft, bitfield)
- return bytes + return fbytes
def do_bitarray(self, i, count): + """Parse a bitarray.""" if count % 8 != 0: raise ValueError("bit array must be divisible by 8.")
class bitDE(bitDataElement): + """A bitwise data element, 1 bit wide.""" _nbits = 1 _shift = 8 - i % 8
return bitDE(self._data, self._offset)
def parse_defn(self, defn): + """Parse a definition.""" dtype = defn[0]
if defn[1][0] == "bitfield": @@ -821,6 +876,7 @@ class Processor: self._generators[name] = res
def parse_struct_decl(self, struct): + """Parse a structure declaration.""" block = struct[:-1] if block[0][0] == "symbol": # This is a pre-defined struct @@ -834,7 +890,7 @@ class Processor: count = 1
result = arrayDataElement(self._offset) - for i in range(0, count): + for _ in range(0, count): element = structDataElement(self._data, self._offset, count, name=name) result.append(element) @@ -849,11 +905,13 @@ class Processor: self._generators[name] = result
def parse_struct_defn(self, struct): + """Parse a structure definition.""" name = struct[0][1] block = struct[1:] self._user_types[name] = block
def parse_struct(self, struct): + """Parse a structure.""" if struct[0][0] == "struct_defn": return self.parse_struct_defn(struct[0][1]) elif struct[0][0] == "struct_decl": @@ -862,6 +920,7 @@ class Processor: raise Exception("Internal error: What is `%s'?" % struct[0][0])
def parse_directive(self, directive): + """Parse a directive.""" name = directive[0][0] value = directive[0][1][0][1] if name == "seekto": @@ -869,10 +928,11 @@ class Processor: elif name == "seek": self._offset += int(value, 0) elif name == "printoffset": - LOG.debug("%s: %i (0x%08X)" % - (value[1:-1], self._offset, self._offset)) + LOG.debug("%s: %i (0x%08X)", + value[1:-1], self._offset, self._offset)
def parse_block(self, lang): + """Parse a block.""" for t, d in lang: if t == "struct": self.parse_struct(d) @@ -882,12 +942,14 @@ class Processor: self.parse_directive(d)
def parse(self, lang): + """Parse the data using the specified @lang.""" self._generators = structDataElement(self._data, self._offset) self.parse_block(lang) return self._generators
def parse(spec, data, offset=0): + """Parse the @data according to @spec, starting at @offset.""" ast = bitwise_grammar.parse(spec) p = Processor(data, offset) return p.parse(ast) diff --git a/tools/cpep8.lintful b/tools/cpep8.lintful index caf4dcf..3178dae 100644 --- a/tools/cpep8.lintful +++ b/tools/cpep8.lintful @@ -1,7 +1,6 @@ # cpep8.lintful: The list of files that do not meet pylint standards. # DO NOT ADD NEW FILES!! Instead, fix the code to be compliant. # Over time, this list should shrink and (eventually) be eliminated. -./chirp/bitwise.py ./chirp/chirp_common.py ./chirp/directory.py ./chirp/drivers/alinco.py