[chirp_devel] [PATCH 2 of 2] pylint fixes round 1

Dan Smith
Fri Apr 27 14:35:46 PDT 2012


# HG changeset patch
# User Dan Smith <dsmith at danplanet.com>
# Date 1335562541 25200
# Node ID f805c420592f8a8b1b0dd89107920c6bbed7fdf7
# Parent  db82df47f205409ac1f71304f7372ca7f7d88e52
pylint fixes round 1
#93

diff -r db82df47f205 -r f805c420592f chirp/alinco.py
--- a/chirp/alinco.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/alinco.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,11 +13,11 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from chirp import chirp_common, bitwise, memmap, errors, directory
+from chirp import chirp_common, bitwise, memmap, errors, directory, util
 
 import time
 
-DRx35_mem_format = """
+DRX35_MEM_FORMAT = """
 #seekto 0x0120;
 u8 used_flags[25];
 
@@ -59,7 +59,9 @@
 STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0]
 
 class AlincoStyleRadio(chirp_common.CloneModeRadio):
+    """Base class for all known Alinco radios"""
     _memsize = 0
+    _model = "NONE"
 
     def _send(self, data):
         self.pipe.write(data)
@@ -96,20 +98,19 @@
             time.sleep(0.1)
 
             if self.status_fn:
-                s = chirp_common.Status()
-                s.cur = addr + 16
-                s.max = self._memsize
-                s.msg = "Downloading from radio"
-                self.status_fn(s)
+                status = chirp_common.Status()
+                status.cur = addr + 16
+                status.max = self._memsize
+                status.msg = "Downloading from radio"
+                self.status_fn(status)
 
         self._send("AL~E\r\n")
-        r = self.pipe.read(20)
-        #print r
+        self.pipe.read(20)
 
         return memmap.MemoryMap(data)
 
     def _identify(self):
-        for i in range(0, 3):
+        for _i in range(0, 3):
             self._send("%s\r\n" % self._model)
             resp = self.pipe.read(6)
             if resp.strip() == "OK":
@@ -137,18 +138,18 @@
             time.sleep(0.1)
 
             if self.status_fn:
-                s = chirp_common.Status()
-                s.cur = addr + 16
-                s.max = self._memsize
-                s.msg = "Uploading to radio"
-                self.status_fn(s)
+                status = chirp_common.Status()
+                status.cur = addr + 16
+                status.max = self._memsize
+                status.msg = "Uploading to radio"
+                self.status_fn(status)
 
         self._send("AL~E\r\n")
-        r = self.pipe.read(20)
+        self.pipe.read(20)
         #print r
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(DRx35_mem_format, self._mmap)
+        self._memobj = bitwise.parse(DRX35_MEM_FORMAT, self._mmap)
 
     def sync_in(self):
         try:
@@ -183,32 +184,33 @@
     [chr(x + ord("A")) for x in range(0, 26)] + [" "] + \
     list("\x00" * 128)
 
+def _get_name(_mem):
+    name = ""
+    for i in _mem.name:
+        if not i:
+            break
+        name += CHARSET[i]
+    return name
+
+def _set_name(mem, _mem):
+    name = [0x00] * 7
+    j = 0
+    for i in range(0, 7):
+        try:
+            name[j] = CHARSET.index(mem.name[i])
+            j += 1
+        except IndexError:
+            pass
+        except ValueError:
+            pass
+    return name
+
 class DRx35Radio(AlincoStyleRadio):
+    """Base class for the DR-x35 radios"""
     _range = [(118000000, 155000000)]
     _power_levels = []
     _valid_tones = list(chirp_common.TONES)
 
-    def _get_name(self, mem, _mem):
-        name = ""
-        for i in _mem.name:
-            if not i:
-                break
-            name += CHARSET[i]
-        return name
-
-    def _set_name(self, mem, _mem):
-        name = [0x00] * 7
-        j = 0
-        for i in range(0, 7):
-            try:
-                name[j] = CHARSET.index(mem.name[i])
-                j += 1
-            except IndexError:
-                pass
-            except ValueError:
-                pass
-        return name
-
     def get_features(self):
         rf = chirp_common.RadioFeatures()
         rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"]
@@ -254,7 +256,7 @@
         if _skp & bit:
             mem.skip = "S"
 
-        mem.name = self._get_name(mem, _mem).rstrip()
+        mem.name = _get_name(_mem).rstrip()
 
         return mem
 
@@ -298,10 +300,11 @@
         else:
             _skp &= ~bit
 
-        _mem.name = self._set_name(mem, _mem)
+        _mem.name = _set_name(mem, _mem)
 
 @directory.register
 class DR03Radio(DRx35Radio):
+    """Alinco DR03"""
     VENDOR = "Alinco"
     MODEL = "DR03T"
 
@@ -316,6 +319,7 @@
 
 @directory.register
 class DR06Radio(DRx35Radio):
+    """Alinco DR06"""
     VENDOR = "Alinco"
     MODEL = "DR06T"
 
@@ -330,6 +334,7 @@
             
 @directory.register
 class DR135Radio(DRx35Radio):
+    """Alinco DR135"""
     VENDOR = "Alinco"
     MODEL = "DR135T"
 
@@ -344,6 +349,7 @@
 
 @directory.register
 class DR235Radio(DRx35Radio):
+    """Alinco DR235"""
     VENDOR = "Alinco"
     MODEL = "DR235T"
 
@@ -358,6 +364,7 @@
 
 @directory.register
 class DR435Radio(DRx35Radio):
+    """Alinco DR435"""
     VENDOR = "Alinco"
     MODEL = "DR435T"
 
@@ -385,6 +392,7 @@
 
 @directory.register
 class DJ596Radio(DRx35Radio):
+    """Alinco DJ596"""
     VENDOR = "Alinco"
     MODEL = "DJ596"
 
@@ -402,6 +410,7 @@
 
 @directory.register
 class JT220MRadio(DRx35Radio):
+    """Jetstream JT220"""
     VENDOR = "Jetstream"
     MODEL = "JT220M"
 
diff -r db82df47f205 -r f805c420592f chirp/bitwise.py
--- a/chirp/bitwise.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/bitwise.py	Fri Apr 27 14:35:41 2012 -0700
@@ -136,6 +136,10 @@
     def set_raw(self, data):
         self._data[self._offset] = data[:self._size]
 
+    def __getattr__(self, name):
+        raise AttributeError("Unknown attribute %s in %s" % (name,
+                                                             self.__class__))
+
     def __repr__(self):
         return "(%s:%i bytes @ %04x)" % (self.__class__.__name__,
                                          self._size,
@@ -542,7 +546,10 @@
             self._keys.append(key)
 
     def __getattr__(self, name):
-        return self._generators[name]
+        try:
+            return self._generators[name]
+        except KeyError:
+            raise AttributeError("No attribute %s in struct" % name)
 
     def __setattr__(self, name, value):
         if not self.__dict__.has_key("_structDataElement__init"):
diff -r db82df47f205 -r f805c420592f chirp/chirp_common.py
--- a/chirp/chirp_common.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/chirp_common.py	Fri Apr 27 14:35:41 2012 -0700
@@ -17,9 +17,7 @@
     
 #print "Using separation character of '%s'" % SEPCHAR
 
-import threading
 import math
-from decimal import Decimal
 
 from chirp import errors, memmap
 
@@ -60,7 +58,8 @@
     "->DTCS",
 ]
 
-MODES = ["WFM", "FM", "NFM", "AM", "NAM", "DV", "USB", "LSB", "CW", "RTTY", "DIG", "PKT", "NCW", "NCWR", "CWR", "P25"]
+MODES = ["WFM", "FM", "NFM", "AM", "NAM", "DV", "USB", "LSB", "CW", "RTTY",
+         "DIG", "PKT", "NCW", "NCWR", "CWR", "P25"]
 
 STD_6M_OFFSETS = [
     (51620000, 51980000, -500000),
@@ -108,6 +107,7 @@
 
 # NB: This only works for some bands, throws an Exception otherwise
 def freq_to_band(freq):
+    """Returns the band (in cm) for a given frequency"""
     for band, (lo, hi) in BAND_TO_MHZ.items():
         if int(freq) > lo and int(freq) < hi:
             return band
@@ -138,12 +138,15 @@
 CHARSET_ASCII = "".join([chr(x) for x in range(ord(" "), ord("~")+1)])
 
 def watts_to_dBm(watts):
+    """Converts @watts in watts to dBm"""
     return int(10 * math.log10(int(watts * 1000)))
 
 def dBm_to_watts(dBm):
+    """Converts @dBm from dBm to watts"""
     return int(math.pow(10, (dBm - 30) / 10))
 
 class PowerLevel:
+    """Represents a power level supported by a radio"""
     def __init__(self, label, watts=0, dBm=0):
         if watts:
             dBm = watts_to_dBm(watts)
@@ -180,6 +183,7 @@
         return "%s (%i dBm)" % (self._label, self._power)
 
 def parse_freq(freqstr):
+    """Parse a frequency string and return the value in integral Hz"""
     if "." in freqstr:
         MHz, kHz = freqstr.split(".")
     else:
@@ -192,9 +196,12 @@
     return int(("%s%-6s" % (MHz, kHz)).replace(" ", "0"))
 
 def format_freq(freq):
+    """Format a frequency given in Hz as a string"""
+
     return "%i.%06i" % (freq / 1000000, freq % 1000000)
 
 class Memory:
+    """Base class for a single radio memory"""
     freq = 0
     number = 0
     extd_number = ""
@@ -262,13 +269,15 @@
         return "Memory[%i]" % self.number
 
     def dupe(self):
-        m = self.__class__()
+        """Return a deep copy of @self"""
+        mem = self.__class__()
         for k, v in self.__dict__.items():
-            m.__dict__[k] = v
+            mem.__dict__[k] = v
 
-        return m
+        return mem
 
     def clone(self, source):
+        """Absorb all of the properties of @source"""
         for k, v in source.__dict__.items():
             self.__dict__[k] = v
 
@@ -294,9 +303,11 @@
         self.__dict__[name] = val
 
     def format_freq(self):
+        """Return a properly-formatted string of this memory's frequency"""
         return format_freq(self.freq)
 
     def parse_freq(self, freqstr):
+        """Set the frequency from a string"""
         self.freq = parse_freq(freqstr)
         return self.freq
 
@@ -321,7 +332,7 @@
         else:
             dup = self.duplex
 
-        return "Memory %i: %s%s%s %s (%s) r%.1f%s c%.1f%s d%03i%s%s [TS=%.2f]"% \
+        return "Memory %i: %s%s%s %s (%s) r%.1f%s c%.1f%s d%03i%s%s [%.2f]"% \
             (self.number,
              format_freq(self.freq),
              dup,
@@ -338,6 +349,7 @@
              self.tuning_step)
 
     def to_csv(self):
+        """Return a CSV representation of this memory"""
         return [
             "%i"   % self.number,
             "%s"   % self.name,
@@ -355,18 +367,16 @@
             "%s"   % self.comment,
             "", "", "", ""]
 
-    class Callable:
-        def __init__(self, target):
-            self.__call__ = target
-
-    def _from_csv(_line):
+    @classmethod
+    def _from_csv(cls, _line):
         line = _line.strip()
         if line.startswith("Location"):
             raise errors.InvalidMemoryLocation("Non-CSV line")
 
         vals = line.split(SEPCHAR)
         if len(vals) < 11:
-            raise errors.InvalidDataError("CSV format error (14 columns expected)")
+            raise errors.InvalidDataError("CSV format error " +
+                                          "(14 columns expected)")
 
         if vals[10] == "DV":
             mem = DVMemory()
@@ -376,9 +386,8 @@
         mem.really_from_csv(vals)
         return mem
 
-    from_csv = Callable(_from_csv)
-
     def really_from_csv(self, vals):
+        """Careful parsing of split-out @vals"""
         try:
             self.number = int(vals[0])
         except:
@@ -450,6 +459,7 @@
         return True
 
 class DVMemory(Memory):
+    """A Memory with D-STAR attributes"""
     dv_urcall = "CQCQCQ"
     dv_rpt1call = ""
     dv_rpt2call = ""
@@ -493,10 +503,11 @@
         self.dv_rpt2call = vals[17].rstrip()[:8]
         try:
             self.dv_code = int(vals[18].strip())
-        except:
+        except Exception:
             self.dv_code = 0
 
 class Bank:
+    """Base class for a radio's Bank"""
     def __init__(self, model, index, name):
         self._model = model
         self._index = index
@@ -520,6 +531,7 @@
         return self.get_index() == other.get_index()
 
 class NamedBank(Bank):
+    """A bank that can have a name"""
     def set_name(self, name):
         """Changes the user-adjustable bank name"""
         self._name = name
@@ -556,6 +568,7 @@
         raise Exception("Not implemented")
 
 class BankIndexInterface:
+    """Interface for banks with index capabilities"""
     def get_index_bounds(self):
         """Returns a tuple (lo,hi) of the minimum and maximum bank indices"""
         raise Exception("Not implemented")
@@ -579,18 +592,16 @@
     pass
 
 def console_status(status):
+    """Write a status object to the console"""
     import sys
 
     sys.stderr.write("\r%s" % status)
     
 
-class Callable:
-    def __init__(self, target):
-        self.__call__ = target
-
 BOOLEAN = [True, False]
 
 class RadioFeatures:
+    """Radio Feature Flags"""
     _valid_map = {
         # General
         "has_bank_index"      : BOOLEAN,
@@ -602,7 +613,6 @@
         "has_bank"            : BOOLEAN,
         "has_bank_names"      : BOOLEAN,
         "has_tuning_step"     : BOOLEAN,
-        "has_name"            : BOOLEAN,
         "has_ctone"           : BOOLEAN,
         "has_cross"           : BOOLEAN,
         "has_infinite_number" : BOOLEAN,
@@ -663,11 +673,17 @@
                                                                         name))
         self.__dict__[name] = val
 
+    def __getattr__(self, name):
+        raise AttributeError("pylint is confused by RadioFeatures")
+
     def init(self, attribute, default, doc=None):
+        """Initialize a feature flag @attribute with default value @default,
+        and documentation string @doc"""
         self.__setattr__(attribute, default)
         self.__docs[attribute] = doc
 
     def get_doc(self, attribute):
+        """Return the description of @attribute"""
         return self.__docs[attribute]
 
     def __init__(self):
@@ -751,70 +767,79 @@
                   "callsign at the beginning of the master URCALL list")
 
     def is_a_feature(self, name):
+        """Returns True if @name is a valid feature flag name"""
         return name in self._valid_map.keys()
 
     def __getitem__(self, name):
         return self.__dict__[name]
 
 class ValidationMessage(str):
+    """Base class for Validation Errors and Warnings"""
     pass
 
 class ValidationWarning(ValidationMessage):
+    """A non-fatal warning during memory validation"""
     pass
 
 class ValidationError(ValidationMessage):
+    """A fatal error during memory validation"""
     pass
 
 class Radio:
+    """Base class for all Radio drivers"""
     BAUD_RATE = 9600
     HARDWARE_FLOW = False
     VENDOR = "Unknown"
     MODEL = "Unknown"
     VARIANT = ""
 
-    status_fn = lambda x, y: console_status(y)
+    def status_fn(self, status):
+        """Deliver @status to the UI"""
+        console_status(status)
 
     def __init__(self, pipe):
         self.errors = []
         self.pipe = pipe
 
     def get_features(self):
+        """Return a RadioFeatures object for this radio"""
         return RadioFeatures()
 
     def get_settings(self):
+        """Return a RadioSettingsGroup object for this radio"""
         return None
 
     def set_settings(self, settings):
+        """Sets the settings contained in the @settings object that has
+        been queried with get_settings() and modified"""
         raise Exception("Not implemented")
 
-    def _get_name_raw(*args):
-        cls = args[-1]
+    @classmethod
+    def get_name(cls):
+        """Return a printable name for this radio"""
         return "%s %s" % (cls.VENDOR, cls.MODEL)
 
-    def get_name(self):
-        return self._get_name_raw(self.__class__)
-
-    _get_name = Callable(_get_name_raw)
-
     def set_pipe(self, pipe):
+        """Set the serial object to be used for communications"""
         self.pipe = pipe
 
     def get_memory(self, number):
+        """Return a Memory object for the memory at location @number"""
         pass
 
     def erase_memory(self, number):
-        m = Memory()
-        m.number = number
-        m.empty = True
-        self.set_memory(m)
+        """Erase memory at location @number"""
+        mem = Memory()
+        mem.number = number
+        mem.empty = True
+        self.set_memory(mem)
 
     def get_memories(self, lo=None, hi=None):
+        """Get all the memories between @lo and @hi"""
         pass
 
     def set_memory(self, memory):
-        pass
-
-    def set_memories(self, memories):
+        """Set the memory object @memory"""
         pass
 
     def get_bank_model(self):
@@ -822,22 +847,30 @@
         return None
 
     def get_raw_memory(self, number):
+        """Return a raw string describing the memory at @number"""
         pass
 
     def get_special_locations(self):
+        """Return a list of special memory location names"""
         return []
 
     def filter_name(self, name):
+        """Filter @name to just the length and characters supported"""
         rf = self.get_features()
         if rf.valid_characters == rf.valid_characters.upper():
             # Radio only supports uppercase, so help out here
             name = name.upper()
-        return "".join([x for x in name[:rf.valid_name_length] if x in rf.valid_characters])
+        return "".join([x for x in name[:rf.valid_name_length] 
+                        if x in rf.valid_characters])
 
     def get_sub_devices(self):
+        """Return a list of sub-device Radio objects, if
+        RadioFeatures.has_sub_devices is True"""
         return []
 
     def validate_memory(self, mem):
+        """Return a list of warnings and errors that will be encoundered
+        if trying to set @mem on the current radio"""
         msgs = []
         rf = self.get_features()
 
@@ -857,8 +890,10 @@
             msgs.append(msg)
         else:
             if mem.tmode == "Cross":
-                if rf.valid_cross_modes and mem.cross_mode not in rf.valid_cross_modes:
-                    msg = ValidationError("Cross tone mode %s not supported" % mem.cross_mode)
+                if rf.valid_cross_modes and \
+                        mem.cross_mode not in rf.valid_cross_modes:
+                    msg = ValidationError("Cross tone mode %s not supported" % \
+                                              mem.cross_mode)
                     msgs.append(msg)
 
         if rf.has_dtcs_polarity and mem.dtcs_polarity not in rf.valid_dtcs_pols:
@@ -933,16 +968,24 @@
     """A file-backed radio stores its data in a file"""
     FILE_EXTENSION = "img"
 
+    def __init__(self, *args, **kwargs):
+        Radio.__init__(self, *args, **kwargs)
+        self._memobj = None
+        
     def save(self, filename):
+        """Save the radio's memory map to @filename"""
         self.save_mmap(filename)
 
     def load(self, filename):
+        """Load the radio's memory map object from @filename"""
         self.load_mmap(filename)
 
     def process_mmap(self):
+        """Process a newly-loaded or downloaded memory map"""
         pass
 
     def load_mmap(self, filename):
+        """Load the radio's memory map from @filename"""
         mapfile = file(filename, "rb")
         self._mmap = memmap.MemoryMap(mapfile.read())
         mapfile.close()
@@ -957,26 +1000,13 @@
             mapfile = file(filename, "wb")
             mapfile.write(self._mmap.get_packed())
             mapfile.close()
-        except IOError,e:
+        except IOError:
             raise Exception("File Access Error")
 
     def get_mmap(self):
+        """Return the radio's memory map object"""
         return self._mmap
 
-    def get_memsize(self):
-        return self._memsize
-
-    @classmethod
-    def match_model(cls, filedata, filename):
-        """Given contents of a stored file (@filedata), return True if 
-        this radio driver handles the represented model"""
-
-        # Unless the radio driver does something smarter, claim
-        # support if the data is the same size as our memory.
-        # Ideally, each radio would perform an intelligent analysis to
-        # make this determination to avoid model conflicts with
-        # memories of the same size.
-        return len(filedata) == cls._memsize
 
 
 class CloneModeRadio(FileBackedRadio):
@@ -997,7 +1027,23 @@
             self._mmap = pipe
             self.process_mmap()
         else:
-            Radio.__init__(self, pipe)
+            FileBackedRadio.__init__(self, pipe)
+
+    def get_memsize(self):
+        """Return the radio's memory size"""
+        return self._memsize
+
+    @classmethod
+    def match_model(cls, filedata, filename):
+        """Given contents of a stored file (@filedata), return True if 
+        this radio driver handles the represented model"""
+
+        # Unless the radio driver does something smarter, claim
+        # support if the data is the same size as our memory.
+        # Ideally, each radio would perform an intelligent analysis to
+        # make this determination to avoid model conflicts with
+        # memories of the same size.
+        return len(filedata) == cls._memsize
 
     def sync_in(self):
         "Initiate a radio-to-PC clone operation"
@@ -1008,36 +1054,47 @@
         pass
 
 class LiveRadio(Radio):
+    """Base class for all Live-Mode radios"""
     pass
 
 class NetworkSourceRadio(Radio):
+    """Base class for all radios based on a network source"""
     def do_fetch(self):
+        """Fetch the source data from the network"""
         pass
 
 class IcomDstarSupport:
+    """Base interface for radios supporting Icom's D-STAR technology"""
     MYCALL_LIMIT = (1, 1)
     URCALL_LIMIT = (1, 1)
     RPTCALL_LIMIT = (1, 1)
     
     def get_urcall_list(self):
+        """Return a list of URCALL callsigns"""
         return []
 
     def get_repeater_call_list(self):
+        """Return a list of RPTCALL callsigns"""
         return []
 
     def get_mycall_list(self):
+        """Return a list of MYCALL callsigns"""
         return []
 
     def set_urcall_list(self, calls):
+        """Set the URCALL callsign list"""
         pass
 
     def set_repeater_call_list(self, calls):
+        """Set the RPTCALL callsign list"""
         pass
 
     def set_mycall_list(self, calls):
+        """Set the MYCALL callsign list"""
         pass
 
 class Status:
+    """Clone status object for conveying clone progress to the UI"""
     name = "Job"
     msg = "Unknown"
     max = 100
@@ -1055,21 +1112,27 @@
         return "|%-10s| %2.1f%% %s" % (ticks, pct, self.msg)
 
 def is_fractional_step(freq):
+    """Returns True if @freq requires a 12.5kHz or 6.25kHz step"""
     return not is_5_0(freq) and (is_12_5(freq) or is_6_25(freq))
 
 def is_5_0(freq):
+    """Returns True if @freq is reachable by a 5kHz step"""
     return (freq % 5000) == 0
 
 def is_12_5(freq):
+    """Returns True if @freq is reachable by a 12.5kHz step"""
     return (freq % 12500) == 0
 
 def is_6_25(freq):
+    """Returns True if @freq is reachable by a 6.25kHz step"""
     return (freq % 6250) == 0
 
 def is_2_5(freq):
+    """Returns True if @freq is reachable by a 2.5kHz step"""
     return (freq % 2500) == 0
 
 def required_step(freq):
+    """Returns the simplest tuning step that is required to reach @freq"""
     if is_5_0(freq):
         return 5.0
     elif is_12_5(freq):
@@ -1080,10 +1143,13 @@
         return 2.5
     else:
         raise errors.InvalidDataError("Unable to calculate the required " +
-                                      "tuning step for %i.%5i" % (freq / 1000000,
-                                                                  freq % 1000000))
+                                      "tuning step for %i.%5i" % \
+                                          (freq / 1000000,
+                                           freq % 1000000))
 
 def fix_rounded_step(freq):
+    """Some radios imply the last bit of 12.5kHz and 6.25kHz step
+    frequencies. Take the base @freq and return the corrected one"""
     try:
         required_step(freq)
         return freq
@@ -1112,57 +1178,43 @@
                                       format_freq(freq))
 
 def _name(name, len, just_upper):
+    """Justify @name to @len, optionally converting to all uppercase"""
     if just_upper:
         name = name.upper()
     return name.ljust(len)[:len]
 
 def name6(name, just_upper=True):
+    """6-char name"""
     return _name(name, 6, just_upper)
 
 def name8(name, just_upper=False):
+    """8-char name"""
     return _name(name, 8, just_upper)
 
 def name16(name, just_upper=False):
+    """16-char name"""
     return _name(name, 16, just_upper)
 
-class KillableThread(threading.Thread):
-    def __tid(self):
-        if not self.isAlive():
-            raise threading.ThreadError("Not running")
-
-        for tid, thread in threading._active.items():
-            if thread == self:
-                return tid
-
-        raise threading.ThreadError("I don't know my own TID")
-
-    def kill(self, exception):
-        import ctypes
-        import inspect
-
-        if not inspect.isclass(exception):
-            raise Exception("Parameter is not an Exception")
-
-        ctype = ctypes.py_object(exception)
-        ret = ctypes.pythonapi.PyThreadState_SetAsyncExc(self.__tid(), ctype)
-        if ret != 1:
-            ctypes.pythonapi.PyThreadState_SetAsyncExc(self.__tid(), 0)
-            raise Exception("Failed to signal thread!")
-
 def to_GHz(val):
+    """Convert @val in GHz to Hz"""
     return val * 1000000000
 
 def to_MHz(val):
+    """Convert @val in MHz to Hz"""
     return val * 1000000
 
 def to_kHz(val):
+    """Convert @val in kHz to Hz"""
     return val * 1000
 
 def from_GHz(val):
+    """Convert @val in Hz to GHz"""
     return val / 100000000
 
 def from_MHz(val):
+    """Convert @val in Hz to MHz"""
     return val / 100000
 
 def from_kHz(val):
+    """Convert @val in Hz to kHz"""
     return val / 100
diff -r db82df47f205 -r f805c420592f chirp/detect.py
--- a/chirp/detect.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/detect.py	Fri Apr 27 14:35:41 2012 -0700
@@ -15,16 +15,16 @@
 
 import serial
 
-from chirp import chirp_common, errors, idrp, util, icf, directory, ic9x_ll
-from chirp import kenwood_live, tmv71, tmv71_ll, icomciv, thd72
+from chirp import errors, icf, directory, ic9x_ll
+from chirp import kenwood_live, icomciv
 
 def _icom_model_data_to_rclass(md):
-    for rtype, rclass in directory.DRV_TO_RADIO.items():
+    for _rtype, rclass in directory.DRV_TO_RADIO.items():
         if rclass.VENDOR != "Icom":
             continue
-        if not rclass._model:
+        if not rclass.get_model():
             continue
-        if rclass._model[:4] == md[:4]:
+        if rclass.get_model()[:4] == md[:4]:
             return rclass
 
     raise errors.RadioError("Unknown radio type %02x%02x%02x%02x" %\
@@ -33,22 +33,21 @@
                                  ord(md[2]),
                                  ord(md[3])))
 
-def _detect_icom_radio(s):
+def _detect_icom_radio(ser):
     # ICOM VHF/UHF Clone-type radios @ 9600 baud
 
     try:
-        s.setBaudrate(9600)
-        md = icf.get_model_data(s)
+        ser.setBaudrate(9600)
+        md = icf.get_model_data(ser)
         return _icom_model_data_to_rclass(md)
     except errors.RadioError, e:
         print e
-        pass
 
     # ICOM IC-91/92 Live-mode radios @ 4800/38400 baud
 
-    s.setBaudrate(4800)
+    ser.setBaudrate(4800)
     try:
-        ic9x_ll.send_magic(s)
+        ic9x_ll.send_magic(ser)
         return _icom_model_data_to_rclass("ic9x")
     except errors.RadioError:
         pass
@@ -57,25 +56,26 @@
 
     for rate in [9600, 4800, 19200]:
         try:
-            s.setBaudrate(rate)
-            return icomciv.probe_model(s)
+            ser.setBaudrate(rate)
+            return icomciv.probe_model(ser)
         except errors.RadioError:
             pass
 
-    s.close()
+    ser.close()
 
     raise errors.RadioError("Unable to get radio model")
 
 def detect_icom_radio(port):
-    s = serial.Serial(port=port, timeout=0.5)
+    """Detect which Icom model is connected to @port"""
+    ser = serial.Serial(port=port, timeout=0.5)
 
     try:
-        result = _detect_icom_radio(s)
+        result = _detect_icom_radio(ser)
     except Exception:
-        s.close()
+        ser.close()
         raise
 
-    s.close()
+    ser.close()
 
     print "Auto-detected %s %s on %s" % (result.VENDOR,
                                          result.MODEL,
@@ -84,9 +84,10 @@
     return result
 
 def detect_kenwoodlive_radio(port):
-    s = serial.Serial(port=port, baudrate=9600, timeout=0.5)
-    r_id = kenwood_live.get_id(s)
-    s.close()
+    """Detect which Kenwood model is connected to @port"""
+    ser = serial.Serial(port=port, baudrate=9600, timeout=0.5)
+    r_id = kenwood_live.get_id(ser)
+    ser.close()
 
     models = {}
     for rclass in directory.DRV_TO_RADIO.values():
@@ -102,8 +103,3 @@
     "Icom" : detect_icom_radio,
     "Kenwood" : detect_kenwoodlive_radio,
 }
-
-if __name__ == "__main__":
-    import sys
-
-    print "Found %s" % detect_radio(sys.argv[1])
diff -r db82df47f205 -r f805c420592f chirp/directory.py
--- a/chirp/directory.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/directory.py	Fri Apr 27 14:35:41 2012 -0700
@@ -21,6 +21,7 @@
 from chirp import chirp_common, util, rfinder, radioreference, errors
 
 def radio_class_id(cls):
+    """Return a unique identification string for @cls"""
     ident = "%s_%s" % (cls.VENDOR, cls.MODEL)
     if cls.VARIANT:
         ident += "_%s" % cls.VARIANT
@@ -31,6 +32,7 @@
     return ident
 
 def register(cls):
+    """Register radio @cls with the directory"""
     global DRV_TO_RADIO
     ident = radio_class_id(cls)
     if ident in DRV_TO_RADIO.keys():
@@ -45,20 +47,24 @@
 RADIO_TO_DRV = {}
 
 def get_radio(driver):
+    """Get radio driver class by identification string"""
     if DRV_TO_RADIO.has_key(driver):
         return DRV_TO_RADIO[driver]
     else:
         raise Exception("Unknown radio type `%s'" % driver)
 
-def get_driver(radio):
-    if RADIO_TO_DRV.has_key(radio):
-        return RADIO_TO_DRV[radio]
-    elif RADIO_TO_DRV.has_key(radio.__bases__[0]):
-        return RADIO_TO_DRV[radio.__bases__[0]]
+def get_driver(rclass):
+    """Get the identification string for a given class"""
+    if RADIO_TO_DRV.has_key(rclass):
+        return RADIO_TO_DRV[rclass]
+    elif RADIO_TO_DRV.has_key(rclass.__bases__[0]):
+        return RADIO_TO_DRV[rclass.__bases__[0]]
     else:
-        raise Exception("Unknown radio type `%s'" % radio)
+        raise Exception("Unknown radio type `%s'" % rclass)
 
 def icf_to_image(icf_file, img_file):
+    # FIXME: Why is this here?
+    """Convert an ICF file to a .img file"""
     mdata, mmap = icf.read_file(icf_file)
     img_data = None
 
@@ -80,16 +86,17 @@
         raise Exception("Unsupported model")
 
 def get_radio_by_image(image_file):
+    """Attempt to get the radio class that owns @image_file"""
     if image_file.startswith("radioreference://"):
-        method, _, zipcode, username, password = image_file.split("/", 4)
+        _, _, zipcode, username, password = image_file.split("/", 4)
         rr = radioreference.RadioReferenceRadio(None)
         rr.set_params(zipcode, username, password)
         return rr
     
     if image_file.startswith("rfinder://"):
-        method, _, email, passwd, lat, lon, miles = image_file.split("/")
+        _, _, email, passwd, lat, lon, miles = image_file.split("/")
         rf = rfinder.RFinderRadio(None)
-        rf.set_params(float(lat), float(lon), int(miles), email, passwd)
+        rf.set_params((float(lat), float(lon)), int(miles), email, passwd)
         return rf
     
     if os.path.exists(image_file) and icf.is_icf_file(image_file):
@@ -105,27 +112,9 @@
     else:
         filedata = ""
 
-    for radio in DRV_TO_RADIO.values():
-        if not issubclass(radio, chirp_common.FileBackedRadio):
+    for rclass in DRV_TO_RADIO.values():
+        if not issubclass(rclass, chirp_common.FileBackedRadio):
             continue
-        if radio.match_model(filedata, image_file):
-            return radio(image_file)
+        if rclass.match_model(filedata, image_file):
+            return rclass(image_file)
     raise errors.ImageDetectFailed("Unknown file format")
-
-def get_radio_name(driver):
-    cls = DRV_TO_RADIO[driver]
-    return cls._get_name(cls)
-
-if __name__ == "__main__":
-    vendors = {
-        "Icom" : {},
-        "Yaesu" : {},
-        "Kenwood" : {},
-        }
-
-    for radio in DRV_TO_RADIO.values():
-        vendors[radio.VENDOR][radio.MODEL]
-        print "%s %s:" % (radio.VENDOR, radio.MODEL)
-        if radio.VARIANT:
-            print "  Variant: %s" % radio.VARIANT
-        print "  Baudrate: %i" % radio.BAUD_RATE
diff -r db82df47f205 -r f805c420592f chirp/errors.py
--- a/chirp/errors.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/errors.py	Fri Apr 27 14:35:41 2012 -0700
@@ -14,19 +14,25 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 class InvalidDataError(Exception):
+    """The radio driver encountered some invalid data"""
     pass
 
 class InvalidValueError(Exception):
+    """An invalid value for a given parameter was used"""
     pass
 
 class InvalidMemoryLocation(Exception):
+    """The requested memory location does not exist"""
     pass
 
 class RadioError(Exception):
+    """An error occurred while talking to the radio"""
     pass
 
 class UnsupportedToneError(Exception):
+    """The radio does not support the specified tone value"""
     pass
 
 class ImageDetectFailed(Exception):
+    """The driver for the supplied image could not be determined"""
     pass
diff -r db82df47f205 -r f805c420592f chirp/ft2800.py
--- a/chirp/ft2800.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ft2800.py	Fri Apr 27 14:35:41 2012 -0700
@@ -14,7 +14,6 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import time
-import struct
 import os
 
 from chirp import util, memmap, chirp_common, bitwise, directory, errors
@@ -23,7 +22,7 @@
 DEBUG = os.getenv("CHIRP_DEBUG") and True or False
 
 CHUNK_SIZE = 16
-def send(s, data):
+def _send(s, data):
     for i in range(0, len(data), CHUNK_SIZE):
         chunk = data[i:i+CHUNK_SIZE]
         s.write(chunk)
@@ -35,9 +34,9 @@
 TRAILER = "\x0c\x02\x41\x33\x35\x00\x00\xb7"
 ACK = "\x0C\x06\x00"
 
-def download(radio):
+def _download(radio):
     data = ""
-    for i in range(0, 10):
+    for _i in range(0, 10):
         data = radio.pipe.read(8)
         if data == IDBLOCK:
             break
@@ -48,7 +47,7 @@
     if len(data) != 8:
         raise Exception("Failed to read header")
 
-    send(radio.pipe, ACK)
+    _send(radio.pipe, ACK)
 
     data = ""
 
@@ -72,7 +71,7 @@
 
             data += chunk[5:-1]
 
-        send(radio.pipe, ACK)
+        _send(radio.pipe, ACK)
         if radio.status_fn:
             status = chirp_common.Status()
             status.max = radio._block_sizes[1]
@@ -85,14 +84,14 @@
 
     return memmap.MemoryMap(data)
 
-def upload(radio):
-    for i in range(0, 10):
+def _upload(radio):
+    for _i in range(0, 10):
         data = radio.pipe.read(256)
         if not data:
             break
         print "What is this garbage?\n%s" % util.hexprint(data)
 
-    send(radio.pipe, IDBLOCK)
+    _send(radio.pipe, IDBLOCK)
     time.sleep(1)
     ack = radio.pipe.read(300)
     if DEBUG:
@@ -101,9 +100,9 @@
         raise Exception("Radio did not ack ID")
 
     block = 0
-    while block < (radio._memsize / 32):
+    while block < (radio.get_memsize() / 32):
         data = "\x0C\x03\x00\x00" + chr(block)
-        data += radio._mmap[block*32:(block+1)*32]
+        data += radio.get_mmap()[block*32:(block+1)*32]
         cs = 0
         for byte in data:
             cs += ord(byte)
@@ -112,7 +111,7 @@
         if DEBUG:
             print "Writing block %i:\n%s" % (block, util.hexprint(data))
 
-        send(radio.pipe, data)
+        _send(radio.pipe, data)
         time.sleep(0.1)
         ack = radio.pipe.read(3)
         if ack != ACK:
@@ -126,9 +125,9 @@
             radio.status_fn(status)
         block += 1
 
-    send(radio.pipe, TRAILER)
+    _send(radio.pipe, TRAILER)
 
-mem_format = """
+MEM_FORMAT = """
 struct {
   bbcd freq[4];
   u8 unknown1[4];
@@ -164,6 +163,7 @@
 
 @directory.register
 class FT2800Radio(YaesuCloneModeRadio):
+    """Yaesu FT-2800"""
     VENDOR = "Yaesu"
     MODEL = "FT-2800M"
 
@@ -196,7 +196,7 @@
         self.pipe.setParity("E")
         start = time.time()
         try:
-            self._mmap = download(self)
+            self._mmap = _download(self)
         except errors.RadioError:
             raise
         except Exception, e:
@@ -209,7 +209,7 @@
         self.pipe.setParity("E")
         start = time.time()
         try:
-            upload(self)
+            _upload(self)
         except errors.RadioError:
             raise
         except Exception, e:
@@ -217,7 +217,7 @@
         print "Uploaded in %.2f sec" % (time.time() - start)
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_raw_memory(self, number):
         return repr(self._memobj.memory[number])
diff -r db82df47f205 -r f805c420592f chirp/ft60.py
--- a/chirp/ft60.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ft60.py	Fri Apr 27 14:35:41 2012 -0700
@@ -19,13 +19,13 @@
 
 ACK = "\x06"
 
-def send(pipe, data):
+def _send(pipe, data):
     pipe.write(data)
     echo = pipe.read(len(data))
     if echo != data:
         raise errors.RadioError("Error reading echo (Bad cable?)")
 
-def download(radio):
+def _download(radio):
     data = ""
     for i in range(0, 10):
         chunk = radio.pipe.read(8)
@@ -40,12 +40,12 @@
     if not data:
         raise Exception("Radio is not responding")
 
-    send(radio.pipe, ACK)
+    _send(radio.pipe, ACK)
 
     for i in range(0, 448):
         chunk = radio.pipe.read(64)
         data += chunk
-        send(radio.pipe, ACK)
+        _send(radio.pipe, ACK)
         if len(chunk) == 1 and i == 447:
             break
         elif len(chunk) != 64:
@@ -53,14 +53,14 @@
         if radio.status_fn:
             status = chirp_common.Status()
             status.cur = i * 64
-            status.max = radio._memsize
+            status.max = radio.get_memsize()
             status.msg = "Cloning from radio"
             radio.status_fn(status)
 
     return memmap.MemoryMap(data)
 
-def upload(radio):
-    send(radio.pipe, radio._mmap[0:8])
+def _upload(radio):
+    _send(radio.pipe, radio.get_mmap()[0:8])
 
     ack = radio.pipe.read(1)
     if ack != ACK:
@@ -68,7 +68,7 @@
 
     for i in range(0, 448):
         offset = 8 + (i * 64)
-        send(radio.pipe, radio._mmap[offset:offset+64])
+        _send(radio.pipe, radio.get_mmap()[offset:offset+64])
         ack = radio.pipe.read(1)
         if ack != ACK:
             raise Exception("Radio did not ack block %i" % i)
@@ -76,11 +76,11 @@
         if radio.status_fn:
             status = chirp_common.Status()
             status.cur = offset+64
-            status.max = radio._memsize
+            status.max = radio.get_memsize()
             status.msg = "Cloning to radio"
             radio.status_fn(status)            
 
-mem_format = """
+MEM_FORMAT = """
 #seekto 0x0238;
 struct {
   u8 used:1,
@@ -136,6 +136,7 @@
 
 @directory.register
 class FT60Radio(yaesu_clone.YaesuCloneModeRadio):
+    """Yaesu FT-60"""
     BAUD_RATE = 9600
     VENDOR = "Yaesu"
     MODEL = "FT-60"
@@ -158,6 +159,7 @@
         rf.has_ctone = False
         rf.has_bank = False
         rf.has_dtcs_polarity = False
+
         return rf
 
     def _checksums(self):
@@ -165,7 +167,7 @@
 
     def sync_in(self):
         try:
-            self._mmap = download(self)
+            self._mmap = _download(self)
         except errors.RadioError:
             raise
         except Exception, e:
@@ -175,14 +177,14 @@
     def sync_out(self):
         self.update_checksums()
         try:
-            upload(self)
+            _upload(self)
         except errors.RadioError:
             raise
         except Exception, e:
             raise errors.RadioError("Failed to communicate with radio: %s" % e)
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_raw_memory(self, number):
         return repr(self._memobj.memory[number]) + \
diff -r db82df47f205 -r f805c420592f chirp/ft7800.py
--- a/chirp/ft7800.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ft7800.py	Fri Apr 27 14:35:41 2012 -0700
@@ -15,11 +15,11 @@
 
 import time
 from chirp import chirp_common, yaesu_clone, memmap, directory
-from chirp import bitwise, util, errors
+from chirp import bitwise, errors
 
 ACK = chr(0x06)
 
-mem_format = """
+MEM_FORMAT = """
 #seekto 0x04C8;
 struct {
   u8 used:1,
@@ -89,16 +89,15 @@
                     chirp_common.PowerLevel("Mid2", watts=10),
                     chirp_common.PowerLevel("Low", watts=5)]
 
-def send(s, data):
-
+def _send(ser, data):
     for i in data:
-        s.write(i)
+        ser.write(i)
         time.sleep(0.002)
-    echo = s.read(len(data))
+    echo = ser.read(len(data))
     if echo != data:
         raise errors.RadioError("Error reading echo (Bad cable?)")
 
-def download(radio):
+def _download(radio):
     data = ""
 
     chunk = ""
@@ -111,49 +110,49 @@
         raise Exception("Failed to read header (%i)" % len(chunk))
     data += chunk
 
-    send(radio.pipe, ACK)
+    _send(radio.pipe, ACK)
 
     for i in range(0, radio._block_lengths[1], 64):
         chunk = radio.pipe.read(64)
         data += chunk
         if len(chunk) != 64:
             break
-            raise Exception("No block at %i" % i)
         time.sleep(0.01)
-        send(radio.pipe, ACK)
+        _send(radio.pipe, ACK)
         if radio.status_fn:
             status = chirp_common.Status()
-            status.max = radio._memsize
+            status.max = radio.get_memsize()
             status.cur = i+len(chunk)
             status.msg = "Cloning from radio"
             radio.status_fn(status)
 
     data += radio.pipe.read(1)
-    send(radio.pipe, ACK)
+    _send(radio.pipe, ACK)
 
     return memmap.MemoryMap(data)
 
-def upload(radio):
+def _upload(radio):
     cur = 0
     for block in radio._block_lengths:
-        for i in range(0, block, 64):
+        for _i in range(0, block, 64):
             length = min(64, block)
             #print "i=%i length=%i range: %i-%i" % (i, length,
             #                                       cur, cur+length)
-            send(radio.pipe, radio._mmap[cur:cur+length])
+            _send(radio.pipe, radio.get_mmap()[cur:cur+length])
             if radio.pipe.read(1) != ACK:
                 raise errors.RadioError("Radio did not ack block at %i" % cur)
             cur += length
             time.sleep(0.05)
 
             if radio.status_fn:
-                s = chirp_common.Status()
-                s.cur = cur
-                s.max = radio._memsize
-                s.msg = "Cloning to radio"
-                radio.status_fn(s)
+                status = chirp_common.Status()
+                status.cur = cur
+                status.max = radio.get_memsize()
+                status.msg = "Cloning to radio"
+                radio.status_fn(status)
 
 def get_freq(rawfreq):
+    """Decode a frequency that may include a fractional step flag"""
     # Ugh.  The 0x80 and 0x40 indicate values to add to get the
     # real frequency.  Gross.
     if rawfreq > 8000000000:
@@ -165,6 +164,7 @@
     return rawfreq
 
 def set_freq(freq, obj, field):
+    """Encode a frequency with any necessary fractional step flags"""
     obj[field] = freq / 10000
     if (freq % 1000) == 500:
         obj[field][0].set_bits(0x40)
@@ -175,6 +175,7 @@
     return freq
 
 class FTx800Radio(yaesu_clone.YaesuCloneModeRadio):
+    """Base class for FT-7800,7900,8800,8900 radios"""
     BAUD_RATE = 9600
     VENDOR = "Yaesu"
 
@@ -200,30 +201,30 @@
         return [ yaesu_clone.YaesuChecksum(0x0000, 0x7B47) ]
 
     def sync_in(self):
-        t = time.time()
+        start = time.time()
         try:
-            self._mmap = download(self)
+            self._mmap = _download(self)
         except errors.RadioError:
             raise
         except Exception, e:
             raise errors.RadioError("Failed to communicate with radio: %s" % e)
-        print "Download finished in %i seconds" % (time.time() - t)
+        print "Download finished in %i seconds" % (time.time() - start)
         self.check_checksums()
         self.process_mmap()
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def sync_out(self):
         self.update_checksums()
-        t = time.time()
+        start = time.time()
         try:
-            upload(self)
+            _upload(self)
         except errors.RadioError:
             raise
         except Exception, e:
             raise errors.RadioError("Failed to communicate with radio: %s" % e)
-        print "Upload finished in %i seconds" % (time.time() - t)
+        print "Upload finished in %i seconds" % (time.time() - start)
 
     def get_raw_memory(self, number):
         return repr(self._memobj.memory[number-1])
@@ -330,6 +331,7 @@
         self._set_mem_skip(mem, _mem)
 
 class FT7800BankModel(chirp_common.BankModel):
+    """Yaesu FT-7800/7900 bank model"""
     def get_num_banks(self):
         return 20
 
@@ -353,8 +355,8 @@
         _bitmap = self._radio._memobj.bank_channels[bank.index]
         ishft = 31 - (index % 32)
         if not (_bitmap.bitmap[index / 32] & (1 << ishft)):
-            raise Exception(_("Memory {num} is "
-                              "not in bank {bank}").format(num=memory.number,
+            raise Exception("Memory {num} is " +
+                            "not in bank {bank}".format(num=memory.number,
                                                            bank=bank))
         _bitmap.bitmap[index / 32] &= ~(1 << ishft)
 
@@ -377,6 +379,7 @@
 
 @directory.register
 class FT7800Radio(FTx800Radio):
+    """Yaesu FT-7800"""
     MODEL = "FT-7800"
 
     _model = "AH016"
@@ -396,9 +399,10 @@
         FTx800Radio.set_memory(self, memory)
 
 class FT7900Radio(FT7800Radio):
+    """Yaesu FT-7900"""
     MODEL = "FT-7900"
 
-mem_format_8800 = """
+MEM_FORMAT_8800 = """
 #seekto %s;
 struct {
   u8 used:1,
@@ -434,6 +438,7 @@
 
 @directory.register
 class FT8800Radio(FTx800Radio):
+    """Base class for Yaesu FT-8800"""
     MODEL = "FT-8800"
 
     _model = "AH018"
@@ -460,7 +465,7 @@
         if not self._memstart:
             return
 
-        self._memobj = bitwise.parse(mem_format_8800 % self._memstart,
+        self._memobj = bitwise.parse(MEM_FORMAT_8800 % self._memstart,
                                      self._mmap)
 
     def _get_mem_offset(self, mem, _mem):
@@ -502,14 +507,16 @@
         _mem.nameused = bool(mem.name.rstrip())
 
 class FT8800RadioLeft(FT8800Radio):
+    """Yaesu FT-8800 Left VFO subdevice"""
     VARIANT = "Left"
     _memstart = "0x0948"
 
 class FT8800RadioRight(FT8800Radio):
+    """Yaesu FT-8800 Right VFO subdevice"""
     VARIANT = "Right"
     _memstart = "0x2948"
 
-mem_format_8900 = """
+MEM_FORMAT_8900 = """
 #seekto 0x0708;
 struct {
   u8 used:1,
@@ -546,6 +553,7 @@
 
 @directory.register
 class FT8900Radio(FT8800Radio):
+    """Yaesu FT-8900"""
     MODEL = "FT-8900"
 
     _model = "AH008"
@@ -553,7 +561,7 @@
     _block_lengths = [8, 14784, 1]
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format_8900, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT_8900, self._mmap)
 
     def get_features(self):
         rf = FT8800Radio.get_features(self)
@@ -595,7 +603,7 @@
         # the memory should show up on the sub (right) band
         _mem = self._memobj.memory[mem.number - 1]
         if mem.freq < 108000000 or mem.freq > 480000000:
-            _mem.sub_used = 0;
+            _mem.sub_used = 0
         else:
             _mem.sub_used = 1
 
diff -r db82df47f205 -r f805c420592f chirp/ft817.py
--- a/chirp/ft817.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ft817.py	Fri Apr 27 14:35:41 2012 -0700
@@ -20,26 +20,29 @@
 
 CMD_ACK = 0x06
 
-def ft817_read(pipe, block, blocknum):
-    for i in range(0,60):
+def _ft8x7_read(pipe, block, blocknum):
+    for _i in range(0, 60):
         data = pipe.read(block+2)
-	if data:
+        if data:
             break
-	time.sleep(0.5)
+        time.sleep(0.5)
     if len(data) == block+2 and data[0] == chr(blocknum):
-            checksum = yaesu_clone.YaesuChecksum(1, block)
-            if checksum.get_existing(data) != \
-                    checksum.get_calculated(data):
-                raise Exception("Checksum Failed [%02X<>%02X] block %02X" % (checksum.get_existing(data), checksum.get_calculated(data), blocknum))
-	    data = data[1:block+1] # Chew away the block number and the checksum
+        checksum = yaesu_clone.YaesuChecksum(1, block)
+        if checksum.get_existing(data) != \
+                checksum.get_calculated(data):
+            raise Exception("Checksum Failed [%02X<>%02X] block %02X" % \
+                                (checksum.get_existing(data),
+                                 checksum.get_calculated(data), blocknum))
+        data = data[1:block+1] # Chew away the block number and the checksum
     else:
-        raise Exception("Unable to read block %02X expected %i got %i" % (blocknum, block+2, len(data)))
+        raise Exception("Unable to read block %02X expected %i got %i" % \
+                            (blocknum, block+2, len(data)))
 
     if os.getenv("CHIRP_DEBUG"):
         print "Read %i" % len(data)
     return data        
 
-def clone_in(radio):
+def _ft8x7_clone_in(radio):
     pipe = radio.pipe
 
     # Be very patient with the radio
@@ -54,21 +57,21 @@
     status.max = len(radio._block_lengths) + 39
     for block in radio._block_lengths:
         if blocks == 8:
-            repeat = 40   # repeated read of 40 block same size (memory area btw)
+            repeat = 40   # repeated read of 40 block same size (memory area)
         else:
             repeat = 1
-        for i in range(0, repeat):	
-	    data += ft817_read(pipe, block, blocks)
-	    pipe.write(chr(CMD_ACK))
-	    blocks += 1
-	    status.cur = blocks
-	    radio.status_fn(status)
+        for _i in range(0, repeat):	
+            data += _ft8x7_read(pipe, block, blocks)
+            pipe.write(chr(CMD_ACK))
+            blocks += 1
+            status.cur = blocks
+            radio.status_fn(status)
 
     print "Clone completed in %i seconds" % (time.time() - start)
 
     return memmap.MemoryMap(data)
 
-def clone_out(radio):
+def _ft8x7_clone_out(radio):
     delay = 0.5
     pipe = radio.pipe
 
@@ -81,21 +84,24 @@
     status.max = len(radio._block_lengths) + 39
     for block in radio._block_lengths:
         if blocks == 8:
-            repeat = 40   # repeated read of 40 block same size (memory area btw)
+            repeat = 40   # repeated read of 40 block same size (memory area)
         else:
             repeat = 1
-	for i in range(0, repeat):
+        for _i in range(0, repeat):
             time.sleep(0.01)
             checksum = yaesu_clone.YaesuChecksum(pos, pos+block-1)
             if os.getenv("CHIRP_DEBUG"):
-                print "Block %i - will send from %i to %i byte " % (blocks, pos, pos+block)
+                print "Block %i - will send from %i to %i byte " % (blocks,
+                                                                    pos,
+                                                                    pos+block)
                 print util.hexprint(chr(blocks))
-                print util.hexprint(radio._mmap[pos:pos+block])
-                print util.hexprint(chr(checksum.get_calculated(radio._mmap)))
+                print util.hexprint(radio.get_mmap()[pos:pos+block])
+                print util.hexprint(chr(checksum.get_calculated(\
+                            radio.get_mmap())))
             pipe.write(chr(blocks))
-            pipe.write(radio._mmap[pos:pos+block])
-            pipe.write(chr(checksum.get_calculated(radio._mmap)))
-	    buf = pipe.read(1)
+            pipe.write(radio.get_mmap()[pos:pos+block])
+            pipe.write(chr(checksum.get_calculated(radio.get_mmap())))
+            buf = pipe.read(1)
             if not buf or buf[0] != chr(CMD_ACK):
                 time.sleep(delay)
                 buf = pipe.read(1)
@@ -105,12 +111,12 @@
                 raise Exception("Radio did not ack block %i" % blocks)
             pos += block
             blocks += 1
-	    status.cur = blocks
-	    radio.status_fn(status)
+            status.cur = blocks
+            radio.status_fn(status)
 
     print "Clone completed in %i seconds" % (time.time() - start)
 
-mem_format = """
+MEM_FORMAT = """
 struct mem_struct {
   u8   tag_on_off:1,
        tag_default:1,
@@ -167,21 +173,29 @@
 
 @directory.register
 class FT817Radio(yaesu_clone.YaesuCloneModeRadio):
+    """Yaesu FT-817"""
     BAUD_RATE = 9600
     MODEL = "FT-817"
     _model = ""
 
     DUPLEX = ["", "-", "+", "split"]
-    MODES  = ["LSB", "USB", "CW", "CWR", "AM", "FM", "DIG", "PKT", "NCW", "NCWR", "NFM"]   # narrow modes has to be at end
+    # narrow modes has to be at end
+    MODES  = ["LSB", "USB", "CW", "CWR", "AM", "FM", "DIG", "PKT", "NCW",
+              "NCWR", "NFM"]
     TMODES = ["", "Tone", "TSQL", "DTCS"]
     STEPSFM = [5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0]
     STEPSAM = [2.5, 5.0, 9.0, 10.0, 12.5, 25.0]
     STEPSSSB = [1.0, 2.5, 5.0]
-    VALID_BANDS = [(100000,33000000), (33000000,56000000), (76000000,108000000), (108000000,137000000), (137000000,154000000), (420000000,470000000)] # warning ranges has to be in this exact order
+
+    # warning ranges has to be in this exact order
+    VALID_BANDS = [(100000, 33000000), (33000000, 56000000),
+                   (76000000, 108000000), (108000000, 137000000),
+                   (137000000, 154000000), (420000000, 470000000)] 
 
     CHARSET = [chr(x) for x in range(0, 256)]
 
-    POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=5.00),       # not used in memory
+    # Hi not used in memory
+    POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=5.00),
                     chirp_common.PowerLevel("L3", watts=2.50),
                     chirp_common.PowerLevel("L2", watts=1.00),
                     chirp_common.PowerLevel("L1", watts=0.5)]
@@ -190,7 +204,8 @@
     # block 9 (130 Bytes long) is to be repeted 40 times
     _block_lengths = [ 2, 40, 208, 182, 208, 182, 198, 53, 130, 118, 118]
 
-    SPECIAL_MEMORIES = {        # WARNING Index are hard wired in memory management code !!!
+    # WARNING Index are hard wired in memory management code !!!
+    SPECIAL_MEMORIES = {
         "VFOa-1.8M" : -35,
         "VFOa-3.5M" : -34,
         "VFOa-7M" : -33,
@@ -232,11 +247,12 @@
     FIRST_VFOA_INDEX = -21
     LAST_VFOA_INDEX = -35
 
-    SPECIAL_MEMORIES_REV = dict(zip(SPECIAL_MEMORIES.values(), SPECIAL_MEMORIES.keys()))
+    SPECIAL_MEMORIES_REV = dict(zip(SPECIAL_MEMORIES.values(),
+                                    SPECIAL_MEMORIES.keys()))
 
     def sync_in(self):
         try:
-            self._mmap = clone_in(self)
+            self._mmap = _ft8x7_clone_in(self)
         except errors.RadioError:
             raise
         except Exception, e:
@@ -245,14 +261,14 @@
 
     def sync_out(self):
         try:
-            clone_out(self)
+            _ft8x7_clone_out(self)
         except errors.RadioError:
             raise
         except Exception, e:
             raise errors.RadioError("Failed to communicate with radio: %s" % e)
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_features(self):
         rf = chirp_common.RadioFeatures()
@@ -276,27 +292,28 @@
     def get_raw_memory(self, number):
         return repr(self._memobj.memory[number-1])
 
-    def get_duplex(self, mem, _mem):
+    def _get_duplex(self, mem, _mem):
         if _mem.is_duplex == 1:
             mem.duplex = self.DUPLEX[_mem.duplex]
         else:
             mem.duplex = ""
 
-    def get_tmode(self, mem, _mem):
+    def _get_tmode(self, mem, _mem):
         mem.tmode = self.TMODES[_mem.tmode]
 
-    def set_duplex(self, mem, _mem):
+    def _set_duplex(self, mem, _mem):
         _mem.duplex = self.DUPLEX.index(mem.duplex)
         _mem.is_duplex = mem.duplex != ""
 
-    def set_tmode(self, mem, _mem):
+    def _set_tmode(self, mem, _mem):
         _mem.tmode = self.TMODES.index(mem.tmode)
 
     def get_memory(self, number):
         if isinstance(number, str):
             return self._get_special(number)
         elif number < 0:
-            # I can't stop delete operation from loosing extd_number but I know how to get it back
+            # I can't stop delete operation from loosing extd_number but
+            # I know how to get it back
             return self._get_special(self.SPECIAL_MEMORIES_REV[number])
         else:
             return self._get_normal(number)
@@ -315,27 +332,32 @@
         mem.number = self.SPECIAL_MEMORIES[number]
         mem.extd_number = number
 
-        if mem.number in range(self.FIRST_VFOA_INDEX, self.LAST_VFOA_INDEX -1, -1):
+        if mem.number in range(self.FIRST_VFOA_INDEX,
+                               self.LAST_VFOA_INDEX - 1,
+                               -1):
             _mem = self._memobj.vfoa[-self.LAST_VFOA_INDEX + mem.number]
-            immutable = ["number", "skip", "rtone", "ctone", "extd_number", "name",
-                         "dtcs_polarity", "power", "comment"]
-        elif mem.number in range(self.FIRST_VFOB_INDEX, self.LAST_VFOB_INDEX -1, -1):
+            immutable = ["number", "skip", "rtone", "ctone", "extd_number",
+                         "name", "dtcs_polarity", "power", "comment"]
+        elif mem.number in range(self.FIRST_VFOB_INDEX,
+                                 self.LAST_VFOB_INDEX - 1,
+                                 -1):
             _mem = self._memobj.vfob[-self.LAST_VFOB_INDEX + mem.number]
-            immutable = ["number", "skip", "rtone", "ctone", "extd_number", "name",
-                         "dtcs_polarity", "power", "comment"]
+            immutable = ["number", "skip", "rtone", "ctone", "extd_number",
+                         "name", "dtcs_polarity", "power", "comment"]
         elif mem.number in range(-2, -6, -1):
             _mem = self._memobj.home[5 + mem.number]
             immutable = ["number", "skip", "rtone", "ctone", "extd_number",
                          "dtcs_polarity", "power", "comment"]
         elif mem.number == -1:
             _mem = self._memobj.qmb
-            immutable = ["number", "skip", "rtone", "ctone", "extd_number", "name",
-                         "dtcs_polarity", "power", "comment"]
-	else:
-            raise Exception("Sorry, special memory index %i unknown you hit a bug!!" % mem.number)
+            immutable = ["number", "skip", "rtone", "ctone", "extd_number",
+                         "name", "dtcs_polarity", "power", "comment"]
+        else:
+            raise Exception("Sorry, special memory index %i " % mem.number +
+                            "unknown you hit a bug!!")
 
         mem = self._get_memory(mem, _mem)
-	mem.immutable = immutable
+        mem.immutable = immutable
 
         return mem
 
@@ -352,16 +374,21 @@
                                         "is not supported on this channel")
 
         # TODO add frequency range check for vfo and home memories
-        if mem.number in range(self.FIRST_VFOA_INDEX, self.LAST_VFOA_INDEX -1, -1):
+        if mem.number in range(self.FIRST_VFOA_INDEX,
+                               self.LAST_VFOA_INDEX -1,
+                               -1):
             _mem = self._memobj.vfoa[-self.LAST_VFOA_INDEX + mem.number]
-        elif mem.number in range(self.FIRST_VFOB_INDEX, self.LAST_VFOB_INDEX -1, -1):
+        elif mem.number in range(self.FIRST_VFOB_INDEX,
+                                 self.LAST_VFOB_INDEX -1,
+                                 -1):
             _mem = self._memobj.vfob[-self.LAST_VFOB_INDEX + mem.number]
         elif mem.number in range(-2, -6, -1):
             _mem = self._memobj.home[5 + mem.number]
         elif mem.number == -1:
             _mem = self._memobj.qmb
-	else:
-            raise Exception("Sorry, special memory index %i unknown you hit a bug!!" % mem.number)
+        else:
+            raise Exception("Sorry, special memory index %i " % mem.number +
+                            "unknown you hit a bug!!")
 
         self._set_memory(mem, _mem)
 
@@ -382,8 +409,10 @@
 
     def _set_normal(self, mem):
         _mem = self._memobj.memory[mem.number-1]
-        wasused = (self._memobj.visible[(mem.number-1)/8] >> (mem.number-1)%8) & 0x01
-        wasvalid = (self._memobj.filled[(mem.number-1)/8] >> (mem.number-1)%8) & 0x01
+        wasused = (self._memobj.visible[(mem.number - 1) / 8] >> \
+                       (mem.number - 1) % 8) & 0x01
+        wasvalid = (self._memobj.filled[(mem.number - 1) / 8] >> \
+                        (mem.number - 1) % 8) & 0x01
 
         if mem.empty:
             if mem.number == 1:
@@ -391,18 +420,20 @@
 		# if you ulpoad an empty image you can brick your radio
                 raise Exception("Sorry, can't delete first memory") 
             if wasvalid and not wasused:
-                self._memobj.filled[(mem.number-1)/8] &= ~ (1 << (mem.number-1)%8)
-            self._memobj.visible[(mem.number-1)/8] &= ~ (1 << (mem.number-1)%8)
+                self._memobj.filled[(mem.number-1) / 8] &= \
+                    ~(1 << (mem.number - 1) % 8)
+            self._memobj.visible[(mem.number-1) / 8] &= \
+                ~(1 << (mem.number - 1) % 8)
             return
         
-        self._memobj.visible[(mem.number-1)/8] |= 1 << (mem.number-1)%8
-        self._memobj.filled[(mem.number-1)/8] |= 1 << (mem.number-1)%8
+        self._memobj.visible[(mem.number - 1) / 8] |= 1 << (mem.number - 1) % 8
+        self._memobj.filled[(mem.number - 1) / 8] |= 1 << (mem.number - 1) % 8
         self._set_memory(mem, _mem)
 
     def _get_memory(self, mem, _mem):
         mem.freq = int(_mem.freq) * 10
         mem.offset = int(_mem.offset) * 10
-        self.get_duplex(mem, _mem)
+        self._get_duplex(mem, _mem)
         mem.mode = self.MODES[_mem.mode]
         if mem.mode == "FM":
             if _mem.is_fm_narrow == 1:
@@ -420,11 +451,11 @@
             except IndexError:
                 pass
         mem.skip = _mem.skip and "S" or ""
-        self.get_tmode(mem, _mem)
+        self._get_tmode(mem, _mem)
         mem.rtone = mem.ctone = chirp_common.TONES[_mem.tone]
         mem.dtcs = chirp_common.DTCS_CODES[_mem.dcs]
 
-	if _mem.tag_on_off == 1:
+        if _mem.tag_on_off == 1:
             for i in _mem.name:
                 if i == "\xFF":
                     break
@@ -442,31 +473,34 @@
         else:
             _mem.tag_on_off = 0
         _mem.tag_default = 0       # never use default label "CH-nnn"
-        self.set_duplex(mem, _mem)
+        self._set_duplex(mem, _mem)
         if mem.mode[0] == "N": # is it narrow?
             _mem.mode = self.MODES.index(mem.mode[1:])
-            _mem.is_fm_narrow = _mem.is_cwdig_narrow = 1       # here I suppose it's safe to set both
+            # here I suppose it's safe to set both
+            _mem.is_fm_narrow = _mem.is_cwdig_narrow = 1       
         else:
             _mem.mode = self.MODES.index(mem.mode)
-            _mem.is_fm_narrow = _mem.is_cwdig_narrow = 0       # here I suppose it's safe to set both
-        i = 0                                   # This search can probably be written better but
-        for lo, hi in self.VALID_BANDS:              # I just don't know python enought
+            # here I suppose it's safe to set both
+            _mem.is_fm_narrow = _mem.is_cwdig_narrow = 0       
+        i = 0
+        for lo, hi in self.VALID_BANDS:
             if mem.freq > lo and mem.freq < hi:
                 break 
-            i+=1
+            i += 1
         _mem.freq_range = i
-        if mem.duplex == "split":	# all this should be safe also when not in split but ... 
+	# all this should be safe also when not in split but ... 
+        if mem.duplex == "split":
             _mem.tx_mode = _mem.mode
-            i = 0                                   # This search can probably be written better but
-            for lo, hi in self.VALID_BANDS:              # I just don't know python enought
+            i = 0
+            for lo, hi in self.VALID_BANDS:
                 if mem.offset >= lo and mem.offset < hi:
                     break 
-                i+=1
+                i += 1
             _mem.tx_freq_range = i
         _mem.skip = mem.skip == "S"
         _mem.ipo = 0	# not supported in chirp
         _mem.att = 0    # not supported in chirp
-        self.set_tmode(mem, _mem)
+        self._set_tmode(mem, _mem)
         try:
             _mem.ssb_step = self.STEPSSSB.index(mem.tuning_step)
         except ValueError:
@@ -490,10 +524,11 @@
     def validate_memory(self, mem):
         msgs = yaesu_clone.YaesuCloneModeRadio.validate_memory(self, mem)
 
-	lo, hi = self.VALID_BANDS[2]    # this is fm broadcasting
-	if mem.freq >= lo and mem.freq <= hi:
+        lo, hi = self.VALID_BANDS[2]    # this is fm broadcasting
+        if mem.freq >= lo and mem.freq <= hi:
             if mem.mode != "FM":
-                msgs.append(chirp_common.ValidationError("Only FM is supported in this band"))
+                msgs.append(chirp_common.ValidationError(\
+                        "Only FM is supported in this band"))
         # TODO check that step is valid in current mode
         return msgs
 
@@ -503,6 +538,7 @@
 
 @directory.register
 class FT817NDRadio(FT817Radio):
+    """Yaesu FT-817ND"""
     MODEL = "FT-817ND"
 
     _model = ""
@@ -512,8 +548,9 @@
 
 @directory.register
 class FT817ND_US_Radio(FT817Radio):
-    # seems that radios configured for 5MHz operations send one paket more than others
-    # so we have to distinguish sub models
+    """Yaesu FT-817ND (US version)"""
+    # seems that radios configured for 5MHz operations send one paket
+    # more than others so we have to distinguish sub models
     MODEL = "FT-817ND (US)"
 
     _model = ""
@@ -533,14 +570,16 @@
     SPECIAL_MEMORIES = dict(FT817Radio.SPECIAL_MEMORIES)
     SPECIAL_MEMORIES.update(SPECIAL_60M)
 
-    SPECIAL_MEMORIES_REV = dict(zip(SPECIAL_MEMORIES.values(), SPECIAL_MEMORIES.keys()))
+    SPECIAL_MEMORIES_REV = dict(zip(SPECIAL_MEMORIES.values(),
+                                    SPECIAL_MEMORIES.keys()))
 
     def _get_special_60M(self, number):
         mem = chirp_common.Memory()
         mem.number = self.SPECIAL_60M[number]
         mem.extd_number = number
 
-        _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number]
+        _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX +
+                                                mem.number]
 
         mem = self._get_memory(mem, _mem)
 
@@ -564,16 +603,19 @@
                                         "is not supported on M-60x channels")
 
         if mem.mode not in ["USB", "LSB", "CW", "CWR", "NCW", "NCWR", "DIG"]:
-            raise errors.RadioError(_("Mode {mode} is not valid "
-                                      "in 60m channels").format(mode=mem.mode))
-        _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number]
+            raise errors.RadioError("Mode {mode} is not valid "
+                                    "in 60m channels".format(mode=mem.mode))
+        _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX +
+                                                mem.number]
         self._set_memory(mem, _mem)
 
     def get_memory(self, number):
         if number in self.SPECIAL_60M.keys():
             return self._get_special_60M(number)
-        elif number < 0 and self.SPECIAL_MEMORIES_REV[number] in self.SPECIAL_60M.keys():
-            # I can't stop delete operation from loosing extd_number but I know how to get it back
+        elif number < 0 and \
+                self.SPECIAL_MEMORIES_REV[number] in self.SPECIAL_60M.keys():
+            # I can't stop delete operation from loosing extd_number but
+            # I know how to get it back
             return self._get_special_60M(self.SPECIAL_MEMORIES_REV[number])
         else:
             return FT817Radio.get_memory(self, number)
diff -r db82df47f205 -r f805c420592f chirp/ft857.py
--- a/chirp/ft857.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ft857.py	Fri Apr 27 14:35:41 2012 -0700
@@ -18,7 +18,7 @@
 from chirp import bitwise
 import os
 
-mem_format = """
+MEM_FORMAT = """
 struct mem_struct{
   u8   tag_on_off:1,
        tag_default:1,
@@ -84,6 +84,7 @@
 
 @directory.register
 class FT857Radio(ft817.FT817Radio):
+    """Yaesu FT-857/897"""
     MODEL = "FT-857/897"
     _model = ""
 
@@ -121,10 +122,15 @@
     _memsize = 7341
     # block 9 (140 Bytes long) is to be repeted 40 times 
     # should be 42 times but this way I can use original 817 functions
-    _block_lengths = [ 2, 82, 252, 196, 252, 196, 212, 55, 140, 140, 140, 38, 176]
-    VALID_BANDS = [(100000,33000000), (33000000,56000000), (76000000,108000000), (108000000,137000000), (137000000,164000000), (420000000,470000000)] # warning ranges has to be in this exact order
+    _block_lengths = [ 2, 82, 252, 196, 252, 196, 212, 55, 140, 140, 140,
+                       38, 176]
+    # warning ranges has to be in this exact order
+    VALID_BANDS = [(100000, 33000000), (33000000, 56000000),
+                   (76000000, 108000000), (108000000, 137000000),
+                   (137000000, 164000000), (420000000, 470000000)]
 
-    SPECIAL_MEMORIES = {        # WARNING Index are hard wired in memory management code !!!
+    # WARNING Index are hard wired in memory management code !!!
+    SPECIAL_MEMORIES = {
         "VFOa-1.8M" : -37,
         "VFOa-3.5M" : -36,
         "VFOa-5M" : -35,
@@ -168,7 +174,8 @@
     FIRST_VFOA_INDEX = -22
     LAST_VFOA_INDEX = -37
 
-    SPECIAL_PMS = {          # WARNING Index are hard wired in memory management code !!!
+    # WARNING Index are hard wired in memory management code !!!
+    SPECIAL_PMS = {
         "PMS-1L" : -47,
         "PMS-1U" : -46,
         "PMS-2L" : -45,
@@ -184,7 +191,8 @@
     SPECIAL_MEMORIES = dict(SPECIAL_MEMORIES)
     SPECIAL_MEMORIES.update(SPECIAL_PMS)
 
-    SPECIAL_MEMORIES_REV = dict(zip(SPECIAL_MEMORIES.values(), SPECIAL_MEMORIES.keys()))
+    SPECIAL_MEMORIES_REV = dict(zip(SPECIAL_MEMORIES.values(),
+                                    SPECIAL_MEMORIES.keys()))
 
     def get_features(self):
         rf = ft817.FT817Radio.get_features(self)
@@ -193,22 +201,25 @@
         rf.valid_cross_modes = self.CROSS_MODES_REV.keys()
         return rf
 
-    def get_duplex(self, mem, _mem):
+    def _get_duplex(self, mem, _mem):
         # radio set is_duplex only for + and - but not for split
-        # at the same time it does not complain if we set it same way 817 does (so no set_duplex here)
+        # at the same time it does not complain if we set it same way 817 does
+        # (so no set_duplex here)
         mem.duplex = self.DUPLEX[_mem.duplex]
 
-    def get_tmode(self, mem, _mem):
-	# I do not use is_split_tone here because the radio sometimes set it also for standard tone mode
+    def _get_tmode(self, mem, _mem):
+	# I do not use is_split_tone here because the radio sometimes set it
+        # also for standard tone mode
         try:
             mem.tmode = self.TMODES[int(_mem.tmode)]
         except KeyError:
             mem.tmode = "Cross"
             mem.cross_mode = self.CROSS_MODES[int(_mem.tmode)]
 
-    def set_tmode(self, mem, _mem):
-	_mem.unknown_flag = 0	# have to put this bit to 0 otherwise we get strange display in tone frequency (menu 83)
-				# see bug #88
+    def _set_tmode(self, mem, _mem):
+        # have to put this bit to 0 otherwise we get strange display in tone
+        # frequency (menu 83). See bug #88
+        _mem.unknown_flag = 0
         if mem.tmode != "Cross":
             _mem.is_split_tone = 0
             _mem.tmode = self.TMODES_REV[mem.tmode]
@@ -217,18 +228,24 @@
             _mem.is_split_tone = 1
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def _get_special_pms(self, number):
         mem = chirp_common.Memory()
         mem.number = self.SPECIAL_PMS[number]
         mem.extd_number = number
 
-	bitindex = 47 + mem.number
+        bitindex = 47 + mem.number
         used = (self._memobj.pmsvisible >> bitindex) & 0x01
         valid = (self._memobj.pmsfilled >> bitindex) & 0x01
         if os.getenv("CHIRP_DEBUG"):
-	    print "mem.number %i bitindex %i pmsvisible %i pmsfilled %i used %i filled %i" % (mem.number, bitindex, self._memobj.pmsvisible, self._memobj.pmsfilled, used, valid)
+            print "mem.number %i bitindex %i pmsvisible %i" % \
+                (mem.number,
+                 bitindex,
+                 self._memobj.pmsvisible),
+            print "pmsfilled %i used %i filled %i" % (self._memobj.pmsfilled,
+                                                      used,
+                                                      valid)
         if not used:
             mem.empty = True
         if not valid:
@@ -249,7 +266,7 @@
     def _set_special_pms(self, mem):
         cur_mem = self._get_special_pms(self.SPECIAL_MEMORIES_REV[mem.number])
 
-	bitindex = 47 + mem.number
+        bitindex = 47 + mem.number
         wasused = (self._memobj.pmsvisible >> bitindex) & 0x01
         wasvalid = (self._memobj.pmsfilled >> bitindex) & 0x01
 
@@ -273,8 +290,10 @@
     def get_memory(self, number):
         if number in self.SPECIAL_PMS.keys():
             return self._get_special_pms(number)
-        elif number < 0 and self.SPECIAL_MEMORIES_REV[number] in self.SPECIAL_PMS.keys():
-            # I can't stop delete operation from loosing extd_number but I know how to get it back
+        elif number < 0 and \
+                self.SPECIAL_MEMORIES_REV[number] in self.SPECIAL_PMS.keys():
+            # I can't stop delete operation from loosing extd_number but
+            # I know how to get it back
             return self._get_special_pms(self.SPECIAL_MEMORIES_REV[number])
         else:
             return ft817.FT817Radio.get_memory(self, number)
@@ -287,16 +306,17 @@
 
 @directory.register
 class FT857_US_Radio(FT857Radio):
-    # seems that radios configured for 5MHz operations send one paket more than others
-    # so we have to distinguish sub models
+    """Yaesu FT857/897 (US version)"""
+    # seems that radios configured for 5MHz operations send one paket more
+    # than others so we have to distinguish sub models
     MODEL = "FT-857/897 (US)"
 
     _model = ""
     _memsize = 7481
     # block 9 (140 Bytes long) is to be repeted 40 times 
     # should be 42 times but this way I can use original 817 functions
-    _block_lengths = [ 2, 82, 252, 196, 252, 196, 212, 55, 140, 140, 140, 38, 176, 140]
-
+    _block_lengths = [ 2, 82, 252, 196, 252, 196, 212, 55, 140, 140, 140, 38,
+                       176, 140]
 
     SPECIAL_60M = {
         "M-601" : -52,
@@ -310,7 +330,8 @@
     SPECIAL_MEMORIES = dict(FT857Radio.SPECIAL_MEMORIES)
     SPECIAL_MEMORIES.update(SPECIAL_60M)
 
-    SPECIAL_MEMORIES_REV = dict(zip(SPECIAL_MEMORIES.values(), SPECIAL_MEMORIES.keys()))
+    SPECIAL_MEMORIES_REV = dict(zip(SPECIAL_MEMORIES.values(),
+                                    SPECIAL_MEMORIES.keys()))
 
     # this is identical to the one in FT817ND_US_Radio but we inherit from 857
     def _get_special_60M(self, number):
@@ -318,7 +339,8 @@
         mem.number = self.SPECIAL_60M[number]
         mem.extd_number = number
 
-        _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number]
+        _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX +
+                                                mem.number]
 
         mem = self._get_memory(mem, _mem)
 
@@ -343,16 +365,19 @@
                                         "is not supported on M-60x channels")
 
         if mem.mode not in ["USB", "LSB", "CW", "CWR", "NCW", "NCWR", "DIG"]:
-            raise errors.RadioError(_("Mode {mode} is not valid "
-                                      "in 60m channels").format(mode=mem.mode))
-        _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number]
+            raise errors.RadioError("Mode {mode} is not valid "
+                                    "in 60m channels".format(mode=mem.mode))
+        _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX +
+                                                mem.number]
         self._set_memory(mem, _mem)
 
     def get_memory(self, number):
         if number in self.SPECIAL_60M.keys():
             return self._get_special_60M(number)
-        elif number < 0 and self.SPECIAL_MEMORIES_REV[number] in self.SPECIAL_60M.keys():
-            # I can't stop delete operation from loosing extd_number but I know how to get it back
+        elif number < 0 and \
+                self.SPECIAL_MEMORIES_REV[number] in self.SPECIAL_60M.keys():
+            # I can't stop delete operation from loosing extd_number but
+            # I know how to get it back
             return self._get_special_60M(self.SPECIAL_MEMORIES_REV[number])
         else:
             return FT857Radio.get_memory(self, number)
diff -r db82df47f205 -r f805c420592f chirp/generic_csv.py
--- a/chirp/generic_csv.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/generic_csv.py	Fri Apr 27 14:35:41 2012 -0700
@@ -19,10 +19,29 @@
 from chirp import chirp_common, errors, directory
 
 class OmittedHeaderError(Exception):
+    """Internal exception to signal that a column has been omitted"""
     pass
 
+def get_datum_by_header(headers, data, header):
+    """Return the column corresponding to @headers[@header] from @data"""
+    if header not in headers:
+        raise OmittedHeaderError("Header %s not provided" % header)
+
+    try:
+        return data[headers.index(header)]
+    except IndexError:
+        raise OmittedHeaderError("Header %s not provided on this line" % \
+                                     header)
+
+def write_memory(writer, mem):
+    """Write @mem using @writer if not empty"""
+    if mem.empty:
+        return
+    writer.writerow(mem.to_csv())
+
 @directory.register
 class CSVRadio(chirp_common.FileBackedRadio, chirp_common.IcomDstarSupport):
+    """A driver for Generic CSV files"""
     VENDOR = "Generic"
     MODEL = "CSV"
     FILE_EXTENSION = "csv"
@@ -51,13 +70,14 @@
         self.errors = []
         self.memories = []
         for i in range(0, 1000):
-            m = chirp_common.Memory()
-            m.number = i
-            m.empty = True
-            self.memories.append(m)
+            mem = chirp_common.Memory()
+            mem.number = i
+            mem.empty = True
+            self.memories.append(mem)
 
     def __init__(self, pipe):
         chirp_common.FileBackedRadio.__init__(self, None)
+        self.memories = []
 
         self._filename = pipe
         if self._filename and os.path.exists(self._filename):
@@ -86,34 +106,17 @@
 
         return rf
 
-    def _parse_quoted_line(self, line):
-        line = line.replace("\n", "")
-        line = line.replace("\r", "")
-        line = line.replace('"', "")
-
-        return line.split(",")
-
-    def _get_datum_by_header(self, headers, data, header):
-        if header not in headers:
-            raise OmittedHeaderError("Header %s not provided" % header)
-
-        try:
-            return data[headers.index(header)]
-        except IndexError:
-            raise OmittedHeaderError("Header %s not provided on this line" %\
-                                     header)
-
     def _parse_csv_data_line(self, headers, line):
         mem = chirp_common.Memory()
         try:
-            if self._get_datum_by_header(headers, line, "Mode") == "DV":
+            if get_datum_by_header(headers, line, "Mode") == "DV":
                 mem = chirp_common.DVMemory()
         except OmittedHeaderError:
             pass
 
         for header, (typ, attr) in self.ATTR_MAP.items():
             try:
-                val = self._get_datum_by_header(headers, line, header)
+                val = get_datum_by_header(headers, line, header)
                 if not val and typ == int:
                     val = None
                 else:
@@ -174,12 +177,6 @@
             print self.errors
             raise errors.InvalidDataError("No channels found")
 
-    def save_memory(self, writer, mem):
-        if mem.empty:
-            return
-        
-        writer.writerow(mem.to_csv())
-
     def save(self, filename=None):
         if filename is None and self._filename is None:
             raise errors.RadioError("Need a location to save to")
@@ -192,7 +189,7 @@
         writer.writerow(chirp_common.Memory.CSV_FORMAT)
 
         for mem in self.memories:
-            self.save_memory(writer, mem)
+            write_memory(writer, mem)
 
         f.close()
 
@@ -220,20 +217,20 @@
         delta += 1
         
         for i in range(len(self.memories), len(self.memories) + delta + 1):
-            m = chirp_common.Memory()
-            m.empty = True
-            m.number = i
-            self.memories.append(m)
+            mem = chirp_common.Memory()
+            mem.empty = True
+            mem.number = i
+            self.memories.append(mem)
 
     def set_memory(self, newmem):
         self._grow(newmem.number)
         self.memories[newmem.number] = newmem
 
     def erase_memory(self, number):
-        m = chirp_common.Memory()
-        m.number = number
-        m.empty = True
-        self.memories[number] = m
+        mem = chirp_common.Memory()
+        mem.number = number
+        mem.empty = True
+        self.memories[number] = mem
 
     def get_raw_memory(self, number):
         return ",".join(chirp_common.Memory.CSV_FORMAT) + \
@@ -241,5 +238,6 @@
             ",".join(self.memories[number].to_csv())
 
     @classmethod
-    def match_model(cls, filedata, filename):
+    def match_model(cls, _filedata, filename):
+        """Match files ending in .CSV"""
         return filename.lower().endswith("." + cls.FILE_EXTENSION)
diff -r db82df47f205 -r f805c420592f chirp/generic_tpe.py
--- a/chirp/generic_tpe.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/generic_tpe.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,12 +13,10 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import os
-import csv
-
+import UserDict
 from chirp import chirp_common, directory, generic_csv
 
-class TpeMap:
+class TpeMap(UserDict.UserDict):
     """Pretend we're a dict"""
     def items(self):
         return [
@@ -27,13 +25,20 @@
             ("Call Sign"       , (str, "name")),
             ("Output Frequency", (chirp_common.parse_freq, "freq")),
             ("Input Frequency" , (str, "duplex")),
-            ("CTCSS Tones"     , (lambda v: "Tone" if float(v) in chirp_common.TONES else "", "tmode")),
-            ("CTCSS Tones"     , (lambda v: float(v) if float(v) in chirp_common.TONES else 88.5, "rtone")),
-            ("CTCSS Tones"     , (lambda v: float(v) if float(v) in chirp_common.TONES else 88.5, "ctone")),
+            ("CTCSS Tones"     , (lambda v: "Tone" 
+                                  if float(v) in chirp_common.TONES
+                                  else "", "tmode")),
+            ("CTCSS Tones"     , (lambda v: float(v)
+                                  if float(v) in chirp_common.TONES
+                                  else 88.5, "rtone")),
+            ("CTCSS Tones"     , (lambda v: float(v)
+                                  if float(v) in chirp_common.TONES
+                                  else 88.5, "ctone")),
         ]
 
 @directory.register
 class TpeRadio(generic_csv.CSVRadio):
+    """Generic ARRL Travel Plus"""
     VENDOR = "ARRL"
     MODEL = "Travel Plus"
     FILE_EXTENSION = "tpe"
diff -r db82df47f205 -r f805c420592f chirp/generic_xml.py
--- a/chirp/generic_xml.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/generic_xml.py	Fri Apr 27 14:35:41 2012 -0700
@@ -19,6 +19,7 @@
 from chirp import chirp_common, errors, xml_ll, platform, directory
 
 def validate_doc(doc):
+    """Validate the document"""
     basepath = platform.get_platform().executable_path()
     path = os.path.abspath(os.path.join(basepath, "chirp.xsd"))
     if not os.path.exists(path):
@@ -37,16 +38,16 @@
     errs = []
     warnings = []
 
-    def err(msg, arg=None):
+    def _err(msg, *_args):
         errs.append("ERROR: %s" % msg)
 
-    def wrn(msg, arg=None):
+    def _wrn(msg, *_args):
         print "WARNING: %s" % msg
         warnings.append("WARNING: %s" % msg)
 
-    validCtx = schema.schemaNewValidCtxt()
-    validCtx.setValidityErrorHandler(err, wrn)
-    err = validCtx.schemaValidateDoc(doc)
+    validctx = schema.schemaNewValidCtxt()
+    validctx.setValidityErrorHandler(_err, _wrn)
+    err = validctx.schemaValidateDoc(doc)
     print os.linesep.join(warnings)
     if err:
         print "---DOC---\n%s\n------" % doc.serialize(format=1)
@@ -54,6 +55,7 @@
         raise errors.RadioError("Schema error")
 
 def default_banks():
+    """Return an empty set of banks"""
     banks = []
 
     for i in range(0, 26):
@@ -63,6 +65,7 @@
 
 @directory.register
 class XMLRadio(chirp_common.FileBackedRadio, chirp_common.IcomDstarSupport):
+    """Generic XML driver"""
     VENDOR = "Generic"
     MODEL = "XML"
     FILE_EXTENSION = "chirp"
@@ -135,18 +138,6 @@
         xml_ll.del_memory(self.doc, number)
 
     @classmethod
-    def match_model(cls, filedata, filename):
+    def match_model(cls, _filedata, filename):
+        """Match this driver if the extension matches"""
         return filename.lower().endswith("." + cls.FILE_EXTENSION)
-
-if __name__ == "__main__":
-    r = XMLRadio("testmem.chirp")
-
-    print r.get_memory(3)
-
-    m = chirp_common.Memory()
-    m.name = "TestMem2"
-    m.freq = 123.456
-    m.number = 10
-
-    #r.set_memory(m)
-    #r.erase_memory(10)
diff -r db82df47f205 -r f805c420592f chirp/ic2100.py
--- a/chirp/ic2100.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ic2100.py	Fri Apr 27 14:35:41 2012 -0700
@@ -16,7 +16,7 @@
 from chirp import chirp_common, icf, util, directory
 from chirp import bitwise, memmap
 
-mem_format = """
+MEM_FORMAT = """
 struct {
   bbcd  freq[2];
   u8    freq_10khz:4,
@@ -82,8 +82,73 @@
 DUPLEX = ["", "", "+", "-"]
 STEPS =  [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0]
 
+def _get_special():
+    special = { "C": 506 }
+    for i in range(0, 3):
+        ida = "%iA" % (i + 1)
+        idb = "%iB" % (i + 1)
+        num = 500 + (i * 2)
+        special[ida] = num
+        special[idb] = num + 1
+
+    return special
+
+def _get_freq(mem):
+    freq = (int(mem.freq) * 100000) + \
+        (mem.freq_10khz * 10000) + \
+        (mem.freq_1khz * 1000)
+
+    if mem.is_12_5:
+        if chirp_common.is_12_5(freq):
+            pass
+        elif mem.freq_1khz == 2:
+            freq += 500
+        elif mem.freq_1khz == 5:
+            freq += 2500
+        elif mem.freq_1khz == 7:
+            freq += 500
+        else:
+            raise Exception("Unable to resolve 12.5kHz: %i" % freq)
+
+    return freq
+
+def _set_freq(mem, freq):
+    mem.freq = freq / 100000
+    mem.freq_10khz = (freq / 10000) % 10
+    khz = (freq / 1000) % 10
+    mem.freq_1khz = khz
+    mem.is_12_5 = chirp_common.is_12_5(freq)
+
+def _get_offset(mem):
+    raw = memmap.MemoryMap(mem.get_raw())
+    if ord(raw[5]) & 0x0A:
+        raw[5] = ord(raw[5]) & 0xF0
+        mem.set_raw(raw.get_packed())
+        offset = int(mem.offset) * 1000 + 5000
+        raw[5] = ord(raw[5]) | 0x0A
+        mem.set_raw(raw.get_packed())
+        return offset
+    else:
+        return int(mem.offset) * 1000
+
+def _set_offset(mem, offset):
+    if (offset % 10) == 5000:
+        extra = 0x0A
+        offset -= 5000
+    else:
+        extra = 0x00
+
+    mem.offset = offset / 1000
+    raw = memmap.MemoryMap(mem.get_raw())
+    raw[5] = ord(raw[5]) | extra
+    mem.set_raw(raw.get_packed())
+
+def _wipe_memory(mem, char):
+    mem.set_raw(char * (mem.size() / 8))
+
 @directory.register
 class IC2100Radio(icf.IcomCloneModeRadio):
+    """Icom IC-2100"""
     VENDOR = "Icom"
     MODEL = "IC-2100H"
 
@@ -110,81 +175,20 @@
         return rf
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
-
-    def _get_special(self):
-        special = { "C": 506 }
-        for i in range(0, 3):
-            idA = "%iA" % (i+1)
-            idB = "%iB" % (i+1)
-            num = 500 + (i * 2)
-            special[idA] = num
-            special[idB] = num + 1
-
-        return special
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_special_locations(self):
-        return sorted(self._get_special().keys())
-
-    def __get_freq(self, mem):
-        freq = (int(mem.freq) * 100000) + \
-            (mem.freq_10khz * 10000) + \
-            (mem.freq_1khz * 1000)
-
-        if mem.is_12_5:
-            if chirp_common.is_12_5(freq):
-                pass
-            elif mem.freq_1khz == 2:
-                freq += 500
-            elif mem.freq_1khz == 5:
-                freq += 2500
-            elif mem.freq_1khz == 7:
-                freq += 500
-            else:
-                raise Exception("Unable to resolve 12.5kHz: %i" % freq)
-
-        return freq
-
-    def __set_freq(self, mem, freq):
-        mem.freq = freq / 100000
-        mem.freq_10khz = (freq / 10000) % 10
-        khz = (freq / 1000) % 10
-        mem.freq_1khz = khz
-        mem.is_12_5 = chirp_common.is_12_5(freq)
-
-    def __get_offset(self, mem):
-        raw = memmap.MemoryMap(mem.get_raw())
-        if ord(raw[5]) & 0x0A:
-            raw[5] = ord(raw[5]) & 0xF0
-            mem.set_raw(raw.get_packed())
-            offset = int(mem.offset) * 1000 + 5000
-            raw[5] = ord(raw[5]) | 0x0A
-            mem.set_raw(raw.get_packed())
-            return offset
-        else:
-            return int(mem.offset) * 1000
-
-    def __set_offset(self, mem, offset):
-        if (offset % 10) == 5000:
-            extra = 0x0A
-            offset -= 5000
-        else:
-            extra = 0x00
-
-        mem.offset = offset / 1000
-        raw = memmap.MemoryMap(mem.get_raw())
-        raw[5] = ord(raw[5]) | extra
-        mem.set_raw(raw.get_packed())
+        return sorted(_get_special().keys())
 
     def get_memory(self, number):
         mem = chirp_common.Memory()
 
         if isinstance(number, str):
             if number == "C":
-                number = self._get_special()[number]
+                number = _get_special()[number]
                 _mem = self._memobj.call[0]
             else:
-                number = self._get_special()[number]
+                number = _get_special()[number]
                 _mem = self._memobj.special[number - 500]
             empty = False
         else:
@@ -202,15 +206,15 @@
         if number <= 100:
             mem.skip = isskip and "S" or ""
         else:
-            mem.extd_number = util.get_dict_rev(self._get_special(), number)
+            mem.extd_number = util.get_dict_rev(_get_special(), number)
             mem.immutable = ["number", "skip", "extd_number"]
 
         if empty:
             mem.empty = True
             return mem
 
-        mem.freq = self.__get_freq(_mem)
-        mem.offset = self.__get_offset(_mem)
+        mem.freq = _get_freq(_mem)
+        mem.offset = _get_offset(_mem)
         mem.rtone = chirp_common.TONES[_mem.rtone]
         mem.ctone = chirp_common.TONES[_mem.ctone]
         mem.tmode = TMODES[_mem.tmode]
@@ -218,14 +222,11 @@
         
         return mem
 
-    def _wipe_memory(self, mem, char):
-        mem.set_raw(char * (mem.size() / 8))
-
     def set_memory(self, mem):
         if mem.number == "C":
             _mem = self._memobj.call[0]
         elif isinstance(mem.number, str):
-            _mem = self._memobj.special[self._get_special[number] - 500]
+            _mem = self._memobj.special[_get_special[mem.number] - 500]
         else:
             number = mem.number - 1
             _mem = self._memobj.memory[number]
@@ -242,8 +243,8 @@
                 _skp &= ~mask
             _mem.name = mem.name.ljust(6)
 
-        self.__set_freq(_mem, mem.freq)
-        self.__set_offset(_mem, mem.offset)
+        _set_freq(_mem, mem.freq)
+        _set_offset(_mem, mem.offset)
         _mem.rtone = chirp_common.TONES.index(mem.rtone)
         _mem.ctone = chirp_common.TONES.index(mem.ctone)
         _mem.tmode = TMODES.index(mem.tmode)
diff -r db82df47f205 -r f805c420592f chirp/ic2200.py
--- a/chirp/ic2200.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ic2200.py	Fri Apr 27 14:35:41 2012 -0700
@@ -16,7 +16,7 @@
 from chirp import chirp_common, icf, util, directory
 from chirp import bitwise
 
-mem_format = """
+MEM_FORMAT = """
 struct {
   ul16  freq;
   ul16  offset;
@@ -83,8 +83,23 @@
                 chirp_common.PowerLevel("MidLow", watts=10),
                 chirp_common.PowerLevel("Low", watts=5)]
 
+def _get_special():
+    special = { "C" : 206 }
+    for i in range(0, 3):
+        ida = "%iA" % (i+1)
+        idb = "%iB" % (i+1)
+        num = 200 + i * 2
+        special[ida] = num
+        special[idb] = num + 1
+
+    return special
+
+def _wipe_memory(mem, char):
+    mem.set_raw(char * (mem.size() / 8))
+
 @directory.register
 class IC2200Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport):
+    """Icom IC-2200"""
     VENDOR = "Icom"
     MODEL = "IC-2200H"
 
@@ -145,25 +160,14 @@
         return rf
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
-
-    def _get_special(self):
-        special = { "C" : 206 }
-        for i in range(0, 3):
-            idA = "%iA" % (i+1)
-            idB = "%iB" % (i+1)
-            num = 200 + i * 2
-            special[idA] = num
-            special[idB] = num + 1
-
-        return special
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_special_locations(self):
-        return sorted(self._get_special().keys())
+        return sorted(_get_special().keys())
 
     def get_memory(self, number):
         if isinstance(number, str):
-            number = self._get_special()[number]
+            number = _get_special()[number]
 
         _mem = self._memobj.memory[number]
         _flag = self._memobj.flags[number]
@@ -183,7 +187,7 @@
         if number < 200:
             mem.skip = _flag.skip and "S" or ""
         else:
-            mem.extd_number = util.get_dict_rev(self._get_special(), number)
+            mem.extd_number = util.get_dict_rev(_get_special(), number)
             mem.immutable = ["number", "skip", "bank", "bank_index",
                              "extd_number"]
 
@@ -214,12 +218,9 @@
 
         return [m for m in self._memories if m.number >= lo and m.number <= hi]
 
-    def _wipe_memory(self, mem, char):
-        mem.set_raw(char * (mem.size() / 8))
-
     def set_memory(self, mem):
         if isinstance(mem.number, str):
-            number = self._get_special()[mem.number]
+            number = _get_special()[mem.number]
         else:
             number = mem.number
 
@@ -230,11 +231,11 @@
 
         _flag.empty = mem.empty
         if mem.empty:
-            self._wipe_memory(_mem, "\xFF")
+            _wipe_memory(_mem, "\xFF")
             return
 
         if was_empty:
-            self._wipe_memory(_mem, "\x00")
+            _wipe_memory(_mem, "\x00")
 
         _mem.unknown8 = 0
         _mem.is_625 = chirp_common.is_fractional_step(mem.freq)
diff -r db82df47f205 -r f805c420592f chirp/ic2720.py
--- a/chirp/ic2720.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ic2720.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,10 +13,10 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from chirp import chirp_common, icf, util, directory
+from chirp import chirp_common, icf, directory
 from chirp import bitwise
 
-mem_format = """
+MEM_FORMAT = """
 struct {
     u32 freq;
     u32 offset;
@@ -69,6 +69,7 @@
 
 @directory.register
 class IC2720Radio(icf.IcomCloneModeRadio):
+    """Icom IC-2720"""
     VENDOR = "Icom"
     MODEL = "IC-2720H"
     
@@ -113,7 +114,7 @@
         return rf
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_raw_memory(self, number):
         return repr(self._memobj.memory[number])
diff -r db82df47f205 -r f805c420592f chirp/ic2820.py
--- a/chirp/ic2820.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ic2820.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,10 +13,10 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from chirp import chirp_common, icf, errors, util, directory
-from chirp import bitwise;
+from chirp import chirp_common, icf, util, directory
+from chirp import bitwise
 
-mem_format = """
+MEM_FORMAT = """
 struct {
   u32  freq;
   u32  offset;
@@ -84,7 +84,8 @@
 
 MEM_LOC_SIZE = 48
 
-class IC2820Bank(icf.IcomBank):
+class IC2820Bank(icf.IcomNamedBank):
+    """An IC2820 bank"""
     def get_name(self):
         _banks = self._model._radio._memobj.bank_names
         return str(_banks[self.index].name).rstrip()
@@ -93,8 +94,30 @@
         _banks = self._model._radio._memobj.bank_names
         _banks[self.index].name = str(name).ljust(8)[:8]
 
+def _get_special():
+    special = {"C0" : 500 + 20,
+               "C1" : 500 + 21}
+
+    for i in range(0, 10):
+        ida = "%iA" % i
+        idb = "%iB" % i
+        special[ida] = 500 + i * 2
+        special[idb] = 500 + i * 2 + 1
+
+    return special
+
+def _resolve_memory_number(number):
+    if isinstance(number, str):
+        return _get_special()[number]
+    else:
+        return number
+
+def _wipe_memory(mem, char):
+    mem.set_raw(char * (mem.size() / 8))
+
 @directory.register
 class IC2820Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport):
+    """Icom IC-2820"""
     VENDOR = "Icom"
     MODEL = "IC-2820H"
 
@@ -156,32 +179,14 @@
         rf.valid_name_length = 8
         return rf
 
-    def _get_special(self):
-        special = {"C0" : 500 + 20,
-                   "C1" : 500 + 21}
-
-        for i in range(0, 10):
-            idA = "%iA" % i
-            idB = "%iB" % i
-            special[idA] = 500 + i * 2
-            special[idB] = 500 + i * 2 + 1
-
-        return special
-
     def get_special_locations(self):
-        return sorted(self._get_special().keys())
+        return sorted(_get_special().keys())
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
-
-    def _resolve_memory_number(self, number):
-        if isinstance(number, str):
-            return self._get_special()[number]
-        else:
-            return number
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_memory(self, number):
-        number = self._resolve_memory_number(number)
+        number = _resolve_memory_number(number)
 
         bitpos = (1 << (number % 8))
         bytepos = number / 8
@@ -208,7 +213,7 @@
             elif _pskip & bitpos:
                 mem.skip = "P"
         else:
-            mem.extd_number = util.get_dict_rev(self._get_special(), number)
+            mem.extd_number = util.get_dict_rev(_get_special(), number)
             mem.immutable = ["number", "skip", "bank", "bank_index",
                              "extd_number"]
 
@@ -233,9 +238,6 @@
 
         return mem
 
-    def _wipe_memory(self, mem, char):
-        mem.set_raw(char * (mem.size() / 8))
-
     def set_memory(self, mem):
         bitpos = (1 << (mem.number % 8))
         bytepos = mem.number / 8
@@ -259,13 +261,13 @@
 
         if mem.empty:
             _used |= bitpos
-            self._wipe_memory(_mem, "\xFF")
+            _wipe_memory(_mem, "\xFF")
             self._set_bank(mem.number, None)
             return
 
         _used &= ~bitpos
         if was_empty:
-            self._wipe_memory(_mem, "\x00")
+            _wipe_memory(_mem, "\x00")
 
         _mem.freq = mem.freq
         _mem.offset = mem.offset
diff -r db82df47f205 -r f805c420592f chirp/ic9x.py
--- a/chirp/ic9x.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ic9x.py	Fri Apr 27 14:35:41 2012 -0700
@@ -16,13 +16,11 @@
 import time
 import threading
 
-from chirp import chirp_common, errors, memmap, ic9x_ll, util, icf, directory
+from chirp import chirp_common, errors, ic9x_ll, icf, util, directory
 from chirp import bitwise
 
-IC9xA_SPECIAL = {}
-IC9xA_SPECIAL_REV = {}
-IC9xB_SPECIAL = {}
-IC9xB_SPECIAL_REV = {}
+IC9XA_SPECIAL = {}
+IC9XB_SPECIAL = {}
 
 for i in range(0, 25):
     idA = "%iA" % i
@@ -30,30 +28,18 @@
     Anum = 800 + i * 2
     Bnum = 400 + i * 2
 
-    IC9xA_SPECIAL[idA] = Anum
-    IC9xA_SPECIAL[idB] = Bnum
-    IC9xA_SPECIAL_REV[Anum] = idA
-    IC9xA_SPECIAL_REV[Bnum] = idB
+    IC9XA_SPECIAL[idA] = Anum
+    IC9XA_SPECIAL[idB] = Bnum
 
-    IC9xB_SPECIAL[idA] = Bnum
-    IC9xB_SPECIAL[idB] = Bnum + 1
-    IC9xB_SPECIAL_REV[Bnum] = idA
-    IC9xB_SPECIAL_REV[Bnum+1] = idB
+    IC9XB_SPECIAL[idA] = Bnum
+    IC9XB_SPECIAL[idB] = Bnum + 1
 
-IC9xA_SPECIAL["C0"] = IC9xB_SPECIAL["C0"] = -1
-IC9xA_SPECIAL["C1"] = IC9xB_SPECIAL["C1"] = -2
+IC9XA_SPECIAL["C0"] = IC9XB_SPECIAL["C0"] = -1
+IC9XA_SPECIAL["C1"] = IC9XB_SPECIAL["C1"] = -2
 
-IC9xA_SPECIAL_REV[-1] = IC9xB_SPECIAL_REV[-1] = "C0"
-IC9xA_SPECIAL_REV[-2] = IC9xB_SPECIAL_REV[-2] = "C1"
-
-IC9x_SPECIAL = {
-    1 : IC9xA_SPECIAL,
-    2 : IC9xB_SPECIAL,
-}
-
-IC9x_SPECIAL_REV = {
-    1 : IC9xA_SPECIAL_REV,
-    2 : IC9xB_SPECIAL_REV,
+IC9X_SPECIAL = {
+    1 : IC9XA_SPECIAL,
+    2 : IC9XB_SPECIAL,
 }
 
 CHARSET = chirp_common.CHARSET_ALPHANUMERIC + \
@@ -61,7 +47,8 @@
 
 LOCK = threading.Lock()
 
-class IC9xBank(icf.IcomBank):
+class IC9xBank(icf.IcomNamedBank):
+    """Icom 9x Bank"""
     def get_name(self):
         banks = self._model._radio._ic9x_get_banks()
         return banks[self.index]
@@ -73,6 +60,7 @@
 
 @directory.register
 class IC9xRadio(icf.IcomLiveRadio):
+    """Base class for Icom IC-9x radios"""
     MODEL = "IC-91/92AD"
 
     _model = "ic9x" # Fake model info for detect.py
@@ -102,7 +90,7 @@
         self.set_memory(mem)
 
     def __init__(self, *args, **kwargs):
-        chirp_common.LiveRadio.__init__(self, *args, **kwargs)
+        icf.IcomLiveRadio.__init__(self, *args, **kwargs)
 
         if self.pipe:
             self.pipe.setTimeout(0.1)
@@ -119,35 +107,22 @@
             ic9x_ll.send_magic(self.pipe)
         self.__last = time.time()
 
-    def get_available_bank_index(self, bank):
-        indexes = []
-        for mem in self.__memcache.values():
-            if mem.bank == bank and mem.bank_index >= 0:
-                indexes.append(mem.bank_index)
-
-        print "Index list for %i: %s" % (bank, indexes)
-
-        for i in range(0, 99):
-            if i not in indexes:
-                return i
-
-        raise errors.RadioError("Out of slots in this bank")
-
     def get_special_locations(self):
-        return sorted(IC9x_SPECIAL[self.vfo].keys())
+        return sorted(IC9X_SPECIAL[self.vfo].keys())
     
     def get_memory(self, number):
         if isinstance(number, str):
             try:
-                number = IC9x_SPECIAL[self.vfo][number]
+                number = IC9X_SPECIAL[self.vfo][number]
             except KeyError:
-                raise InvalidMemoryLocation("Unknown channel %s" % number)
+                raise errors.InvalidMemoryLocation("Unknown channel %s" % \
+                                                       number)
 
         if number < -2 or number > 999:
             raise errors.InvalidValueError("Number must be between 0 and 999")
 
         if self.__memcache.has_key(number):
-                return self.__memcache[number]
+            return self.__memcache[number]
 
         self._lock.acquire()
         try:
@@ -165,7 +140,8 @@
         self._lock.release()
 
         if number > self._upper or number < 0:
-            mem.extd_number = IC9x_SPECIAL_REV[self.vfo][number]
+            mem.extd_number = util.get_dict_rev(IC9X_SPECIAL,
+                                                [self.vfo][number])
             mem.immutable = ["number", "skip", "bank", "bank_index",
                              "extd_number"]
 
@@ -184,7 +160,7 @@
 
         self._lock.release()
 
-        return repr(bitwise.parse(ic9x_ll.memory_frame_format, mframe))
+        return repr(bitwise.parse(ic9x_ll.MEMORY_FRAME_FORMAT, mframe))
 
     def get_memories(self, lo=0, hi=None):
         if hi is None:
@@ -192,7 +168,7 @@
 
         memories = []
 
-        for i in range(lo, hi+1):
+        for i in range(lo, hi + 1):
             try:
                 print "Getting %i" % i
                 mem = self.get_memory(i)
@@ -244,7 +220,8 @@
 
     def _ic9x_get_banks(self):
         if len(self.__bankcache.keys()) == 26:
-            return [self.__bankcache[k] for k in sorted(self.__bankcache.keys())]
+            return [self.__bankcache[k] for k in
+                    sorted(self.__bankcache.keys())]
 
         self._lock.acquire()
         try:
@@ -302,6 +279,7 @@
         return rf
 
 class IC9xRadioA(IC9xRadio):
+    """IC9x Band A subdevice"""
     VARIANT = "Band A"
     vfo = 1
     _upper = 849
@@ -323,6 +301,7 @@
         return rf
 
 class IC9xRadioB(IC9xRadio, chirp_common.IcomDstarSupport):
+    """IC9x Band B subdevice"""
     VARIANT = "Band B"
     vfo = 2
     _upper = 399
@@ -362,7 +341,7 @@
         calls = []
 
         self._maybe_send_magic()
-        for i in range(ulimit-1):
+        for i in range(ulimit - 1):
             call = ic9x_ll.get_call(self.pipe, cstype, i+1)
             calls.append(call)
 
@@ -426,15 +405,13 @@
                                              self.RPTCALL_LIMIT[1],
                                              calls)
 
+def _test():
+    import serial
+    ser = IC9xRadioB(serial.Serial(port="/dev/ttyUSB1",
+                                   baudrate=38400, timeout=0.1))
+    print ser.get_urcall_list()
+    print "-- FOO --"
+    ser.set_urcall_list(["K7TAY", "FOOBAR", "BAZ"])
+
 if __name__ == "__main__":
-    def test():
-        import serial
-        import util
-        r = IC9xRadioB(serial.Serial(port="/dev/ttyUSB1",
-                                     baudrate=38400, timeout=0.1))
-        print r.get_urcall_list()
-        #r.set_urcall_list(["K7TAY", "FOOBAR"])
-        print "-- FOO --"
-        r.set_urcall_list(["K7TAY", "FOOBAR", "BAZ"])
-
-    test()
+    _test()
diff -r db82df47f205 -r f805c420592f chirp/ic9x_icf.py
--- a/chirp/ic9x_icf.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ic9x_icf.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,7 +13,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from chirp import chirp_common, icf, ic9x_icf_ll, util, directory
+from chirp import chirp_common, icf, ic9x_icf_ll, util, directory, errors
 
 @directory.register
 class IC9xICFRadio(chirp_common.CloneModeRadio):
@@ -45,7 +45,7 @@
         return ic9x_icf_ll.get_memory(self._mmap, number)
 
     def load_mmap(self, filename):
-        mdata, self._mmap = icf.read_file(filename)
+        _mdata, self._mmap = icf.read_file(filename)
 
     def get_sub_devices(self):
         return [IC9xICFRadioA(self._mmap),
diff -r db82df47f205 -r f805c420592f chirp/ic9x_icf_ll.py
--- a/chirp/ic9x_icf_ll.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ic9x_icf_ll.py	Fri Apr 27 14:35:41 2012 -0700
@@ -14,7 +14,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import struct
-from chirp import chirp_common, util
+from chirp import chirp_common
 from chirp.memmap import MemoryMap
 
 MEM_LOC_SIZE_A = 20
@@ -31,12 +31,14 @@
 POS_NAME     = 12
 
 def get_mem_offset(number):
+    """Get the offset into the memory map for memory @number"""
     if number < 850:
         return MEM_LOC_SIZE_A * number
     else:
         return (MEM_LOC_SIZE_A * 850) + (MEM_LOC_SIZE_B * (number - 850))
 
 def get_raw_memory(mmap, number):
+    """Return a raw representation of memory @number"""
     offset = get_mem_offset(number)
     if number >= 850:
         size = MEM_LOC_SIZE_B
@@ -45,6 +47,7 @@
     return MemoryMap(mmap[offset:offset+size])
 
 def get_freq(mmap):
+    """Return the memory frequency"""
     if ord(mmap[10]) & 0x10:
         mult = 6250
     else:
@@ -53,22 +56,27 @@
     return val * mult
 
 def get_offset(mmap):
+    """Return the memory offset"""
     val, = struct.unpack(">H", mmap[POS_OFFSET:POS_OFFSET+2])
     return val * 5000
 
 def get_rtone(mmap):
+    """Return the memory rtone"""
     val = (ord(mmap[POS_TONE]) & 0xFC) >> 2
     return chirp_common.TONES[val]
 
 def get_ctone(mmap):
+    """Return the memory ctone"""
     val = (ord(mmap[POS_TONE]) & 0x03) | ((ord(mmap[POS_TONE+1]) & 0xF0) >> 4)
     return chirp_common.TONES[val]
 
 def get_dtcs(mmap):
+    """Return the memory dtcs value"""
     val = ord(mmap[POS_DTCS]) >> 1
     return chirp_common.DTCS_CODES[val]
 
 def get_mode(mmap):
+    """Return the memory mode"""
     val = ord(mmap[POS_MODE]) & 0x07
 
     modemap = ["FM", "NFM", "WFM", "AM", "DV", "FM"]
@@ -76,20 +84,22 @@
     return modemap[val]
 
 def get_ts(mmap):
+    """Return the memory tuning step"""
     val = (ord(mmap[POS_TS]) & 0xF0) >> 4
     if val == 14:
         return 5.0 # Coerce "Auto" to 5.0
 
-    ICF_TS = list(chirp_common.TUNING_STEPS)
-    ICF_TS.insert(2, 8.33)
-    ICF_TS.insert(3, 9.00)
-    ICF_TS.append(100.0)
-    ICF_TS.append(125.0)
-    ICF_TS.append(200.0)
+    icf_ts = list(chirp_common.TUNING_STEPS)
+    icf_ts.insert(2, 8.33)
+    icf_ts.insert(3, 9.00)
+    icf_ts.append(100.0)
+    icf_ts.append(125.0)
+    icf_ts.append(200.0)
 
-    return ICF_TS[val]
+    return icf_ts[val]
 
 def get_dtcs_polarity(mmap):
+    """Return the memory dtcs polarity"""
     val = (ord(mmap[POS_DTCSPOL]) & 0x03)
 
     pols = ["NN", "NR", "RN", "RR"]
@@ -97,6 +107,7 @@
     return pols[val]
 
 def get_duplex(mmap):
+    """Return the memory duplex"""
     val = (ord(mmap[POS_DUPLEX]) & 0x0C) >> 2
 
     dup = ["", "-", "+", ""]
@@ -104,9 +115,11 @@
     return dup[val]
 
 def get_name(mmap):
+    """Return the memory name"""
     return mmap[POS_NAME:POS_NAME+8]
 
 def get_memory(_mmap, number):
+    """Get memory @number from global memory map @_mmap"""
     mmap = get_raw_memory(_mmap, number)
     mem = chirp_common.Memory()
     mem.number = number
diff -r db82df47f205 -r f805c420592f chirp/ic9x_ll.py
--- a/chirp/ic9x_ll.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ic9x_ll.py	Fri Apr 27 14:35:41 2012 -0700
@@ -32,11 +32,13 @@
 
 # Dirty hack until I clean up this IC9x mess
 class IC9xMemory(chirp_common.Memory):
+    """A dirty hack to stash bank information in a memory"""
     _bank = None
     _bank_index = 0
     def __init__(self):
         chirp_common.Memory.__init__(self)
 class IC9xDVMemory(chirp_common.DVMemory):
+    """See above dirty hack"""
     _bank = None
     _bank_index = 0
     def __init__(self):
@@ -89,32 +91,34 @@
 
     return _ic9x_parse_frames(data)
 
-class IcomFrame:
-    pass
-
-class IC92Frame(IcomFrame):
+class IC92Frame:
+    """IC9x frame base class"""
     def get_vfo(self):
+        """Return the vfo number"""
         return ord(self._map[0])
 
     def set_vfo(self, vfo):
+        """Set the vfo number"""
         self._map[0] = chr(vfo)
 
     def from_raw(self, data):
+        """Construct the frame from raw data"""
         self._map = MemoryMap(data)
 
-        #self._map.printable()
-
     def from_frame(self, frame):
-        self._map = frame._map
+        """Construct the frame by copying another frame"""
+        self._map = MemoryMap(frame.get_raw())
 
     def __init__(self, subcmd=0, flen=0, cmd=0x1A):
         self._map = MemoryMap("\x00" * (4 + flen))
         self._map[0] = "\x01\x80" + chr(cmd) + chr(subcmd)
 
     def get_payload(self):
+        """Return the entire payload (sans header)"""
         return self._map[4:]
 
     def get_raw(self):
+        """Return the raw version of the frame"""
         return self._map.get_packed()
 
     def __str__(self):
@@ -126,6 +130,7 @@
         return string
 
     def send(self, pipe, verbose=False):
+        """Send the frame to the radio via @pipe"""
         if verbose:
             print "Sending:\n%s" % util.hexprint(self.get_raw())
 
@@ -146,10 +151,11 @@
         return self._map[start+4:end+4]
     
 class IC92GetBankFrame(IC92Frame):
+    """A frame for requesting bank information"""
     def __init__(self):
         IC92Frame.__init__(self, 0x09)
 
-    def send(self, pipe):
+    def send(self, pipe, verbose=False):
         rframes = ic9x_send(pipe, self.get_raw())
 
         if len(rframes) == 0:
@@ -158,27 +164,30 @@
         return rframes
 
 class IC92BankFrame(IC92Frame):
+    """A frame for bank information"""
     def __init__(self):
         # 1 byte for identifier
         # 8 bytes for name
         IC92Frame.__init__(self, 0x0B, 9)
 
-    def __str__(self):
-        return "Bank %s: %s" % (self._data[2], self._data[3:])
-
     def get_name(self):
+        """Return the bank name"""
         return self[1:]
 
     def get_identifier(self):
+        """Return the letter for the bank (A-Z)"""
         return self[0]
 
     def set_name(self, name):
+        """Set the bank name"""
         self[1] = name[:8].ljust(8)
 
     def set_identifier(self, ident):
+        """Set the letter for the bank (A-Z)"""
         self[0] = ident[0]
 
 class IC92MemClearFrame(IC92Frame):
+    """A frame for clearing (erasing) a memory"""
     def __init__(self, loc):
         # 2 bytes for location
         # 1 byte for 0xFF
@@ -187,24 +196,27 @@
         self[0] = struct.pack(">BHB", 1, int("%i" % loc, 16), 0xFF)
 
 class IC92MemGetFrame(IC92Frame):
-    def __init__(self, loc, call=False):
+    """A frame for requesting a memory"""
+    def __init__(self, loc, iscall=False):
         # 2 bytes for location
         IC92Frame.__init__(self, 0x00, 3)
 
-        if call:
-            c = 2
+        if iscall:
+            call = 2
         else:
-            c = 1
+            call = 1
 
-        self[0] = struct.pack(">BH", c, int("%i" % loc, 16))
+        self[0] = struct.pack(">BH", call, int("%i" % loc, 16))
 
 class IC92GetCallsignFrame(IC92Frame):
-    def __init__(self, type, number):
-        IC92Frame.__init__(self, type, 1, 0x1D)
+    """A frame for getting callsign information"""
+    def __init__(self, calltype, number):
+        IC92Frame.__init__(self, calltype, 1, 0x1D)
 
         self[0] = chr(number)
 
 class IC92CallsignFrame(IC92Frame):
+    """A frame to communicate callsign information"""
     command = 0 # Invalid
     width = 8
 
@@ -216,19 +228,23 @@
         self[0] = chr(number) + callsign[:self.width].ljust(self.width)
 
     def get_callsign(self):
+        """Return the actual callsign"""
         return self[1:self.width+1].rstrip()
 
 class IC92YourCallsignFrame(IC92CallsignFrame):
+    """URCALL frame"""
     command = 6 # Your
 
 class IC92RepeaterCallsignFrame(IC92CallsignFrame):
+    """RPTCALL frame"""
     command = 7 # Repeater
 
 class IC92MyCallsignFrame(IC92CallsignFrame):
+    """MYCALL frame"""
     command = 8 # My
     width = 12 # 4 bytes for /STID
 
-memory_frame_format = """
+MEMORY_FRAME_FORMAT = """
 struct {
   u8 vfo;
   bbcd number[2];
@@ -261,6 +277,7 @@
 """
 
 class IC92MemoryFrame(IC92Frame):
+    """A frame for communicating memory information"""
     def __init__(self):
         IC92Frame.__init__(self, 0, DV_MEM_LEN)
 
@@ -284,21 +301,24 @@
             self._map.truncate(MEM_LEN + 4)
 
     def set_iscall(self, iscall):
+        """This frame refers to a call channel if @iscall is True"""
         if iscall:
             self[0] = 2
         else:
             self[0] = 1
 
     def get_iscall(self):
+        """Return True if this frame refers to a call channel"""
         return ord(self[0]) == 2
 
     def set_memory(self, mem):
+        """Take Memory object @mem and configure the frame accordingly"""
         if mem.number < 0:
             self.set_iscall(True)
             mem.number = abs(mem.number) - 1
             print "Memory is %i (call %s)" % (mem.number, self.get_iscall())
 
-        _mem = bitwise.parse(memory_frame_format, self).mem
+        _mem = bitwise.parse(MEMORY_FRAME_FORMAT, self).mem
 
         _mem.number = mem.number
 
@@ -329,7 +349,8 @@
             _mem.digital_code = mem.dv_code
 
     def get_memory(self):
-        _mem = bitwise.parse(memory_frame_format, self).mem
+        """Return a Memory object based on the contents of the frame"""
+        _mem = bitwise.parse(MEMORY_FRAME_FORMAT, self).mem
 
         if MODES[_mem.mode] == "DV":
             mem = IC9xDVMemory()
@@ -372,74 +393,55 @@
 
         return mem
 
-def print_frames(frames):
-    count = 0
-    for i in frames:
-        print "Frame %i:" % count
-        print i
-        count += 1
-
 def _send_magic_4800(pipe):
     cmd = "\x01\x80\x19"
     magic = ("\xFE" * 25) + cmd
-    for i in [0,1]:
-        r = ic9x_send(pipe, magic)
-        if r:
-            return r[0].get_raw()[0] == "\x80"
-    return r and r[0].get_raw()[:3] == rsp
+    for _i in [0, 1]:
+        resp = ic9x_send(pipe, magic)
+        if resp:
+            return resp[0].get_raw()[0] == "\x80"
+    return True
 
 def _send_magic_38400(pipe):
     cmd = "\x01\x80\x19"
-    rsp = "\x80\x01\x19"
+    #rsp = "\x80\x01\x19"
     magic = ("\xFE" * 400) + cmd
-    for i in [0,1]:
-        r = ic9x_send(pipe, magic)
-        if r:
-            return r[0].get_raw()[0] == "\x80"
+    for _i in [0, 1]:
+        resp = ic9x_send(pipe, magic)
+        if resp:
+            return resp[0].get_raw()[0] == "\x80"
     return False
 
 def send_magic(pipe):
+    """Send the magic incantation to wake up an ic9x radio"""
     if pipe.getBaudrate() == 38400:
-        r = _send_magic_38400(pipe)
-        if r:
+        resp = _send_magic_38400(pipe)
+        if resp:
             return
         print "Switching from 38400 to 4800"
         pipe.setBaudrate(4800)
-        r = _send_magic_4800(pipe)
+        resp = _send_magic_4800(pipe)
         pipe.setBaudrate(38400)
-        if r:
+        if resp:
             return
         raise errors.RadioError("Radio not responding")
     elif pipe.getBaudrate() == 4800:
-        r = _send_magic_4800(pipe)
-        if r:
+        resp = _send_magic_4800(pipe)
+        if resp:
             return
         print "Switching from 4800 to 38400"
         pipe.setBaudrate(38400)
-        r = _send_magic_38400(pipe)
-        if r:
+        resp = _send_magic_38400(pipe)
+        if resp:
             return
         pipe.setBaudrate(4800)
         raise errors.RadioError("Radio not responding")
     else:
-        raise errors.InvalidDataError("Radio in unknown state (%i)" % r.getBaudrate())    
-
-def print_banks(pipe):
-    frames = send(pipe, "\x01\x80\x1a\x09") # Banks
-
-    print "A Banks:"
-    for i in range(180, 180+26):
-        bf = IC92BankFrame()
-        bf.from_frame(frames[i])
-        print str(bf)
-
-    print "B Banks:"
-    for i in range(237, 237+26):
-        bf = IC92BankFrame()
-        bf.from_frame(frames[i])
-        print str(bf)
+        raise errors.InvalidDataError("Radio in unknown state (%i)" % \
+                                          pipe.getBaudrate())    
 
 def get_memory_frame(pipe, vfo, number):
+    """Get the memory frame for @vfo and @number via @pipe"""
     if number < 0:
         number = abs(number + 1)
         call = True
@@ -452,6 +454,7 @@
     return frame.send(pipe)
 
 def get_memory(pipe, vfo, number):
+    """Get a memory object for @vfo and @number via @pipe"""
     rframe = get_memory_frame(pipe, vfo, number)
 
     if len(rframe.get_payload()) < 1:
@@ -466,6 +469,7 @@
     return mf.get_memory()
 
 def set_memory(pipe, vfo, memory):
+    """Set memory @memory on @vfo via @pipe"""
     frame = IC92MemoryFrame()
     frame.set_memory(memory)
     frame.set_vfo(vfo)
@@ -480,6 +484,7 @@
                                           util.hexprint(rframe.get_payload()))
 
 def erase_memory(pipe, vfo, number):
+    """Erase memory @number on @vfo via @pipe"""
     frame = IC92MemClearFrame(number)
     frame.set_vfo(vfo)
 
@@ -488,6 +493,7 @@
         raise errors.InvalidDataError("Radio reported error")
 
 def get_banks(pipe, vfo):
+    """Get banks for @vfo via @pipe"""
     frame = IC92GetBankFrame()
     frame.set_vfo(vfo)
 
@@ -509,6 +515,7 @@
     return banks
 
 def set_banks(pipe, vfo, banks):
+    """Set banks for @vfo via @pipe"""
     for i in range(0, 26):
         bframe = IC92BankFrame()
         bframe.set_vfo(vfo)
@@ -520,6 +527,7 @@
             raise errors.InvalidDataError("Radio reported error")
 
 def get_call(pipe, cstype, number):
+    """Get @cstype callsign @number via @pipe"""
     cframe = IC92GetCallsignFrame(cstype.command, number)
     cframe.set_vfo(2)
     rframe = cframe.send(pipe)
@@ -530,28 +538,10 @@
     return cframe.get_callsign()
 
 def set_call(pipe, cstype, number, call):
+    """Set @cstype @call at position @number via @pipe"""
     cframe = cstype(number, call)
     cframe.set_vfo(2)
     rframe = cframe.send(pipe)
 
     if rframe.get_payload() != "\xfb":
         raise errors.RadioError("Radio reported error")
-
-def print_memory(pipe, vfo, number):
-    if vfo not in [1, 2]:
-        raise errors.InvalidValueError("VFO must be 1 or 2")
-
-    if number < 0 or number > 399:
-        raise errors.InvalidValueError("Number must be between 0 and 399")
-
-    mf = get_memory(pipe, vfo, number)
-
-    print "Memory %i from VFO %i: %s" % (number, vfo, str(mf))
-
-if __name__ == "__main__":
-    print util.hexprint(util.bcd_encode(1072))
-    print util.hexprint(util.bcd_encode(146900000, False))
-    print util.hexprint(util.bcd_encode(25, width=4))
-    print util.hexprint(util.bcd_encode(5000000, False, 6))
-    print util.hexprint(util.bcd_encode(600000, False, 6))
-    
diff -r db82df47f205 -r f805c420592f chirp/icf.py
--- a/chirp/icf.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/icf.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,21 +13,20 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-
 import struct
 import re
 
 from chirp import chirp_common, errors, util, memmap
-from chirp import ic9x_ll # for magic; may need to move later
 
 CMD_CLONE_OUT = 0xE2
 CMD_CLONE_IN  = 0xE3
 CMD_CLONE_DAT = 0xE4
-CMD_CLONE_END = 0xE5
+CMD_CLONE_END = 0xE5 
 
-save_pipe = None
+SAVE_PIPE = None
 
 class IcfFrame:
+    """A single ICF communication frame"""
     src = 0
     dst = 0
     cmd = 0
@@ -53,6 +52,7 @@
         pass
 
 def parse_frame_generic(data):
+    """Parse an ICF frame of unknown type from the beginning of @data"""
     frame = IcfFrame()
 
     frame.src = ord(data[2])
@@ -69,6 +69,7 @@
     return frame, data[end+1:]
 
 class RadioStream:
+    """A class to make reading a stream of IcfFrames easier"""
     def __init__(self, pipe):
         self.pipe = pipe
         self.data = ""
@@ -105,6 +106,7 @@
         return frames
 
     def get_frames(self, nolimit=False):
+        """Read any pending frames from the stream"""
         while True:
             _data = self.pipe.read(64)
             if not _data:
@@ -114,7 +116,7 @@
 
             if not nolimit and len(self.data) > 128 and "\xFD" in self.data:
                 break # Give us a chance to do some status
-            if len(data) > 1024:
+            if len(_data) > 1024:
                 break # Avoid an endless loop of chewing garbage
 
         if not self.data:
@@ -122,8 +124,9 @@
 
         return self._process_frames()
 
-def get_model_data(pipe, model="\x00\x00\x00\x00"):
-    send_clone_frame(pipe, 0xe0, model, raw=True)
+def get_model_data(pipe, mdata="\x00\x00\x00\x00"):
+    """Query the radio connected to @pipe for its model data"""
+    send_clone_frame(pipe, 0xe0, mdata, raw=True)
     
     stream = RadioStream(pipe)
     frames = stream.get_frames()
@@ -134,7 +137,10 @@
     return frames[0].payload
 
 def get_clone_resp(pipe, length=None):
+    """Read the response to a clone frame"""
     def exit_criteria(buf, length):
+        """Stop reading a clone response if we have enough data or encounter
+        the end of a frame"""
         if length is None:
             return buf.endswith("\xfd")
         else:
@@ -147,6 +153,8 @@
     return resp
 
 def send_clone_frame(pipe, cmd, data, raw=False, checksum=False):
+    """Send a clone frame with @cmd and @data to the radio attached
+    to @pipe"""
     cs = 0
 
     if raw:
@@ -166,9 +174,9 @@
 
     frame = "\xfe\xfe\xee\xef%s%s%s\xfd" % (chr(cmd), hed, cs)
 
-    if save_pipe:
+    if SAVE_PIPE:
         print "Saving data..."
-        save_pipe.write(frame)
+        SAVE_PIPE.write(frame)
 
     #print "Sending:\n%s" % util.hexprint(frame)
     #print "Sending:\n%s" % util.hexprint(hed[6:])
@@ -182,6 +190,7 @@
     return frame
 
 def process_bcd(bcddata):
+    """Convert BCD-encoded data to raw"""
     data = ""
     i = 0
     while i < range(len(bcddata)) and i+1 < len(bcddata):
@@ -195,36 +204,45 @@
 
     return data
 
-def process_data_frame(frame, mmap):
+def process_data_frame(frame, _mmap):
+    """Process a data frame, adding the payload to @_mmap"""
     _data = process_bcd(frame.payload)
-    if len(mmap) >= 0x10000:
+    if len(_mmap) >= 0x10000:
         saddr, = struct.unpack(">I", _data[0:4])
-        bytes, = struct.unpack("B", _data[4])
-        data = _data[5:5+bytes]
+        length, = struct.unpack("B", _data[4])
+        data = _data[5:5+length]
     else:
         saddr, = struct.unpack(">H", _data[0:2])
-        bytes, = struct.unpack("B", _data[2])
-        data = _data[3:3+bytes]
+        length, = struct.unpack("B", _data[2])
+        data = _data[3:3+length]
 
     try:
-        mmap[saddr] = data
+        _mmap[saddr] = data
     except IndexError:
-        print "Error trying to set %i bytes at %05x (max %05x)" %\
-            (bytes, saddr, len(mmap))
-    return saddr, saddr + bytes
+        print "Error trying to set %i bytes at %05x (max %05x)" % \
+            (bytes, saddr, len(_mmap))
+    return saddr, saddr + length
 
 def start_hispeed_clone(radio, cmd):
-    buf = ("\xFE" * 20) + "\xEE\xEF\xE8" + radio._model + "\x00\x00\x02\x01\xFD"
+    """Send the magic incantation to the radio to go fast"""
+    buf = ("\xFE" * 20) + \
+        "\xEE\xEF\xE8" + \
+        radio.get_model() + \
+        "\x00\x00\x02\x01\xFD"
     print "Starting HiSpeed:\n%s" % util.hexprint(buf)
     radio.pipe.write(buf)
     radio.pipe.flush()
-    r = radio.pipe.read(128)
-    print "Response:\n%s" % util.hexprint(r)
+    resp = radio.pipe.read(128)
+    print "Response:\n%s" % util.hexprint(resp)
 
     print "Switching to 38400 baud"
     radio.pipe.setBaudrate(38400)
 
-    buf = ("\xFE" * 14) + "\xEE\xEF" + chr(cmd) + radio._model[:3] + "\x00\xFD"
+    buf = ("\xFE" * 14) + \
+        "\xEE\xEF" + \
+        chr(cmd) + \
+        radio.get_model()[:3] + \
+        "\x00\xFD"
     print "Starting HiSpeed Clone:\n%s" % util.hexprint(buf)
     radio.pipe.write(buf)
     radio.pipe.flush()
@@ -247,7 +265,7 @@
     stream = RadioStream(radio.pipe)
 
     addr = 0
-    mmap = memmap.MemoryMap(chr(0x00) * radio._memsize)
+    _mmap = memmap.MemoryMap(chr(0x00) * radio.get_memsize())
     last_size = 0
     while True:
         frames = stream.get_frames()
@@ -256,7 +274,7 @@
 
         for frame in frames:
             if frame.cmd == CMD_CLONE_DAT:
-                src, dst = process_data_frame(frame, mmap)
+                src, dst = process_data_frame(frame, _mmap)
                 if last_size != (dst - src):
                     print "ICF Size change from %i to %i at %04x" % (last_size,
                                                                      dst - src,
@@ -276,16 +294,18 @@
             status.cur = addr
             radio.status_fn(status)
 
-    return mmap
+    return _mmap
 
 def clone_from_radio(radio):
+    """Do a full clone out of the radio's memory"""
     try:
         return _clone_from_radio(radio)
     except Exception, e:
         raise errors.RadioError("Failed to communicate with the radio: %s" % e)
 
 def send_mem_chunk(radio, start, stop, bs=32):
-    mmap = radio.get_mmap()
+    """Send a single chunk of the radio's memory from @start- at stop"""
+    _mmap = radio.get_mmap()
 
     status = chirp_common.Status()
     status.msg = "Cloning to radio"
@@ -297,11 +317,11 @@
         else:
             size = stop - i
 
-        if radio._memsize >= 0x10000:
+        if radio.get_memsize() >= 0x10000:
             chunk = struct.pack(">IB", i, size)
         else:
             chunk = struct.pack(">HB", i, size)
-        chunk += mmap[i:i+size]
+        chunk += _mmap[i:i+size]
 
         send_clone_frame(radio.pipe,
                          CMD_CLONE_DAT,
@@ -315,10 +335,10 @@
     return True
 
 def _clone_to_radio(radio):
-    global save_pipe
+    global SAVE_PIPE
 
     # Uncomment to save out a capture of what we actually write to the radio
-    # save_pipe = file("pipe_capture.log", "w", 0)
+    # SAVE_PIPE = file("pipe_capture.log", "w", 0)
 
     md = get_model_data(radio.pipe)
 
@@ -347,9 +367,9 @@
     send_clone_frame(radio.pipe, CMD_CLONE_END, radio.get_endframe(), raw=True)
     frames += stream.get_frames(True)
 
-    if save_pipe:
-        save_pipe.close()
-        save_pipe = None
+    if SAVE_PIPE:
+        SAVE_PIPE.close()
+        SAVE_PIPE = None
 
     try:
         result = frames[-1]
@@ -359,21 +379,24 @@
     return result.payload[0] == '\x00'
 
 def clone_to_radio(radio):
+    """Initiate a full memory clone out to @radio"""
     try:
         return _clone_to_radio(radio)
     except Exception, e:
         raise errors.RadioError("Failed to communicate with the radio: %s" % e)
 
 def convert_model(mod_str):
+    """Convert an ICF-style model string into what we get from the radio"""
     data = ""
     for i in range(0, len(mod_str), 2):
-        hex = mod_str[i:i+2]
-        val = int(hex, 16)
-        data += chr(val)
+        hexval = mod_str[i:i+2]
+        intval = int(hexval, 16)
+        data += chr(intval)
 
     return data
 
 def convert_data_line(line):
+    """Convert an ICF data line to raw memory format"""
     if line.startswith("#"):
         return ""
 
@@ -381,12 +404,10 @@
 
     if len(line) == 38:
         # Small memory (< 0x10000)
-        pos = int(line[0:4], 16)
         size = int(line[4:6], 16)
         data = line[6:]
     else:
         # Large memory (>= 0x10000)
-        pos = int(line[0:8], 16)
         size = int(line[8:10], 16)
         data = line[10:]
 
@@ -404,6 +425,7 @@
     return _mmap
 
 def read_file(filename):
+    """Read an ICF file and return the model string and memory data"""
     f = file(filename)
 
     mod_str = f.readline()
@@ -419,6 +441,7 @@
     return model, memmap.MemoryMap(_mmap)
 
 def is_9x_icf(filename):
+    """Returns True if @filename is an IC9x ICF file"""
     f = file(filename)
     mdata = f.read(8)
     f.close()
@@ -426,6 +449,7 @@
     return mdata in ["30660000", "28880000"]
 
 def is_icf_file(filename):
+    """Returns True if @filename is an ICF file"""
     f = file(filename)
     data = f.readline()
     data += f.readline()
@@ -436,10 +460,17 @@
     return bool(re.match("^[0-9]{8}#", data))
 
 class IcomBank(chirp_common.Bank):
+    """A bank that works for all Icom radios"""
     # Integral index of the bank (not to be confused with per-memory
     # bank indexes
     index = 0
 
+class IcomNamedBank(IcomBank):
+    """A bank with an adjustable name"""
+    def set_name(self, name):
+        """Set the name of the bank"""
+        pass
+
 class IcomBankModel(chirp_common.BankModel):
     """Icom radios all have pretty much the same simple bank model. This
     central implementation can, with a few icom-specific radio interfaces
@@ -483,6 +514,7 @@
             return [self.get_banks()[index]]
     
 class IcomIndexedBankModel(IcomBankModel, chirp_common.BankIndexInterface):
+    """Generic bank model for Icom radios with indexed banks"""
     def get_index_bounds(self):
         return self._radio._bank_index_bounds
 
@@ -512,6 +544,7 @@
         
 
 class IcomCloneModeRadio(chirp_common.CloneModeRadio):
+    """Base class for Icom clone-mode radios"""
     VENDOR = "Icom"
     BAUDRATE = 9600
 
@@ -523,17 +556,25 @@
     _bank_class = IcomBank
     _can_hispeed = False
 
-    def is_hispeed(self):
-        return self._can_hispeed
+    @classmethod
+    def is_hispeed(cls):
+        """Returns True if the radio supports hispeed cloning"""
+        return cls._can_hispeed
 
-    def get_model(self):
-        return self._model
+    @classmethod
+    def get_model(cls):
+        """Returns the Icom model data for this radio"""
+        return cls._model
 
-    def get_endframe(self):
-        return self._endframe
+    @classmethod
+    def get_endframe(cls):
+        """Returns the magic clone end frame for this radio"""
+        return cls._endframe
 
-    def get_ranges(self):
-        return self._ranges
+    @classmethod
+    def get_ranges(cls):
+        """Returns the ranges this radio likes to have in a clone"""
+        return cls._ranges
 
     def sync_in(self):
         self._mmap = clone_from_radio(self)
@@ -563,6 +604,7 @@
         raise Exception("Not implemented")
 
 class IcomLiveRadio(chirp_common.LiveRadio):
+    """Base class for an Icom Live-mode radio"""
     VENDOR = "Icom"
     BAUD_RATE = 38400
 
@@ -579,14 +621,3 @@
                 return IcomBankModel(self)
         else:
             return None
-
-if __name__ == "__main__":
-    import sys
-
-    model, mmap = read_file(sys.argv[1])
-
-    print util.hexprint(model)
-
-    f = file("out.img", "w")
-    f.write(mmap.get_packed())
-    f.close()
diff -r db82df47f205 -r f805c420592f chirp/icomciv.py
--- a/chirp/icomciv.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/icomciv.py	Fri Apr 27 14:35:41 2012 -0700
@@ -1,18 +1,18 @@
 
 import struct
-from chirp import chirp_common, icf, util, errors, bitwise, ic9x_ll, directory
+from chirp import chirp_common, icf, util, errors, bitwise, directory
 from chirp.memmap import MemoryMap
 
 DEBUG = True
 
-mem_format = """
+MEM_FORMAT = """
 bbcd number[2];
 u8   unknown1;
 lbcd freq[5];
 u8   unknown2:5,
      mode:3;
 """
-mem_vfo_format = """
+MEM_VFO_FORMAT = """
 u8   vfo;
 bbcd number[2];
 u8   unknown1;
@@ -35,6 +35,7 @@
 """
 
 class Frame:
+    """Base class for an ICF frame"""
     _cmd = 0x00
     _sub = 0x00
 
@@ -42,16 +43,20 @@
         self._data = ""
 
     def set_command(self, cmd, sub):
+        """Set the command number (and optional subcommand)"""
         self._cmd = cmd
         self._sub = sub
 
     def get_data(self):
+        """Return the data payload"""
         return self._data
 
     def set_data(self, data):
+        """Set the data payload"""
         self._data = data
 
     def send(self, src, dst, serial, willecho=True):
+        """Send the frame over @serial, using @src and @dst addresses"""
         raw = struct.pack("BBBBBB", 0xFE, 0xFE, src, dst, self._cmd, self._sub)
         raw += str(self._data) + chr(0xFD)
 
@@ -68,13 +73,14 @@
                 print util.hexprint(echo)
 
     def read(self, serial):
+        """Read the frame from @serial"""
         data = ""
         while not data.endswith(chr(0xFD)):
-            c = serial.read(1)
-            if not c:
+            char = serial.read(1)
+            if not char:
                 print "Read %i bytes total" % len(data)
                 raise errors.RadioError("Timeout")
-            data += c
+            data += char
 
         if data == chr(0xFD):
             raise errors.RadioError("Radio reported error")
@@ -90,39 +96,49 @@
         return src, dst
 
 class MemFrame(Frame):
+    """A memory frame"""
     _cmd = 0x1A
     _sub = 0x00
     _loc = 0
 
     def set_location(self, loc):
+        """Set the memory location number"""
         self._loc = loc
         self._data = struct.pack(">H", int("%04i" % loc, 16))
 
     def make_empty(self):
+        """Mark as empty so the radio will erase the memory"""
         self._data = struct.pack(">HB", int("%04i" % self._loc, 16), 0xFF)
 
     def is_empty(self):
+        """Return True if memory is marked as empty"""
         return len(self._data) < 5
 
     def get_obj(self):
+        """Return a bitwise parsed object"""
         self._data = MemoryMap(str(self._data)) # Make sure we're assignable
-        return bitwise.parse(mem_format, self._data)
+        return bitwise.parse(MEM_FORMAT, self._data)
 
     def initialize(self):
+        """Initialize to sane values"""
         self._data = MemoryMap("".join(["\x00"] * (self.get_obj().size() / 8)))
 
 class MultiVFOMemFrame(MemFrame):
+    """A memory frame for radios with multiple VFOs"""
     def set_location(self, loc, vfo=1):
         self._loc = loc
         self._data = struct.pack(">BH", vfo, int("%04i" % loc, 16))
 
     def get_obj(self):
         self._data = MemoryMap(str(self._data)) # Make sure we're assignable
-        return bitwise.parse(mem_vfo_format, self._data)
+        return bitwise.parse(MEM_VFO_FORMAT, self._data)
 
 class IcomCIVRadio(icf.IcomLiveRadio):
+    """Base class for ICOM CIV-based radios"""
     BAUD_RATE = 19200
     MODEL = "CIV Radio"
+    _model = "\x00"
+    _template = 0
 
     def _send_frame(self, frame):
         return frame.send(ord(self._model), 0xE0, self.pipe,
@@ -140,9 +156,9 @@
     def _detect_echo(self):
         echo_test = "\xfe\xfe\xe0\xe0\xfa\xfd"
         self.pipe.write(echo_test)
-        r = self.pipe.read(6)
-        print "Echo:\n%s" % util.hexprint(r)
-        return r == echo_test
+        resp = self.pipe.read(6)
+        print "Echo:\n%s" % util.hexprint(resp)
+        return resp == echo_test
 
     def __init__(self, *args, **kwargs):
         icf.IcomLiveRadio.__init__(self, *args, **kwargs)
@@ -256,6 +272,7 @@
 
 @directory.register
 class Icom7200Radio(IcomCIVRadio):
+    """Icom IC-7200"""
     MODEL = "7200"
     _model = "\x76"
     _template = 201
@@ -277,6 +294,7 @@
 
 @directory.register
 class Icom7000Radio(IcomCIVRadio):
+    """Icom IC-7000"""
     MODEL = "7000"
     _model = "\x70"
     _template = 102
@@ -305,14 +323,15 @@
     (0x70, 0xE0) : Icom7000Radio,
 }
 
-def probe_model(s):
+def probe_model(ser):
+    """Probe the radio attatched to @ser for its model"""
     f = Frame()
     f.set_command(0x19, 0x00)
 
     for model, controller in CIV_MODELS.keys():
-        f.send(model, controller, s)
+        f.send(model, controller, ser)
         try:
-            f.read(s)
+            f.read(ser)
         except errors.RadioError:
             continue
 
diff -r db82df47f205 -r f805c420592f chirp/icq7.py
--- a/chirp/icq7.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/icq7.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,12 +13,11 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from chirp import chirp_common, icf, errors, util, directory
+from chirp import chirp_common, icf, directory
 from chirp import bitwise
-from chirp.memmap import MemoryMap
 from chirp.chirp_common import to_GHz, from_GHz
 
-mem_format = """
+MEM_FORMAT = """
 struct {
   bbcd freq[3];
   u8  fractional:1,
@@ -49,6 +48,7 @@
 
 @directory.register
 class ICQ7Radio(icf.IcomCloneModeRadio):
+    """Icom IC-Q7A"""
     VENDOR = "Icom"
     MODEL = "IC-Q7A"
 
@@ -76,7 +76,7 @@
         return rf
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_raw_memory(self, number):
         return repr(self._memobj.memory[number])
diff -r db82df47f205 -r f805c420592f chirp/ict70.py
--- a/chirp/ict70.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/ict70.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,11 +13,10 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from chirp import chirp_common, icf, errors, util, directory
+from chirp import chirp_common, icf, directory
 from chirp import bitwise
-from chirp.memmap import MemoryMap
 
-mem_format = """
+MEM_FORMAT = """
 struct {
   u24 freq;
   ul16 offset;
@@ -71,6 +70,7 @@
                 ]
 
 class ICT70Bank(icf.IcomBank):
+    """ICT70 bank"""
     def get_name(self):
         _bank = self._model._radio._memobj.bank_names[self.index]
         return str(_bank.name).rstrip()
@@ -81,6 +81,7 @@
 
 @directory.register
 class ICT70Radio(icf.IcomCloneModeRadio):
+    """Icom IC-T70"""
     VENDOR = "Icom"
     MODEL = "IC-T70"
 
@@ -133,7 +134,7 @@
         return rf
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_raw_memory(self, number):
         return repr(self._memobj.memory[number])
diff -r db82df47f205 -r f805c420592f chirp/icw32.py
--- a/chirp/icw32.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/icw32.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,10 +13,10 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from chirp import chirp_common, icf, errors, util, directory
+from chirp import chirp_common, icf, util, directory
 from chirp import bitwise
 
-mem_format = """
+MEM_FORMAT = """
 #seekto 0x%x;
 struct {
   bbcd freq[3];
@@ -61,8 +61,16 @@
 DUPLEX = ["", "", "-", "+"]
 TONE = ["", "", "Tone", "TSQL"]
 
+def _get_special():
+    special = {}
+    for i in range(0, 5):
+        special["M%iA" % (i+1)] = 100 + i*2
+        special["M%iB" % (i+1)] = 100 + i*2 + 1
+    return special            
+
 @directory.register
 class ICW32ARadio(icf.IcomCloneModeRadio):
+    """Icom IC-W32A"""
     VENDOR = "Icom"
     MODEL = "IC-W32A"
 
@@ -97,26 +105,18 @@
         return rf
 
     def process_mmap(self):
-        format = mem_format % self._mem_positions
-        self._memobj = bitwise.parse(format, self._mmap)
+        fmt = MEM_FORMAT % self._mem_positions
+        self._memobj = bitwise.parse(fmt, self._mmap)
 
     def get_raw_memory(self, number):
         return repr(self._memobj.memory[number])
 
-    def _get_special(self):
-        special = {}
-        for i in range(0, 5):
-            special["M%iA" % (i+1)] = 100 + i*2
-            special["M%iB" % (i+1)] = 100 + i*2 + 1
-
-        return special            
-
     def get_special_locations(self):
-        return sorted(self._get_special().keys())
+        return sorted(_get_special().keys())
 
     def get_memory(self, number):
         if isinstance(number, str):
-            number = self._get_special()[number]
+            number = _get_special()[number]
 
         _mem = self._memobj.memory[number]
         _flg = self._memobj.flag[number]
@@ -129,7 +129,7 @@
             mem.skip = _flg.skip and "S" or ""
         else:
             # Special memories
-            mem.extd_number = util.get_dict_rev(self._get_special(), number)
+            mem.extd_number = util.get_dict_rev(_get_special(), number)
 
         if _flg.empty:
             mem.empty = True
@@ -190,11 +190,13 @@
         return filedata[-16:] == "IcomCloneFormat3"
 
 class ICW32ARadioVHF(ICW32ARadio):
+    """ICW32 VHF subdevice"""
     VARIANT = "VHF"
     _limits = (118000000, 174000000)
     _mem_positions = (0x0000, 0x0DC0)
 
 class ICW32ARadioUHF(ICW32ARadio):
+    """ICW32 UHF subdevice"""
     VARIANT = "UHF"
     _limits = (400000000, 470000000)
     _mem_positions = (0x06E0, 0x0E2E)
diff -r db82df47f205 -r f805c420592f chirp/icx8x.py
--- a/chirp/icx8x.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/icx8x.py	Fri Apr 27 14:35:41 2012 -0700
@@ -15,7 +15,7 @@
 
 from chirp import chirp_common, icf, icx8x_ll, errors, directory
 
-def isUHF(pipe):
+def _isuhf(pipe):
     try:
         md = icf.get_model_data(pipe)
         val = ord(md[20])
@@ -29,6 +29,7 @@
 
 @directory.register
 class ICx8xRadio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport):
+    """Icom IC-V/U82"""
     VENDOR = "Icom"
     MODEL = "IC-V82/U82"
 
@@ -69,7 +70,7 @@
         rf.valid_duplexes = ["", "-", "+"]
         rf.valid_tuning_steps = [x for x in chirp_common.TUNING_STEPS
                                  if x != 6.25]
-        if self.isUHF:
+        if self._isuhf:
             rf.valid_bands = [(420000000, 470000000)]
         else:
             rf.valid_bands = [(118000000, 176000000)]
@@ -78,12 +79,12 @@
         return rf
 
     def _get_type(self):
-        flag = (isUHF(self.pipe) != 0)
+        flag = (_isuhf(self.pipe) != 0)
 
-        if self.isUHF is not None and (self.isUHF != flag):
+        if self._isuhf is not None and (self._isuhf != flag):
             raise errors.RadioError("VHF/UHF model mismatch")
 
-        self.isUHF = flag
+        self._isuhf = flag
 
         return flag
 
@@ -95,15 +96,15 @@
         # file, look for the flag.  If we're syncing from serial, set
         # that flag.
         if isinstance(pipe, str):
-            self.isUHF = (ord(self._mmap[0x1930]) != 0)
+            self._isuhf = (ord(self._mmap[0x1930]) != 0)
             #print "Found %s image" % (self.isUHF and "UHF" or "VHF")
         else:
-            self.isUHF = None
+            self._isuhf = None
 
     def sync_in(self):
         self._get_type()
         icf.IcomCloneModeRadio.sync_in(self)
-        self._mmap[0x1930] = self.isUHF and 1 or 0
+        self._mmap[0x1930] = self._isuhf and 1 or 0
 
     def sync_out(self):
         self._get_type()
@@ -116,7 +117,7 @@
         if not self._mmap:
             self.sync_in()
 
-        if self.isUHF:
+        if self._isuhf:
             base = 400
         else:
             base = 0
@@ -134,7 +135,7 @@
         if not self._mmap:
             self.sync_in()
 
-        if self.isUHF:
+        if self._isuhf:
             base = 400
         else:
             base = 0
diff -r db82df47f205 -r f805c420592f chirp/id31.py
--- a/chirp/id31.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/id31.py	Fri Apr 27 14:35:41 2012 -0700
@@ -15,7 +15,7 @@
 
 from chirp import directory, icf, bitwise, chirp_common
 
-mem_format = """
+MEM_FORMAT = """
 struct {
   u24 freq;
   u16 offset;
@@ -111,7 +111,6 @@
 
 def _encode_call(call):
     _call = [0x00] * 7
-    mask = 0
     for i in range(0, 7):
         val = ord(call[i]) << (i + 1)
         if i > 0:
@@ -121,7 +120,32 @@
         
     return _call
 
+def _get_freq(_mem):
+    freq = int(_mem.freq)
+    offs = int(_mem.offset)
+
+    if freq & 0x00200000:
+        mult = 6250
+    else:
+        mult = 5000
+
+    freq &= 0x0003FFFF
+
+    return (freq * mult), (offs * mult)
+
+def _set_freq(_mem, freq, offset):
+    if chirp_common.is_fractional_step(freq):
+        mult = 6250
+        flag = 0x00200000
+    else:
+        mult = 5000
+        flag = 0x00000000
+
+    _mem.freq = (freq / mult) | flag
+    _mem.offset = (offset / mult)
+
 class ID31Bank(icf.IcomBank):
+    """A ID-31 Bank"""
     def get_name(self):
         _banks = self._model._radio._memobj.bank_names
         return str(_banks[self.index].name).rstrip()
@@ -132,6 +156,7 @@
 
 @directory.register
 class ID31Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport):
+    """Icom ID-31"""
     MODEL = "ID-31A"
 
     _memsize = 0x15500
@@ -179,35 +204,11 @@
         return rf
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_raw_memory(self, number):
         return repr(self._memobj.memory[number])
 
-    def _get_freq(self, _mem):
-        freq = int(_mem.freq)
-        offs = int(_mem.offset)
-
-        if freq & 0x00200000:
-            mult = 6250
-        else:
-            mult = 5000
-
-        freq &= 0x0003FFFF
-
-        return (freq * mult), (offs * mult)
-
-    def _set_freq(self, _mem, freq, offset):
-        if chirp_common.is_fractional_step(freq):
-            mult = 6250
-            flag = 0x00200000
-        else:
-            mult = 5000
-            flag = 0x00000000
-
-        _mem.freq = (freq / mult) | flag
-        _mem.offset = (offset / mult)
-
     def get_memory(self, number):
         _mem = self._memobj.memory[number]
         _usd = self._memobj.used_flags[number / 8]
@@ -226,7 +227,7 @@
             mem.empty = True
             return mem
 
-        mem.freq, mem.offset = self._get_freq(_mem)
+        mem.freq, mem.offset = _get_freq(_mem)
         mem.name = str(_mem.name).rstrip()
         mem.rtone = chirp_common.TONES[_mem.rtone]
         mem.ctone = chirp_common.TONES[_mem.ctone]
@@ -261,7 +262,7 @@
 
         bit = (1 << (memory.number % 8))
 
-        self._set_freq(_mem, memory.freq, memory.offset)
+        _set_freq(_mem, memory.freq, memory.offset)
         _mem.name = memory.name.ljust(12)[:12]
         _mem.rtone = chirp_common.TONES.index(memory.rtone)
         _mem.ctone = chirp_common.TONES.index(memory.ctone)
@@ -308,10 +309,8 @@
 
     def get_repeater_call_list(self):
         calls = []
-        i = 0
         for rptcall in self._memobj.rptcall:
             call = _decode_call(rptcall.call)
-            i += 1
             if call.rstrip() and not call == "CALLSIGN":
                 calls.append(call)
         for repeater in self._memobj.repeaters:
diff -r db82df47f205 -r f805c420592f chirp/id800.py
--- a/chirp/id800.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/id800.py	Fri Apr 27 14:35:41 2012 -0700
@@ -16,7 +16,7 @@
 from chirp import chirp_common, icf, errors, directory
 from chirp import bitwise
 
-mem_format = """
+MEM_FORMAT = """
 #seekto 0x0020;
 struct {
   u24 freq;
@@ -104,8 +104,50 @@
 ALPHA_CHARSET = " ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 NUMERIC_CHARSET = "0123456789+-=*/()|"
 
+def get_name(_mem):
+    """Decode the name from @_mem"""
+    def _get_char(val):
+        if val == 0:
+            return " "
+        elif val & 0x20:
+            return ALPHA_CHARSET[val & 0x1F]
+        else:
+            return NUMERIC_CHARSET[val & 0x0F]
+
+    name_bytes = [_mem.name1, _mem.name2, _mem.name3,
+                  _mem.name4, _mem.name5, _mem.name6]
+    name = ""
+    for val in name_bytes:
+        name += _get_char(val)
+
+    return name.rstrip()
+
+def set_name(_mem, name):
+    """Encode @name in @_mem"""
+    def _get_index(char):
+        if char == " ":
+            return 0
+        elif char.isalpha():
+            return ALPHA_CHARSET.index(char) | 0x20
+        else:
+            return NUMERIC_CHARSET.index(char) | 0x10
+
+    name = name.ljust(6)[:6]
+
+    _mem.usealpha = bool(name.strip())
+
+    # The element override calling convention makes this harder to automate.
+    # It's just six, so do it manually
+    _mem.name1 = _get_index(name[0])
+    _mem.name2 = _get_index(name[1])
+    _mem.name3 = _get_index(name[2])
+    _mem.name4 = _get_index(name[3])
+    _mem.name5 = _get_index(name[4])
+    _mem.name6 = _get_index(name[5])
+
 @directory.register
 class ID800v2Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport):
+    """Icom ID800"""
     VENDOR = "Icom"
     MODEL = "ID-800H"
     VARIANT = "v2"
@@ -186,50 +228,11 @@
         return rf
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_special_locations(self):
         return sorted(ID800_SPECIAL.keys())
 
-    def _get_name(self, _mem):
-        def get_char(val):
-            if val == 0:
-                return " "
-            elif val & 0x20:
-                return ALPHA_CHARSET[val & 0x1F]
-            else:
-                return NUMERIC_CHARSET[val & 0x0F]
-
-        name_bytes = [_mem.name1, _mem.name2, _mem.name3,
-                      _mem.name4, _mem.name5, _mem.name6]
-        name = ""
-        for val in name_bytes:
-            name += get_char(val)
-
-        return name.rstrip()
-
-    def _set_name(self, _mem, name):
-        def get_index(char):
-            if char == " ":
-                return 0
-            elif char.isalpha():
-                return ALPHA_CHARSET.index(char) | 0x20
-            else:
-                return NUMERIC_CHARSET.index(char) | 0x10
-
-        name = name.ljust(6)[:6]
-
-        _mem.usealpha = bool(name.strip())
-
-        # The element override calling convention makes this harder to automate.
-        # It's just six, so do it manually
-        _mem.name1 = get_index(name[0])
-        _mem.name2 = get_index(name[1])
-        _mem.name3 = get_index(name[2])
-        _mem.name4 = get_index(name[3])
-        _mem.name5 = get_index(name[4])
-        _mem.name6 = get_index(name[5])
-
     def get_memory(self, number):
         if isinstance(number, str):
             try:
@@ -268,7 +271,7 @@
         mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs]
         mem.dtcs_polarity = DTCS_POL[_mem.dtcs_polarity]
         mem.tuning_step = STEPS[_mem.tuning_step]
-        mem.name = self._get_name(_mem)
+        mem.name = get_name(_mem)
 
         mem.skip = _flg.pskip and "P" or _flg.skip and "S" or ""
 
@@ -295,7 +298,7 @@
         _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs)
         _mem.dtcs_polarity = DTCS_POL.index(mem.dtcs_polarity)
         _mem.tuning_step = STEPS.index(mem.tuning_step)
-        self._set_name(_mem, mem.name)
+        set_name(_mem, mem.name)
 
         _flg.pskip = mem.skip == "P"
         _flg.skip = mem.skip == "S"
diff -r db82df47f205 -r f805c420592f chirp/id880.py
--- a/chirp/id880.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/id880.py	Fri Apr 27 14:35:41 2012 -0700
@@ -16,7 +16,7 @@
 from chirp import chirp_common, icf, directory
 from chirp import bitwise
 
-mem_format = """
+MEM_FORMAT = """
 struct {
   u24  freq;
   u16  offset;
@@ -86,12 +86,13 @@
           100.0, 125.0, 200.0]
 
 def decode_call(sevenbytes):
+    """Decode a callsign from a packed region @sevenbytes"""
     if len(sevenbytes) != 7:
         raise Exception("%i (!=7) bytes to decode_call" % len(sevenbytes))
 
     i = 0
     rem = 0
-    str = ""
+    call = ""
     for byte in [ord(x) for x in sevenbytes]:
         i += 1
 
@@ -100,7 +101,7 @@
         code = (byte >> i) | rem      # Code gets the upper bits of remainder
                                       # plus all but the i lower bits of this
                                       # byte
-        str += chr(code)
+        call += chr(code)
 
         rem = (byte & mask) << 7 - i  # Remainder for next time are the masked
                                       # bits, moved to the high places for the
@@ -108,14 +109,13 @@
 
     # After seven trips gathering overflow bits, we chould have seven
     # left, which is the final character
-    str += chr(rem)
+    call += chr(rem)
 
-    return str.rstrip()
+    return call.rstrip()
 
 def encode_call(call):
+    """Encode @call into a 7-byte region"""
     call = call.ljust(8)
-    val = 0
-    
     buf = []
     
     for i in range(0, 8):
@@ -132,7 +132,33 @@
 
     return "".join([chr(x) for x in buf[:7]])
 
-class ID880Bank(icf.IcomBank):
+def _get_freq(_mem):
+    val = int(_mem.freq)
+
+    if val & 0x00200000:
+        mult = 6250
+    else:
+        mult = 5000
+
+    val &= 0x0003FFFF
+
+    return (val * mult)
+
+def _set_freq(_mem, freq):
+    if chirp_common.is_fractional_step(freq):
+        mult = 6250
+        flag = 0x00200000
+    else:
+        mult = 5000
+        flag = 0x00000000
+
+    _mem.freq = (freq / mult) | flag
+
+def _wipe_memory(mem, char):
+    mem.set_raw(char * (mem.size() / 8))
+
+class ID880Bank(icf.IcomNamedBank):
+    """ID880 Bank"""
     def get_name(self):
         _bank = self._model._radio._memobj.bank_names[self.index]
         return str(_bank.name).rstrip()
@@ -143,6 +169,7 @@
 
 @directory.register
 class ID880Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport):
+    """Icom ID880"""
     VENDOR = "Icom"
     MODEL = "ID-880H"
 
@@ -185,7 +212,7 @@
         _bank.index = index
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_features(self):
         rf = chirp_common.RadioFeatures()
@@ -208,28 +235,6 @@
     def get_raw_memory(self, number):
         return repr(self._memobj.memory[number])
 
-    def _get_freq(self, _mem):
-        val = int(_mem.freq)
-
-        if val & 0x00200000:
-            mult = 6250
-        else:
-            mult = 5000
-
-        val &= 0x0003FFFF
-
-        return (val * mult)
-
-    def _set_freq(self, _mem, freq):
-        if chirp_common.is_fractional_step(freq):
-            mult = 6250
-            flag = 0x00200000
-        else:
-            mult = 5000
-            flag = 0x00000000
-
-        _mem.freq = (freq / mult) | flag
-
     def get_memory(self, number):
         bytepos = number / 8
         bitpos = 1 << (number % 8)
@@ -263,7 +268,7 @@
             mem.empty = True
             return mem
 
-        mem.freq = self._get_freq(_mem)
+        mem.freq = _get_freq(_mem)
         mem.offset = (_mem.offset * 5) * 1000
         mem.rtone = chirp_common.TONES[_mem.rtone]
         mem.ctone = chirp_common.TONES[_mem.ctone]
@@ -280,9 +285,6 @@
 
         return mem
 
-    def _wipe_memory(self, mem, char):
-        mem.set_raw(char * (mem.size() / 8))
-
     def set_memory(self, mem):
         bitpos = (1 << (mem.number % 8))
         bytepos = mem.number / 8
@@ -295,16 +297,16 @@
 
         if mem.empty:
             _used |= bitpos
-            self._wipe_memory(_mem, "\xFF")
+            _wipe_memory(_mem, "\xFF")
             self._set_bank(mem.number, None)
             return
 
         _used &= ~bitpos
 
         if was_empty:
-            self._wipe_memory(_mem, "\x00")
+            _wipe_memory(_mem, "\x00")
 
-        self._set_freq(_mem, mem.freq)
+        _set_freq(_mem, mem.freq)
         _mem.offset = int((mem.offset / 1000) / 5)
         _mem.rtone = chirp_common.TONES.index(mem.rtone)
         _mem.ctone = chirp_common.TONES.index(mem.ctone)
@@ -359,7 +361,7 @@
         _calls = self._memobj.rptcall
         calls = ["*NOTUSE*"]
 
-        for i in range(*self.RPTCALL_LIMIT):
+        for _i in range(*self.RPTCALL_LIMIT):
             # FIXME: Not sure where the repeater list actually is
             calls.append("UNSUPRTD")
             continue
@@ -370,6 +372,7 @@
 # the ID-880. So, don't register right now
 #@directory.register
 class ID80Radio(ID880Radio):
+    """Icom ID80"""
     MODEL = "ID-80H"
 
     _model = "\x31\x55\x00\x01"
diff -r db82df47f205 -r f805c420592f chirp/idrp.py
--- a/chirp/idrp.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/idrp.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,16 +13,15 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import struct
 import serial
 
 from chirp import chirp_common, errors
-from chirp.memmap import MemoryMap
 from chirp import util
 
 DEBUG_IDRP = False
 
 def parse_frames(buf):
+    """Parse frames from the radio"""
     frames = []
 
     while "\xfe\xfe" in buf:
@@ -38,8 +37,9 @@
 
     return frames
 
-def send(pipe, buffer):
-    pipe.write("\xfe\xfe%s\xfd" % buffer)
+def send(pipe, buf):
+    """Send data in @buf to @pipe"""
+    pipe.write("\xfe\xfe%s\xfd" % buf)
     pipe.flush()
 
     data = ""
@@ -55,15 +55,18 @@
     return parse_frames(data)
 
 def send_magic(pipe):
+    """Send the magic wakeup call to @pipe"""
     send(pipe, ("\xfe" * 15) + "\x01\x7f\x19")
 
 def drain(pipe):
+    """Chew up any data waiting on @pipe"""
     while True:
         buf = pipe.read(4096)
         if not buf:
             break
 
 def set_freq(pipe, freq):
+    """Set the frequency of the radio on @pipe to @freq"""
     freqbcd = util.bcd_encode(freq, bigendian=False, width=9)
     buf = "\x01\x7f\x05" + freqbcd
 
@@ -78,6 +81,7 @@
     raise errors.InvalidDataError("Repeater reported error")
     
 def get_freq(pipe):
+    """Get the frequency of the radio attached to @pipe"""
     buf = "\x01\x7f\x1a\x09"
 
     drain(pipe)
@@ -103,10 +107,8 @@
                 "ctone", "dtcs", "tmode", "dtcs_polarity", "skip", "duplex",
                 "offset", "mode", "tuning_step", "bank_index"]
 
-class IcomRepeater(chirp_common.LiveRadio):
-    pass
-
-class IDRPx000V(IcomRepeater):
+class IDRPx000V(chirp_common.LiveRadio):
+    """Icom IDRP-*"""
     BAUD_RATE = 19200
     VENDOR = "Icom"
     MODEL = "ID-2000V/4000V/2D/2V"
@@ -154,7 +156,11 @@
 
         set_freq(self.pipe, mem.freq)
 
+def do_test():
+    """Get the frequency of /dev/icom"""
+    ser = serial.Serial(port="/dev/icom", baudrate=19200, timeout=0.5)
+    #set_freq(pipe, 439.920)
+    get_freq(ser)
+
 if __name__ == "__main__":
-    pipe = serial.Serial(port="/dev/icom", baudrate=19200, timeout=0.5)
-    #set_freq(pipe, 439.920)
-    get_freq(pipe)
+    do_test()
diff -r db82df47f205 -r f805c420592f chirp/import_logic.py
--- a/chirp/import_logic.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/import_logic.py	Fri Apr 27 14:35:41 2012 -0700
@@ -16,12 +16,15 @@
 from chirp import chirp_common, errors
 
 class ImportError(Exception):
+    """An import error"""
     pass
 
 class DestNotCompatible(ImportError):
+    """Memory is not compatible with the destination radio"""
     pass
 
 def ensure_has_calls(radio, memory):
+    """Make sure @radio has the necessary D-STAR callsigns for @memory"""
     ulist_changed = rlist_changed = False
 
     ulist = radio.get_urcall_list()
@@ -59,10 +62,10 @@
         radio.set_repeater_cal_list(rlist)
 
 # Filter the name according to the destination's rules
-def _import_name(dst_radio, srcrf, mem):
+def _import_name(dst_radio, _srcrf, mem):
     mem.name = dst_radio.filter_name(mem.name)
 
-def _import_power(dst_radio, srcrf, mem):
+def _import_power(dst_radio, _srcrf, mem):
     levels = dst_radio.get_features().valid_power_levels
     if not levels:
         mem.power = None
@@ -101,6 +104,8 @@
             mem.ctone = mem.rtone
 
 def import_mem(dst_radio, src_features, src_mem, overrides={}):
+    """Perform import logic to create a destination memory from
+    src_mem that will be compatible with @dst_radio"""
     dst_rf = dst_radio.get_features()
 
     if isinstance(src_mem, chirp_common.DVMemory):
@@ -123,10 +128,10 @@
         dst_mem.__dict__[k] = v
 
     msgs = dst_radio.validate_memory(dst_mem)
-    errors = [x for x in msgs if isinstance(x, chirp_common.ValidationError)]
-    if errors:
+    errs = [x for x in msgs if isinstance(x, chirp_common.ValidationError)]
+    if errs:
         raise DestNotCompatible("Unable to create import memory: %s" %\
-                                    ", ".join(errors))
+                                    ", ".join(errs))
 
     return dst_mem
         
diff -r db82df47f205 -r f805c420592f chirp/kenwood_hmk.py
--- a/chirp/kenwood_hmk.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/kenwood_hmk.py	Fri Apr 27 14:35:41 2012 -0700
@@ -14,16 +14,17 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import os
 import csv
 
 from chirp import chirp_common, errors, directory, generic_csv
 
 class OmittedHeaderError(Exception):
+    """An internal exception to indicate that a header was omitted"""
     pass
 
 @directory.register
 class HMKRadio(generic_csv.CSVRadio):
+    """Kenwood HMK format"""
     VENDOR = "Kenwood"
     MODEL = "HMK"
     FILE_EXTENSION = "hmk"
diff -r db82df47f205 -r f805c420592f chirp/kenwood_live.py
--- a/chirp/kenwood_live.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/kenwood_live.py	Fri Apr 27 14:35:41 2012 -0700
@@ -23,8 +23,10 @@
     import sys
     sys.path.insert(0, "..")
 
-from chirp import chirp_common, errors, directory
-from chirp.settings import *
+from chirp import chirp_common, errors, directory, util
+from chirp.settings import RadioSetting, RadioSettingGroup, \
+    RadioSettingValueInteger, RadioSettingValueBoolean, \
+    RadioSettingValueString, RadioSettingValueList
 
 DEBUG = True
 
@@ -35,31 +37,24 @@
 
 THF6_MODES = ["FM", "WFM", "AM", "LSB", "USB", "CW"]
 
-def rev(hash, value):
-    reverse = {}
-    for k, v in hash.items():
-        reverse[v] = k
-
-    return reverse[value]
-
 LOCK = threading.Lock()
 
-def command(s, command, *args):
+def command(ser, cmd, *args):
+    """Send @cmd to radio via @ser"""
     global LOCK
 
     start = time.time()
 
     LOCK.acquire()
-    cmd = command
     if args:
         cmd += " " + " ".join(args)
     if DEBUG:
         print "PC->RADIO: %s" % cmd
-    s.write(cmd + "\r")
+    ser.write(cmd + "\r")
 
     result = ""
     while not result.endswith("\r"):
-        result += s.read(8)
+        result += ser.read(8)
         if (time.time() - start) > 0.5:
             print "Timeout waiting for data"
             break
@@ -72,7 +67,8 @@
     return result.strip()
 
 LAST_BAUD = 9600
-def get_id(s):
+def get_id(ser):
+    """Get the ID of the radio attached to @ser"""
     global LAST_BAUD
     bauds = [9600, 19200, 38400, 57600]
     bauds.remove(LAST_BAUD)
@@ -80,17 +76,18 @@
 
     for i in bauds:
         print "Trying ID at baud %i" % i
-        s.setBaudrate(i)
-        s.write("\r")
-        s.read(25)
-        r = command(s, "ID")
-        if " " in r:
+        ser.setBaudrate(i)
+        ser.write("\r")
+        ser.read(25)
+        resp = command(ser, "ID")
+        if " " in resp:
             LAST_BAUD = i
-            return r.split(" ")[1]
+            return resp.split(" ")[1]
 
     raise errors.RadioError("No response from radio")
 
 def get_tmode(tone, ctcss, dcs):
+    """Get the tone mode based on the values of the tone, ctcss, dcs"""
     if dcs and int(dcs) == 1:
         return "DTCS"
     elif int(ctcss):
@@ -101,9 +98,11 @@
         return ""
 
 def iserr(result):
+    """Returns True if the @result from a radio is an error"""
     return result in ["N", "?"]
 
 class KenwoodLiveRadio(chirp_common.LiveRadio):
+    """Base class for all live-mode kenwood radios"""
     BAUD_RATE = 9600
     VENDOR = "Kenwood"
     MODEL = ""
@@ -178,9 +177,9 @@
         if " " in result:
             value = result.split(" ", 1)[1]
             if value.count(",") == 2:
-                zero, loc, mem.name = value.split(",")
+                _zero, _loc, mem.name = value.split(",")
             else:
-                loc, mem.name = value.split(",")
+                _loc, mem.name = value.split(",")
  
         if mem.duplex == "" and self._kenwood_split:
             result = command(self.pipe, *self._cmd_get_split(number))
@@ -212,7 +211,6 @@
         spec = ",".join(spec)
         r1 = command(self.pipe, *self._cmd_set_memory(memory.number, spec))
         if not iserr(r1):
-            import time
             time.sleep(0.5)
             r2 = command(self.pipe, *self._cmd_set_memory_name(memory.number,
                                                                memory.name))
@@ -238,8 +236,8 @@
         if not self.__memcache.has_key(number):
             return
 
-        r = command(self.pipe, *self._cmd_set_memory(number, ""))
-        if iserr(r):
+        resp = command(self.pipe, *self._cmd_set_memory(number, ""))
+        if iserr(resp):
             raise errors.RadioError("Radio refused delete of %i" % number)
         del self.__memcache[number]
 
@@ -271,6 +269,7 @@
 
 @directory.register
 class THD7Radio(KenwoodLiveRadio):
+    """Kenwood TH-D7"""
     MODEL = "TH-D7"
 
     _kenwood_split = True
@@ -294,7 +293,7 @@
 
     def _make_mem_spec(self, mem):
         if mem.duplex in " -+":
-            duplex = rev(DUPLEX, mem.duplex)
+            duplex = util.get_dict_rev(DUPLEX, mem.duplex)
             offset = mem.offset
         else:
             duplex = 0
@@ -312,7 +311,7 @@
             "", # DCS Code
             "%02i" % (self._kenwood_valid_tones.index(mem.ctone) + 1),
             "%09i" % offset,
-            "%i" % rev(MODES, mem.mode),
+            "%i" % util.get_dict_rev(MODES, mem.mode),
             "%i" % ((mem.skip == "S") and 1 or 0))
 
         return spec
@@ -341,15 +340,15 @@
         return mem
 
     def _kenwood_get(self, cmd):
-        r = command(self.pipe, cmd)
-        if " " in r:
-            return r.split(" ", 1)
+        resp = command(self.pipe, cmd)
+        if " " in resp:
+            return resp.split(" ", 1)
         else:
             raise errors.RadioError("Radio refused to return %s" % cmd)
 
     def _kenwood_set(self, cmd, value):
-        r = command(self.pipe, cmd, value)
-        if " " in r:
+        resp = command(self.pipe, cmd, value)
+        if " " in resp:
             return
         raise errors.RadioError("Radio refused to set %s" % cmd)
 
@@ -377,7 +376,7 @@
                                   aux, tnc, save, display, dtmf)
         sky = RadioSettingGroup("sky", "SkyCommand")
         aprs = RadioSettingGroup("aprs", "APRS")
-        all = RadioSettingGroup("top", "All Settings", radio, aprs, sky)
+        top = RadioSettingGroup("top", "All Settings", radio, aprs, sky)
 
         bools = [("AMR", aprs, "APRS Message Auto-Reply"),
                  ("AIP", aux, "Advanced Intercept Point"),
@@ -394,9 +393,9 @@
 
         for setting, group, name in bools:
             value = self._kenwood_get_bool(setting)
-            s = RadioSetting(setting, name,
-                             RadioSettingValueBoolean(value))
-            group.append(s)
+            rs = RadioSetting(setting, name,
+                              RadioSettingValueBoolean(value))
+            group.append(rs)
 
         lists = [("BAL", all, "Balance"),
                  ("BEP", aux, "Beep"),
@@ -420,18 +419,18 @@
         for setting, group, name in lists:
             value = self._kenwood_get_int(setting)
             options = TH_D7_SETTINGS[setting]
-            s = RadioSetting(setting, name,
-                             RadioSettingValueList(options,
-                                                   options[value]))
-            group.append(s)
+            rs = RadioSetting(setting, name,
+                              RadioSettingValueList(options,
+                                                    options[value]))
+            group.append(rs)
 
         ints = [("CNT", display, "Contrast", 1, 16),
                 ]
-        for setting, group, name, min, max in ints:
+        for setting, group, name, minv, maxv in ints:
             value = self._kenwood_get_int(setting)
-            s = RadioSetting(setting, name,
-                             RadioSettingValueInteger(min, max, value))
-            group.append(s)
+            rs = RadioSetting(setting, name,
+                              RadioSettingValueInteger(minv, maxv, value))
+            group.append(rs)
 
         strings = [("MES", display, "Power-on Message", 8),
                    ("MYC", aprs, "APRS Callsign", 8),
@@ -442,11 +441,11 @@
                    ]
         for setting, group, name, length in strings:
             _cmd, value = self._kenwood_get(setting)
-            s = RadioSetting(setting, name,
-                             RadioSettingValueString(0, length, value))
-            group.append(s)
+            rs = RadioSetting(setting, name,
+                              RadioSettingValueString(0, length, value))
+            group.append(rs)
 
-        return all
+        return top
 
     def set_settings(self, settings):
         for element in settings:
@@ -471,10 +470,12 @@
 
 @directory.register
 class THD7GRadio(THD7Radio):
+    """Kenwood TH-D7G"""
     MODEL = "TH-D7G"
 
 @directory.register
 class TMD700Radio(KenwoodLiveRadio):
+    """Kenwood TH-D700"""
     MODEL = "TM-D700"
 
     _kenwood_split = True
@@ -497,7 +498,7 @@
 
     def _make_mem_spec(self, mem):
         if mem.duplex in " -+":
-            duplex = rev(DUPLEX, mem.duplex)
+            duplex = util.get_dict_rev(DUPLEX, mem.duplex)
         else:
             duplex = 0
         spec = ( \
@@ -512,7 +513,7 @@
             "%03i0" % (chirp_common.DTCS_CODES.index(mem.dtcs) + 1),
             "%02i" % (self._kenwood_valid_tones.index(mem.ctone) + 1),
             "%09i" % mem.offset,
-            "%i" % rev(MODES, mem.mode),
+            "%i" % util.get_dict_rev(MODES, mem.mode),
             "%i" % ((mem.skip == "S") and 1 or 0))
 
         return spec
@@ -555,6 +556,7 @@
 
 @directory.register
 class TMV7Radio(KenwoodLiveRadio):
+    """Kenwood TM-V7"""
     MODEL = "TM-V7"
 
     mem_upper_limit = 200 # Will be updated
@@ -592,7 +594,7 @@
         spec = ( \
             "%011i" % mem.freq,
             "%X" % STEPS.index(mem.tuning_step),
-            "%i" % rev(DUPLEX, mem.duplex),
+            "%i" % util.get_dict_rev(DUPLEX, mem.duplex),
             "0",
             "%i" % (mem.tmode == "Tone"),
             "%i" % (mem.tmode == "TSQL"),
@@ -637,14 +639,14 @@
         mem.empty = False
         try:
             self.set_memory(mem)
-        except:
+        except Exception:
             # Failed, so we're past the limit
             return False
 
         # Erase what we did
         try:
             self.erase_memory(loc)
-        except:
+        except Exception:
             pass # V7A Can't delete just yet
 
         return True
@@ -653,20 +655,24 @@
         return 50
 
 class TMV7RadioSub(TMV7Radio):
+    """Base class for the TM-V7 sub devices"""
     def __init__(self, pipe):
-        KenwoodLiveRadio.__init__(self, pipe)
+        TMV7Radio.__init__(self, pipe)
         self._detect_split()
 
 class TMV7RadioVHF(TMV7RadioSub):
+    """TM-V7 VHF subdevice"""
     VARIANT = "VHF"
     _vfo = 0
 
 class TMV7RadioUHF(TMV7RadioSub):
+    """TM-V7 UHF subdevice"""
     VARIANT = "UHF"
     _vfo = 1
 
 @directory.register
 class TMG707Radio(TMV7Radio):
+    """Kenwood TM-G707"""
     MODEL = "TM-G707"
     
     def get_features(self):
@@ -677,13 +683,15 @@
                           (430000000, 450000000)]
         return rf
 
-THF6A_STEPS = [5.0, 6.25, 8.33, 9.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0]
+THF6A_STEPS = [5.0, 6.25, 8.33, 9.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0,
+               100.0]
 
 THF6A_DUPLEX = dict(DUPLEX)
 THF6A_DUPLEX[3] = "split"
 
 @directory.register
 class THF6ARadio(KenwoodLiveRadio):
+    """Kenwood TH-F6"""
     MODEL = "TH-F6"
 
     _upper = 399
@@ -751,7 +759,7 @@
 
     def _make_mem_spec(self, mem):
         if mem.duplex in " +-":
-            duplex = rev(THF6A_DUPLEX, mem.duplex)
+            duplex = util.get_dict_rev(THF6A_DUPLEX, mem.duplex)
             offset = mem.offset
         elif mem.duplex == "split":
             duplex = 0
@@ -777,6 +785,7 @@
 
 @directory.register
 class THF7ERadio(THF6ARadio):
+    """Kenwood TH-F7"""
     MODEL = "TH-F7"
 
 D710_DUPLEX = ["", "+", "-", "split"]
@@ -786,6 +795,7 @@
 
 @directory.register
 class TMD710Radio(KenwoodLiveRadio):
+    """Kenwood TM-D710"""
     MODEL = "TM-D710"
     
     _upper = 999
@@ -846,11 +856,11 @@
         return mem
 
     def _make_mem_spec(self, mem):
-        print "Index %i for step %.2f" % (chirp_common.TUNING_STEPS.index(mem.tuning_step), mem.tuning_step)
         spec = ( \
             "%010i" % mem.freq,
             "%X" % D710_STEPS.index(mem.tuning_step),
-            "%i" % (0 if mem.duplex == "split" else D710_DUPLEX.index(mem.duplex)),
+            "%i" % (0 if mem.duplex == "split" else \
+                        D710_DUPLEX.index(mem.duplex)),
             "0", # Reverse
             "%i" % (mem.tmode == "Tone" and 1 or 0),
             "%i" % (mem.tmode == "TSQL" and 1 or 0),
@@ -860,7 +870,7 @@
             "%03i" % (chirp_common.DTCS_CODES.index(mem.dtcs)),
             "%08i" % (0 if mem.duplex == "split" else mem.offset), # Offset
             "%i" % D710_MODES.index(mem.mode),
-            "%010i" % (mem.offset if mem.duplex == "split" else 0), # TX Frequency
+            "%010i" % (mem.offset if mem.duplex == "split" else 0), # TX Freq
             "0", # Unknown
             "%i" % D710_SKIP.index(mem.skip), # Memory Lockout
             )
@@ -869,6 +879,7 @@
 
 @directory.register
 class THD72Radio(TMD710Radio):
+    """Kenwood TH-D72"""
     MODEL = "TH-D72"
     HARDWARE_FLOW = True
 
@@ -901,11 +912,11 @@
         return mem
 
     def _make_mem_spec(self, mem):
-        print "Index %i for step %.2f" % (chirp_common.TUNING_STEPS.index(mem.tuning_step), mem.tuning_step)
         spec = ( \
             "%010i" % mem.freq,
             "%X" % D710_STEPS.index(mem.tuning_step),
-            "%i" % (0 if mem.duplex == "split" else D710_DUPLEX.index(mem.duplex)),
+            "%i" % (0 if mem.duplex == "split" else \
+                        D710_DUPLEX.index(mem.duplex)),
             "0", # Reverse
             "%i" % (mem.tmode == "Tone" and 1 or 0),
             "%i" % (mem.tmode == "TSQL" and 1 or 0),
@@ -917,7 +928,7 @@
             "0",
             "%08i" % (0 if mem.duplex == "split" else mem.offset), # Offset
             "%i" % D710_MODES.index(mem.mode),
-            "%010i" % (mem.offset if mem.duplex == "split" else 0), # TX Frequency
+            "%010i" % (mem.offset if mem.duplex == "split" else 0), # TX Freq
             "0", # Unknown
             "%i" % D710_SKIP.index(mem.skip), # Memory Lockout
             )
@@ -926,7 +937,8 @@
 
 @directory.register
 class TMV71Radio(TMD710Radio):
-	MODEL = "TM-V71"	
+    """Kenwood TM-V71"""
+    MODEL = "TM-V71"
 
 THK2_DUPLEX = ["", "+", "-"]
 THK2_MODES = ["FM", "NFM"]
@@ -944,6 +956,7 @@
 
 @directory.register
 class THK2Radio(KenwoodLiveRadio):
+    """Kenwood TH-K2"""
     MODEL = "TH-K2"
 
     _kenwood_valid_tones = list(THK2_TONES)
@@ -1028,6 +1041,7 @@
 
 @directory.register
 class TM271Radio(THK2Radio):
+    """Kenwood TM-271"""
     MODEL = "TM-271"
     
     def get_features(self):
@@ -1059,26 +1073,35 @@
     def _cmd_set_memory_name(self, number, name):
         return "MN", "%03i,%s" % (number, name)
 
-if __name__ == "__main__":
-    m = chirp_common.Memory()
-    m.number = 1
-    m.freq = 144000000
-    m.duplex = "split"
-    m.offset = 146000000
+def do_test():
+    """Dev test"""
+    mem = chirp_common.Memory()
+    mem.number = 1
+    mem.freq = 144000000
+    mem.duplex = "split"
+    mem.offset = 146000000
 
-    TestClass = THF6ARadio
+    tc = THF6ARadio
     class FakeSerial:
+        """Faked serial line"""
         buf = ""
         def write(self, buf):
+            """Write"""
             self.buf = buf
         def read(self, count):
+            """Read"""
             if self.buf[:2] == "ID":
                 return "ID %s\r" % TestClass.MODEL
             return self.buf
         def setTimeout(self, foo):
+            """Set Timeout"""
             pass
         def setBaudrate(self, foo):
+            """Set Baudrate"""
             pass
 
-    r = TestClass(FakeSerial())
-    r.set_memory(m)
+    radio = tc(FakeSerial())
+    radio.set_memory(mem)
+
+if __name__ == "__main__":
+    do_test()
diff -r db82df47f205 -r f805c420592f chirp/memmap.py
--- a/chirp/memmap.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/memmap.py	Fri Apr 27 14:35:41 2012 -0700
@@ -24,6 +24,7 @@
         self._data = list(data)
 
     def printable(self, start=None, end=None, printit=True):
+        """Return a printable representation of the memory map"""
         if not start:
             start = 0
 
@@ -38,12 +39,14 @@
         return string
 
     def get(self, start, length=1):
+        """Return a chunk of memory of @length bytes from @start"""
         if start == -1:
             return "".join(self._data[start:])
         else:
             return "".join(self._data[start:start+length])
 
     def set(self, pos, value):
+        """Set a chunk of memory at @pos to @value"""
         if isinstance(value, int):
             self._data[pos] = chr(value)
         elif isinstance(value, str):
@@ -55,6 +58,7 @@
                                  type(value).__name__)
 
     def get_packed(self):
+        """Return the entire memory map as raw data"""
         return "".join(self._data)
 
     def __len__(self):
@@ -80,4 +84,5 @@
         return self.printable(printit=False)
 
     def truncate(self, size):
+        """Truncate the memory map to @size"""
         self._data = self._data[:size]
diff -r db82df47f205 -r f805c420592f chirp/platform.py
--- a/chirp/platform.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/platform.py	Fri Apr 27 14:35:41 2012 -0700
@@ -1,19 +1,3 @@
-# Copyright 2008 Dan Smith <dsmith at danplanet.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-#
 # Copyright 2008 Dan Smith <dsmith at danplanet.com>
 #
 # This program is free software: you can redistribute it and/or modify
@@ -34,26 +18,30 @@
 import glob
 from subprocess import Popen
 
-def find_me():
+def _find_me():
     return sys.modules["chirp.platform"].__file__
 
 class Platform:
-    # pylint: disable-msg=R0201
+    """Base class for platform-specific functions"""
 
     def __init__(self, basepath):
         self._base = basepath
         self._last_dir = self.default_dir()
 
     def get_last_dir(self):
+        """Return the last directory used"""
         return self._last_dir
 
     def set_last_dir(self, last_dir):
+        """Set the last directory used"""
         self._last_dir = last_dir
 
     def config_dir(self):
+        """Return the preferred configuration file directory"""
         return self._base
 
     def log_dir(self):
+        """Return the preferred log file directory"""
         logdir = os.path.join(self.config_dir(), "logs")
         if not os.path.isdir(logdir):
             os.mkdir(logdir)
@@ -61,29 +49,37 @@
         return logdir
 
     def filter_filename(self, filename):
+        """Filter @filename for platform-forbidden characters"""
         return filename
 
     def log_file(self, filename):
+        """Return the full path to a log file with @filename"""
         filename = self.filter_filename(filename + ".txt").replace(" ", "_")
         return os.path.join(self.log_dir(), filename)
 
     def config_file(self, filename):
+        """Return the full path to a config file with @filename"""
         return os.path.join(self.config_dir(),
                             self.filter_filename(filename))
 
     def open_text_file(self, path):
+        """Spawn the necessary program to open a text file at @path"""
         raise NotImplementedError("The base class can't do that")
 
     def open_html_file(self, path):
+        """Spawn the necessary program to open an HTML file at @path"""
         raise NotImplementedError("The base class can't do that")
 
     def list_serial_ports(self):
+        """Return a list of valid serial ports"""
         return []
 
     def default_dir(self):
+        """Return the default directory for this platform"""
         return "."
 
     def gui_open_file(self, start_dir=None, types=[]):
+        """Prompt the user to pick a file to open"""
         import gtk
 
         if not start_dir:
@@ -114,6 +110,7 @@
             return None
 
     def gui_save_file(self, start_dir=None, default_name=None, types=[]):
+        """Prompt the user to pick a filename to save"""
         import gtk
 
         if not start_dir:
@@ -154,6 +151,7 @@
             return None
 
     def gui_select_dir(self, start_dir=None):
+        """Prompt the user to pick a directory"""
         import gtk
 
         if not start_dir:
@@ -178,9 +176,11 @@
             return None
 
     def os_version_string(self):
+        """Return a string that describes the OS/platform version"""
         return "Unknown Operating System"
 
     def executable_path(self):
+        """Return a full path to the program executable"""
         def we_are_frozen():
             return hasattr(sys, "frozen")
 
@@ -190,7 +190,8 @@
                                            sys.getfilesystemencoding()))
         else:
             # UNIX: Find the parent directory of this module
-            return os.path.dirname(os.path.abspath(os.path.join(find_me(), "..")))
+            return os.path.dirname(os.path.abspath(os.path.join(_find_me(),
+                                                                "..")))
 
 def _unix_editor():
     macos_textedit = "/Applications/TextEdit.app/Contents/MacOS/TextEdit"
@@ -201,6 +202,7 @@
         return "gedit"
 
 class UnixPlatform(Platform):
+    """A platform module suitable for UNIX systems"""
     def __init__(self, basepath):
         if not basepath:
             basepath = os.path.abspath(os.path.join(self.default_dir(),
@@ -214,7 +216,7 @@
 	# This is a hack that needs to be properly fixed by importing the
 	# latest changes to this module from d-rats.  In the interest of
 	# time, however, I'll throw it here
-	if sys.platform == "darwin":
+        if sys.platform == "darwin":
             if not os.environ.has_key("DISPLAY"):
                 print "Forcing DISPLAY for MacOS"
                 os.environ["DISPLAY"] = ":0"
@@ -252,7 +254,6 @@
                       glob.glob("/dev/tty.KeySerial*"))
 
     def os_version_string(self):
-        # pylint: disable-msg=W0703
         try:
             issue = file("/etc/issue.net", "r")
             ver = issue.read().strip().replace("\r", "").replace("\n", "")[:64]
@@ -264,6 +265,7 @@
         return ver
 
 class Win32Platform(Platform):
+    """A platform module suitable for Windows systems"""
     def __init__(self, basepath=None):
         if not basepath:
             appdata = os.getenv("APPDATA")
@@ -319,7 +321,6 @@
         return ports
 
     def gui_open_file(self, start_dir=None, types=[]):
-        # pylint: disable-msg=W0703,W0613
         import win32gui
 
         typestrs = ""
@@ -337,11 +338,10 @@
         return str(fname)
 
     def gui_save_file(self, start_dir=None, default_name=None, types=[]):
-        # pylint: disable-msg=W0703,W0613
         import win32gui
         import win32api
         
-        (pform, _, build, _, _) = win32api.GetVersionEx()
+        (pform, _, _, _, _) = win32api.GetVersionEx()
 
         typestrs = ""
         custom = "%s\0*.%s\0" % (types[0][0], types[0][1])
@@ -358,10 +358,10 @@
 
         def_ext = "*.%s" % types[0][1]
         try:
-            fname, filter, _ = win32gui.GetSaveFileNameW(File=default_name,
-                                                         CustomFilter=custom,
-                                                         DefExt=def_ext,
-                                                         Filter=typestrs)
+            fname, _, _ = win32gui.GetSaveFileNameW(File=default_name,
+                                                    CustomFilter=custom,
+                                                    DefExt=def_ext,
+                                                    Filter=typestrs)
         except Exception, e:
             print "Failed to get filename: %s" % e
             return None
@@ -369,7 +369,6 @@
         return str(fname)
 
     def gui_select_dir(self, start_dir=None):
-        # pylint: disable-msg=W0703,W0613
         from win32com.shell import shell
 
         try:
@@ -401,8 +400,7 @@
 
 PLATFORM = None
 def get_platform(basepath=None):
-    #pylint: disable-msg=W0602
-
+    """Return the platform singleton"""
     global PLATFORM
 
     if not PLATFORM:
@@ -410,19 +408,19 @@
 
     return PLATFORM
 
+def _do_test():
+    __pform = get_platform()
+
+    print "Config dir: %s" % __pform.config_dir()
+    print "Default dir: %s" % __pform.default_dir()
+    print "Log file (foo): %s" % __pform.log_file("foo")
+    print "Serial ports: %s" % __pform.list_serial_ports()
+    print "OS Version: %s" % __pform.os_version_string()
+    #__pform.open_text_file("d-rats.py")
+
+    #print "Open file: %s" % __pform.gui_open_file()
+    #print "Save file: %s" % __pform.gui_save_file(default_name="Foo.txt")
+    print "Open folder: %s" % __pform.gui_select_dir("/tmp")
+
 if __name__ == "__main__":
-    def do_test():
-        __pform = get_platform()
-
-        print "Config dir: %s" % __pform.config_dir()
-        print "Default dir: %s" % __pform.default_dir()
-        print "Log file (foo): %s" % __pform.log_file("foo")
-        print "Serial ports: %s" % __pform.list_serial_ports()
-        print "OS Version: %s" % __pform.os_version_string()
-        #__pform.open_text_file("d-rats.py")
-
-        #print "Open file: %s" % __pform.gui_open_file()
-        #print "Save file: %s" % __pform.gui_save_file(default_name="Foo.txt")
-        print "Open folder: %s" % __pform.gui_select_dir("/tmp")
-
-    do_test()
+    _do_test()
diff -r db82df47f205 -r f805c420592f chirp/radioreference.py
--- a/chirp/radioreference.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/radioreference.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,7 +13,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from chirp import chirp_common, CHIRP_VERSION, errors
+from chirp import chirp_common, errors
 try:
     from suds.client import Client
     HAVE_SUDS = True
@@ -31,6 +31,7 @@
 }
 
 class RadioReferenceRadio(chirp_common.NetworkSourceRadio):
+    """RadioReference.com data source"""
     VENDOR = "Radio Reference LLC"
     MODEL = "RadioReference.com"
 
@@ -38,7 +39,7 @@
     APPKEY = "46785108"
 
     def __init__(self, *args, **kwargs):
-        chirp_common.Radio.__init__(self, *args, **kwargs)
+        chirp_common.NetworkSourceRadio.__init__(self, *args, **kwargs)
 
         if not HAVE_SUDS:
             raise errors.RadioError(
@@ -49,9 +50,11 @@
         self._client = Client(self.URL)
         self._freqs = None
         self._modes = None
+        self._zip = None
 
-    def set_params(self, zip, username, password):
-        self._zip = zip
+    def set_params(self, zipcode, username, password):
+        """Set the parameters to be used for a query"""
+        self._zip = zipcode
         self._auth["username"] = username
         self._auth["password"] = password
 
@@ -72,7 +75,8 @@
             print "Fetching category:", cat.cName
             for subcat in cat.subcats:
                 print "\t", subcat.scName
-                result = self._client.service.getSubcatFreqs(subcat.scid, self._auth)
+                result = self._client.service.getSubcatFreqs(subcat.scid,
+                                                             self._auth)
                 self._freqs += result
                 status.cur += 1
                 self.status_fn(status)
@@ -85,7 +89,8 @@
                 print "Fetching category:", cat.cName
                 for subcat in cat.subcats:
                     print "\t", subcat.scName
-                    result = self._client.service.getSubcatFreqs(subcat.scid, self._auth)
+                    result = self._client.service.getSubcatFreqs(subcat.scid,
+                                                                 self._auth)
                     self._freqs += result
                     status.cur += 1
                     self.status_fn(status)
@@ -126,7 +131,7 @@
             else:
                 try:
                     tone, tmode = freq.tone.split(" ")
-                except:
+                except Exception:
                     tone, tmode = None, None
                 if tmode == "PL":
                     mem.tmode = "TSQL"
@@ -164,7 +169,9 @@
     """
     import sys
     rrr = RadioReferenceRadio(None)
-    rrr.set_params(zip=sys.argv[1], username=sys.argv[2], password=sys.argv[3])
+    rrr.set_params(zipcode=sys.argv[1],
+                   username=sys.argv[2],
+                   password=sys.argv[3])
     rrr.do_fetch()
     print rrr.get_raw_memory(0)
     print rrr.get_memory(0)
diff -r db82df47f205 -r f805c420592f chirp/rfinder.py
--- a/chirp/rfinder.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/rfinder.py	Fri Apr 27 14:35:41 2012 -0700
@@ -17,7 +17,7 @@
 import hashlib
 import re
 
-from math import pi,cos,acos,sin,atan2
+from math import pi, cos, acos, sin, atan2
 
 from chirp import chirp_common, CHIRP_VERSION
 
@@ -48,46 +48,55 @@
     ]
 
 def deg2rad(deg):
+    """Convert degrees to radians"""
     return deg * (pi / 180)
 
 def rad2deg(rad):
+    """Convert radians to degrees"""
     return rad / (pi / 180)
 
-def dm2deg(deg, min):
-    return deg + (min / 60.0)
+def dm2deg(degrees, minutes):
+    """Convert degrees and minutes to decimal degrees"""
+    return degrees + (minutes / 60.0)
 
 def deg2dm(decdeg):
-    deg = int(decdeg)
-    min = (decdeg - deg) * 60.0
+    """Convert decimal degrees to degrees and minutes"""
+    degrees = int(decdeg)
+    minutes = (decdeg - degrees) * 60.0
 
-    return deg, min
+    return degrees, minutes
 
-def nmea2deg(nmea, dir="N"):
+def nmea2deg(nmea, direction="N"):
+    """Convert NMEA-encoded value to float"""
     deg = int(nmea) / 100
     try:
-        min = nmea % (deg * 100)
-    except ZeroDivisionError, e:
-        min = int(nmea)
+        minutes = nmea % (deg * 100)
+    except ZeroDivisionError:
+        minutes = int(nmea)
 
-    if dir == "S" or dir == "W":
-        m = -1
+    if direction == "S" or direction == "W":
+        sign = -1
     else:
-        m = 1
+        sign = 1
 
-    return dm2deg(deg, min) * m
+    return dm2deg(deg, minutes) * sign
 
 def deg2nmea(deg):
-    deg, min = deg2dm(deg)
+    """Convert degrees to a NMEA-encoded value"""
+    degrees, minutes = deg2dm(deg)
 
-    return (deg * 100) + min
+    return (degrees * 100) + minutes
 
 def meters2feet(meters):
+    """Convert meters to feet"""
     return meters * 3.2808399
 
 def feet2meters(feet):
+    """Convert feet to meters"""
     return feet * 0.3048
 
 def distance(lat_a, lon_a, lat_b, lon_b):
+    """Calculate the distance between two points"""
     lat_a = deg2rad(lat_a)
     lon_a = deg2rad(lon_a)
     
@@ -108,30 +117,27 @@
     elif tmp < -1:
         tmp = -1
 
-    distance = acos(tmp)
+    dist = acos(tmp)
 
-    return distance * earth_radius
+    return dist * earth_radius
 
 def bearing(lat_a, lon_a, lat_b, lon_b):
+    """Calculate the bearing between two points"""
     lat_me = deg2rad(lat_a)
-    lon_me = deg2rad(lon_a)
-
     lat_u = deg2rad(lat_b)
-    lon_u = deg2rad(lon_b)
-
-    lat_d = deg2rad(lat_b - lat_a)
     lon_d = deg2rad(lon_b - lon_a)
 
-    y = sin(lon_d) * cos(lat_u)
-    x = cos(lat_me) * sin(lat_u) - \
+    posy = sin(lon_d) * cos(lat_u)
+    posx = cos(lat_me) * sin(lat_u) - \
         sin(lat_me) * cos(lat_u) * cos(lon_d)
 
-    bearing = rad2deg(atan2(y, x))
+    bear = rad2deg(atan2(posy, posx))
 
-    return (bearing + 360) % 360
+    return (bear + 360) % 360
 
 def fuzzy_to(lat_a, lon_a, lat_b, lon_b):
-    dir = bearing(lat_a, lon_a, lat_b, lon_b)
+    """Calculate a fuzzy distance to a point"""
+    bear = bearing(lat_a, lon_a, lat_b, lon_b)
 
     dirs = ["N", "NNE", "NE", "ENE", "E",
             "ESE", "SE", "SSE", "S",
@@ -143,27 +149,29 @@
 
     direction = "?"
     for i in dirs:
-        if dir > angle and dir < (angle + delta):
+        if bear > angle and bear < (angle + delta):
             direction = i
         angle += delta
 
     return direction
 
 class RFinderParser:
+    """Parser for RFinder's data format"""
     def __init__(self, lat, lon):
         self.__memories = []
         self.__cheat = {}
         self.__lat = lat
         self.__lon = lon
 
-    def fetch_data(self, user, pw, lat, lon, radius):
+    def fetch_data(self, user, pw, coords, radius):
+        """Fetches the data for a set of parameters"""
         print user
         print pw
         args = {
             "email"  : urllib.quote_plus(user),
             "pass"  : hashlib.md5(pw).hexdigest(),
-            "lat"   : "%7.5f" % lat,
-            "lon"   : "%8.5f" % lon,
+            "lat"   : "%7.5f" % coords[0],
+            "lon"   : "%8.5f" % coords[1],
             "radius": "%i" % radius,
             "vers"  : "CH%s" % CHIRP_VERSION,
             }
@@ -183,7 +191,7 @@
 
         return data
 
-    def parse_line(self, line):
+    def _parse_line(self, line):
         mem = chirp_common.Memory()
 
         _vals = line.split("|")
@@ -217,15 +225,16 @@
             try:
                 lat = float(vals["LATITUDE"])
                 lon = float(vals["LONGITUDE"])
-                d = distance(self.__lat, self.__lon, lat, lon)
-                b = fuzzy_to(self.__lat, self.__lon, lat, lon)
-                mem.comment = "(%imi %s) %s" % (d, b, mem.comment)
+                dist = distance(self.__lat, self.__lon, lat, lon)
+                bear = fuzzy_to(self.__lat, self.__lon, lat, lon)
+                mem.comment = "(%imi %s) %s" % (dist, bear, mem.comment)
             except Exception, e:
                 print "Failed to calculate distance: %s" % e
 
         return mem
 
     def parse_data(self, data):
+        """Parse the fetched data"""
         number = 1
         for line in data.split("\n"):
             if line.startswith("<"):
@@ -233,7 +242,7 @@
             elif not line.strip():
                 continue
             try:
-                mem = self.parse_line(line)
+                mem = self._parse_line(line)
                 mem.number = number
                 number += 1
                 self.__memories.append(mem)
@@ -247,23 +256,27 @@
                 print "\n\n"
 
     def get_memories(self):
+        """Return the Memory objects associated with the fetched data"""
         return self.__memories
 
 class RFinderRadio(chirp_common.NetworkSourceRadio):
+    """A network source radio that supports the RFinder repeater directory"""
     VENDOR = "ITWeRKS"
     MODEL = "RFinder"
 
     def __init__(self, *args, **kwargs):
-        chirp_common.Radio.__init__(self, *args, **kwargs)
+        chirp_common.NetworkSourceRadio.__init__(self, *args, **kwargs)
        
         self._lat = 0
         self._lon = 0
         self._user = ""
         self._pass = ""
+        self._miles = 25
  
         self._rfp = None
 
-    def set_params(self, lat, lon, miles, email, password):
+    def set_params(self, (lat, lon), miles, email, password):
+        """Sets the parameters to use for the query"""
         self._lat = lat
         self._lon = lon
         self._miles = miles
@@ -275,8 +288,7 @@
 
         self._rfp.parse_data(self._rfp.fetch_data(self._user,
                                                   self._pass,
-                                                  self._lat,
-                                                  self._lon,
+                                                  (self._lat, self._lon),
                                                   self._miles))
         
     def get_features(self):
@@ -297,12 +309,14 @@
 
         return self._rfp.get_memories()[number-1]
 
-if __name__ == "__main__":
-    import sys
-
+def _test():
     rfp = RFinderParser()
-    data = rfp.fetch_data(45.525, -122.9164, "KK7DS", "dsmith at danplanet.com")
+    data = rfp.fetch_data("KK7DS", "dsmith at danplanet.com",
+                          (45.5, -122.91), 25)
     rfp.parse_data(data)
 
-    for m in rfp.get_memories():
-        print m
+    for mem in rfp.get_memories():
+        print mem
+
+if __name__ == "__main__":
+    _test()
diff -r db82df47f205 -r f805c420592f chirp/settings.py
--- a/chirp/settings.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/settings.py	Fri Apr 27 14:35:41 2012 -0700
@@ -16,25 +16,31 @@
 from chirp import chirp_common
 
 class InvalidValueError(Exception):
+    """An invalid value was specified for a given setting"""
     pass
 
 class InternalError(Exception):
+    """A driver provided an invalid settings object structure"""
     pass
 
 class RadioSettingValue:
+    """Base class for a single radio setting"""
     def __init__(self):
         self._current = None
         self._has_changed = False
 
     def changed(self):
+        """Returns True if the setting has been changed since init"""
         return self._has_changed
 
     def set_value(self, value):
+        """Sets the current value, triggers changed"""
         if self._current != None and value != self._current:
             self._has_changed = True
         self._current = value
 
     def get_value(self):
+        """Gets the current value"""
         return self._current
 
     def __trunc__(self):
@@ -44,10 +50,11 @@
         return str(self.get_value())
 
 class RadioSettingValueInteger(RadioSettingValue):
-    def __init__(self, min, max, current, step=1):
+    """An integer setting"""
+    def __init__(self, minval, maxval, current, step=1):
         RadioSettingValue.__init__(self)
-        self._min = min
-        self._max = max
+        self._min = minval
+        self._max = maxval
         self._step = step
         self.set_value(current)
 
@@ -63,15 +70,19 @@
         RadioSettingValue.set_value(self, value)
 
     def get_min(self):
+        """Returns the minimum allowed value"""
         return self._min
 
     def get_max(self):
+        """Returns the maximum allowed value"""
         return self._max
 
     def get_step(self):
+        """Returns the step increment"""
         return self._step
 
 class RadioSettingValueBoolean(RadioSettingValue):
+    """A boolean setting"""
     def __init__(self, current):
         RadioSettingValue.__init__(self)
         self.set_value(current)
@@ -83,6 +94,7 @@
         return str(bool(self.get_value()))
 
 class RadioSettingValueList(RadioSettingValue):
+    """A list-of-strings setting"""
     def __init__(self, options, current):
         RadioSettingValue.__init__(self)
         self._options = options
@@ -94,12 +106,14 @@
         RadioSettingValue.set_value(self, value)
 
     def get_options(self):
+        """Returns the list of valid option values"""
         return self._options
 
     def __trunc__(self):
         return self._options.index(self._current)
 
 class RadioSettingValueString(RadioSettingValue):
+    """A string setting"""
     def __init__(self, minlength, maxlength, current,
                  autopad=True):
         RadioSettingValue.__init__(self)
@@ -110,6 +124,7 @@
         self.set_value(current)
 
     def set_charset(self, charset):
+        """Sets the set of allowed characters"""
         self._charset = charset
 
     def set_value(self, value):
@@ -128,6 +143,7 @@
         return self._current.rstrip()
 
 class RadioSettingGroup(object):
+    """A group of settings"""
     def _validate(self, element):
         # RadioSettingGroup can only contain RadioSettingGroup objects
         if not isinstance(element, RadioSettingGroup):
@@ -146,37 +162,43 @@
             self.append(element)
 
     def get_name(self):
+        """Returns the group name"""
         return self._name
 
     def get_shortname(self):
+        """Returns the short group identifier"""
         return self._shortname
 
     def set_doc(self, doc):
+        """Sets the docstring for the group"""
         self.__doc__ = doc
 
     def __str__(self):
-        s = "{Settings Group %s:\n" % self._name
+        string = "{Settings Group %s:\n" % self._name
         for element in self._elements.values():
-            s += str(element) + "\n"
-        s += "}"
-        return s
+            string += str(element) + "\n"
+        string += "}"
+        return string
 
     # Kinda list interface
 
     def append(self, element):
+        """Adds an element to the group"""
         self[element.get_name()] = element
 
     def __iter__(self):
         class RSGIterator:
+            """Iterator for a RadioSettingsGroup"""
             def __init__(self, rsg):
                 self.__rsg = rsg
                 self.__i = 0
             def __iter__(self):
                 return self
             def next(self):
-                if self.__i >= len(self.__rsg._element_order):
+                """Next Iterator Interface"""
+                if self.__i >= len(self.__rsg.keys()):
                     raise StopIteration()
-                e =  self.__rsg._elements[self.__rsg._element_order[self.__i]]
+                e =  self.__rsg[self.__rsg.keys()[self.__i]]
                 self.__i += 1
                 return e
         return RSGIterator(self)
@@ -196,21 +218,26 @@
         self._element_order.append(name)
 
     def items(self):
+        """Returns a key=>value set of elements, like a dict"""
         return [(name, self._elements[name]) for name in self._element_order]
 
     def keys(self):
+        """Returns a list of string element names"""
         return self._element_order
 
     def values(self):
-        return [self.elements[name] for name in self._element_order]
+        """Returns the list of elements"""
+        return [self._elements[name] for name in self._element_order]
 
 class RadioSetting(RadioSettingGroup):
+    """A single setting, which could be an array of items like a group"""
     def _validate(self, value):
         # RadioSetting can only contain RadioSettingValue objects
         if not isinstance(value, RadioSettingValue):
             raise InternalError("Incorrect type")
 
     def changed(self):
+        """Returns True if any of the elements in the group have been changed"""
         for element in self._elements.values():
             if element.changed():
                 return True
diff -r db82df47f205 -r f805c420592f chirp/template.py
--- a/chirp/template.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/template.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,7 +13,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from chirp import chirp_common, yaesu_clone, util, directory, memmap
+from chirp import chirp_common, directory, memmap
 from chirp import bitwise
 
 # Here is where we define the memory map for the radio. Since
@@ -24,7 +24,7 @@
 # With some very basic settings, a 32-bit unsigned integer for the
 # frequency (in Hertz) and an eight-character alpha tag
 #
-mem_format = """
+MEM_FORMAT = """
 #seekto 0x0000;
 struct {
   u32 freq;
@@ -33,6 +33,7 @@
 """
 
 def do_download(radio):
+    """This is your download function"""
     # NOTE: Remove this in your real implementation!
     return memmap.MemoryMap("\x00" * 1000)
 
@@ -43,12 +44,13 @@
     # from the serial port. Do that one byte at a time and
     # store them in the memory map
     data = ""
-    for i in range(0, 1000):
+    for _i in range(0, 1000):
         data = serial.read(1)
 
     return memmap.MemoryMap(data)
 
 def do_upload(radio):
+    """This is your upload function"""
     # NOTE: Remove this in your real implementation!
     raise Exception("This template driver does not really work!")
 
@@ -59,11 +61,12 @@
     # to the serial port. Do that one byte at a time, reading
     # from our memory map
     for i in range(0, 1000):
-        serial.write(radio._mmap[i])
+        serial.write(radio.get_mmap()[i])
 
 # Uncomment this to actually register this radio in CHIRP
 # @directory.register
 class TemplateRadio(chirp_common.CloneModeRadio):
+    """Acme Template"""
     VENDOR = "Acme"    # Replace this with your vendor
     MODEL = "Template" # Replace this with your model
     BAUD_RATE = 9600   # Replace this with your baud rate
@@ -82,7 +85,7 @@
     # Do a download of the radio from the serial port
     def sync_in(self):
         self._mmap = do_download(self)
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     # Do an upload of the radio to the serial port
     def sync_out(self):
diff -r db82df47f205 -r f805c420592f chirp/util.py
--- a/chirp/util.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/util.py	Fri Apr 27 14:35:41 2012 -0700
@@ -16,6 +16,7 @@
 import struct
 
 def hexprint(data):
+    """Return a hexdump-like encoding of @data"""
     line_sz = 8
 
     lines = len(data) / line_sz
@@ -52,10 +53,8 @@
 
     return out
 
-def write_in_place(mem, start, data):
-    return mem[:start] + data + mem[start+len(data):]
-
 def bcd_encode(val, bigendian=True, width=None):
+    """This is really old and shouldn't be used anymore"""
     digits = []
     while val != 0:
         digits.append(val % 10)
@@ -78,8 +77,9 @@
     
     return result
 
-def get_dict_rev(dict, key):
+def get_dict_rev(thedict, value):
+    """Return the first matching key for a given @value in @dict"""
     _dict = {}
-    for k,v in dict.items():
+    for k, v in thedict.items():
         _dict[v] = k
-    return _dict[key]
+    return _dict[value]
diff -r db82df47f205 -r f805c420592f chirp/uv5r.py
--- a/chirp/uv5r.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/uv5r.py	Fri Apr 27 14:35:41 2012 -0700
@@ -15,11 +15,13 @@
 
 import struct
 
-from chirp import chirp_common, errors, util, directory, memmap, settings
+from chirp import chirp_common, errors, util, directory, memmap
 from chirp import bitwise
-from chirp.settings import *
+from chirp.settings import RadioSetting, RadioSettingGroup, \
+    RadioSettingValueInteger, RadioSettingValueList, \
+    RadioSettingValueList, RadioSettingValueBoolean
 
-mem_format = """
+MEM_FORMAT = """
 #seekto 0x0008;
 struct {
   lbcd rxfreq[4];
@@ -83,31 +85,31 @@
 """
 
 STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0]
-step_list = [str(x) for x in STEPS]
-timeout_list = ["%s sec" % x for x in range(15, 615, 15)]
-resume_list = ["TO", "CO", "SE"]
-mode_list = ["Channel", "Name", "Frequency"]
-color_list = ["Off", "Blue", "Orange", "Purple"]
+STEP_LIST = [str(x) for x in STEPS]
+TIMEOUT_LIST = ["%s sec" % x for x in range(15, 615, 15)]
+RESUME_LIST = ["TO", "CO", "SE"]
+MODE_LIST = ["Channel", "Name", "Frequency"]
+COLOR_LIST = ["Off", "Blue", "Orange", "Purple"]
 
 SETTING_LISTS = {
-    "step" : step_list,
-    "timeout" : timeout_list,
-    "screv" : resume_list,
-    "mdfa" : mode_list,
-    "mdfb" : mode_list,
-    "wtled" : color_list,
-    "rxled" : color_list,
-    "txled" : color_list,
+    "step" : STEP_LIST,
+    "timeout" : TIMEOUT_LIST,
+    "screv" : RESUME_LIST,
+    "mdfa" : MODE_LIST,
+    "mdfb" : MODE_LIST,
+    "wtled" : COLOR_LIST,
+    "rxled" : COLOR_LIST,
+    "txled" : COLOR_LIST,
 }
 
-def do_status(radio, block):
-    s = chirp_common.Status()
-    s.msg = "Cloning"
-    s.cur = block
-    s.max = radio._memsize
-    radio.status_fn(s)
+def _do_status(radio, block):
+    status = chirp_common.Status()
+    status.msg = "Cloning"
+    status.cur = block
+    status.max = radio.get_memsize()
+    radio.status_fn(status)
 
-def do_ident(radio):
+def _do_ident(radio):
     serial = radio.pipe
     serial.setTimeout(1)
 
@@ -130,12 +132,12 @@
 
     return ident
 
-def do_download(radio):
+def _do_download(radio):
     serial = radio.pipe
 
-    data = do_ident(radio)
+    data = _do_ident(radio)
 
-    for i in range(0, radio._memsize - 0x08, 0x40):
+    for i in range(0, radio.get_memsize() - 0x08, 0x40):
         msg = struct.pack(">BHB", ord("S"), i, 0x40)
         serial.write(msg)
 
@@ -162,23 +164,23 @@
         if ack != "\x06":
             raise errors.RadioError("Radio refused to send block 0x%04x" % i)
 
-        do_status(radio, i)
+        _do_status(radio, i)
 
     return memmap.MemoryMap(data)
 
-def do_upload(radio):
+def _do_upload(radio):
     serial = radio.pipe
 
-    do_ident(radio)
+    _do_ident(radio)
 
-    for i in range(0x08, radio._memsize, 0x10):
+    for i in range(0x08, radio.get_memsize(), 0x10):
         msg = struct.pack(">BHB", ord("X"), i - 0x08, 0x10)
-        serial.write(msg + radio._mmap[i:i+0x10])
+        serial.write(msg + radio.get_mmap()[i:i+0x10])
 
         ack = serial.read(1)
         if ack != "\x06":
             raise errors.RadioError("Radio refused to accept block 0x%04x" % i)
-        do_status(radio, i)
+        _do_status(radio, i)
 
 UV5R_POWER_LEVELS = [chirp_common.PowerLevel("High", watts=4.00),
                      chirp_common.PowerLevel("Low",  watts=1.00)]
@@ -186,6 +188,7 @@
 # Uncomment this to actually register this radio in CHIRP
 @directory.register
 class BaofengUV5R(chirp_common.CloneModeRadio):
+    """Baofeng UV-5R"""
     VENDOR = "Baofeng"
     MODEL = "UV-5R"
     BAUD_RATE = 9600
@@ -212,12 +215,12 @@
         return rf
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
         print self.get_settings()
 
     def sync_in(self):
         try:
-            self._mmap = do_download(self)
+            self._mmap = _do_download(self)
         except errors.RadioError:
             raise
         except Exception, e:
@@ -226,7 +229,7 @@
 
     def sync_out(self):
         try:
-            do_upload(self)
+            _do_upload(self)
         except errors.RadioError:
             raise
         except Exception, e:
@@ -387,81 +390,81 @@
         advanced = RadioSettingGroup("advanced", "Advanced Settings")
         group = RadioSettingGroup("top", "All Settings", basic, advanced)
 
-        s = RadioSetting("squelch", "Carrier Squelch Level",
-                         RadioSettingValueInteger(0, 9, _settings.squelch))
-        basic.append(s)
+        rs = RadioSetting("squelch", "Carrier Squelch Level",
+                          RadioSettingValueInteger(0, 9, _settings.squelch))
+        basic.append(rs)
 
-        s = RadioSetting("step", "Tuning Step",
-                         RadioSettingValueList(step_list,
-                                               step_list[_settings.step]))
-        advanced.append(s)
+        rs = RadioSetting("step", "Tuning Step",
+                          RadioSettingValueList(STEP_LIST,
+                                                STEP_LIST[_settings.step]))
+        advanced.append(rs)
 
-        s = RadioSetting("save", "Battery Saver",
-                         RadioSettingValueInteger(0, 4, _settings.save))
-        basic.append(s)
+        rs = RadioSetting("save", "Battery Saver",
+                          RadioSettingValueInteger(0, 4, _settings.save))
+        basic.append(rs)
 
-        s = RadioSetting("vox", "VOX Sensitivity",
-                         RadioSettingValueInteger(0, 10, _settings.vox))
-        advanced.append(s)
+        rs = RadioSetting("vox", "VOX Sensitivity",
+                          RadioSettingValueInteger(0, 10, _settings.vox))
+        advanced.append(rs)
 
-        s = RadioSetting("abr", "Backlight Timeout",
-                         RadioSettingValueInteger(0, 5, _settings.abr))
-        basic.append(s)
+        rs = RadioSetting("abr", "Backlight Timeout",
+                          RadioSettingValueInteger(0, 5, _settings.abr))
+        basic.append(rs)
 
-        s = RadioSetting("tdr", "Dual Watch",
-                         RadioSettingValueBoolean(_settings.tdr))
-        advanced.append(s)
+        rs = RadioSetting("tdr", "Dual Watch",
+                          RadioSettingValueBoolean(_settings.tdr))
+        advanced.append(rs)
 
-        s = RadioSetting("beep", "Beep",
-                         RadioSettingValueBoolean(_settings.beep))
-        basic.append(s)
+        rs = RadioSetting("beep", "Beep",
+                          RadioSettingValueBoolean(_settings.beep))
+        basic.append(rs)
 
-        s = RadioSetting("timeout", "Timeout Timer",
-                         RadioSettingValueList(timeout_list,
-                                               timeout_list[_settings.tdr]))
-        basic.append(s)
+        rs = RadioSetting("timeout", "Timeout Timer",
+                          RadioSettingValueList(TIMEOUT_LIST,
+                                                TIMEOUT_LIST[_settings.tdr]))
+        basic.append(rs)
 
-        s = RadioSetting("voice", "Voice",
-                         RadioSettingValueBoolean(_settings.voice))
-        advanced.append(s)
+        rs = RadioSetting("voice", "Voice",
+                          RadioSettingValueBoolean(_settings.voice))
+        advanced.append(rs)
         
-        s = RadioSetting("screv", "Scan Resume",
-                         RadioSettingValueList(resume_list,
-                                               resume_list[_settings.screv]))
-        advanced.append(s)
+        rs = RadioSetting("screv", "Scan Resume",
+                          RadioSettingValueList(RESUME_LIST,
+                                                RESUME_LIST[_settings.screv]))
+        advanced.append(rs)
 
-        s = RadioSetting("mdfa", "Display Mode (A)",
-                         RadioSettingValueList(mode_list,
-                                               mode_list[_settings.mdfa]))
-        basic.append(s)
+        rs = RadioSetting("mdfa", "Display Mode (A)",
+                          RadioSettingValueList(MODE_LIST,
+                                                MODE_LIST[_settings.mdfa]))
+        basic.append(rs)
 
-        s = RadioSetting("mdfb", "Display Mode (B)",
-                         RadioSettingValueList(mode_list,
-                                               mode_list[_settings.mdfb]))
-        basic.append(s)
+        rs = RadioSetting("mdfb", "Display Mode (B)",
+                          RadioSettingValueList(MODE_LIST,
+                                                MODE_LIST[_settings.mdfb]))
+        basic.append(rs)
 
-        s = RadioSetting("bcl", "Busy Channel Lockout",
-                         RadioSettingValueBoolean(_settings.bcl))
-        advanced.append(s)
+        rs = RadioSetting("bcl", "Busy Channel Lockout",
+                          RadioSettingValueBoolean(_settings.bcl))
+        advanced.append(rs)
 
-        s = RadioSetting("autolk", "Automatic Key Lock",
-                         RadioSettingValueBoolean(_settings.autolk))
-        advanced.append(s)
+        rs = RadioSetting("autolk", "Automatic Key Lock",
+                          RadioSettingValueBoolean(_settings.autolk))
+        advanced.append(rs)
 
-        s = RadioSetting("wtled", "Standby LED Color",
-                         RadioSettingValueList(color_list,
-                                               color_list[_settings.wtled]))
-        basic.append(s)
+        rs = RadioSetting("wtled", "Standby LED Color",
+                          RadioSettingValueList(COLOR_LIST,
+                                                COLOR_LIST[_settings.wtled]))
+        basic.append(rs)
 
-        s = RadioSetting("rxled", "RX LED Color",
-                         RadioSettingValueList(color_list,
-                                               color_list[_settings.rxled]))
-        basic.append(s)
+        rs = RadioSetting("rxled", "RX LED Color",
+                          RadioSettingValueList(COLOR_LIST,
+                                                COLOR_LIST[_settings.rxled]))
+        basic.append(rs)
 
-        s = RadioSetting("txled", "TX LED Color",
-                         RadioSettingValueList(color_list,
-                                               color_list[_settings.txled]))
-        basic.append(s)
+        rs = RadioSetting("txled", "TX LED Color",
+                          RadioSettingValueList(COLOR_LIST,
+                                                COLOR_LIST[_settings.txled]))
+        basic.append(rs)
 
         return group
 
@@ -471,9 +474,6 @@
             if not isinstance(element, RadioSetting):
                 self.set_settings(element)
                 continue
-
-            if element.get_name() in SETTING_LISTS.keys():
-                value = SETTING_LISTS[element.get_name()].index(str(element.value))
             try:
                 setattr(_settings, element.get_name(), element.value)
             except Exception, e:
diff -r db82df47f205 -r f805c420592f chirp/vx3.py
--- a/chirp/vx3.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/vx3.py	Fri Apr 27 14:35:41 2012 -0700
@@ -14,7 +14,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from chirp import chirp_common, yaesu_clone, util, directory
+from chirp import chirp_common, yaesu_clone, directory
 from chirp import bitwise
 
 #interesting offsets which may be checksums needed later
@@ -23,7 +23,7 @@
 #0x0409 checksum2?
 #0x04C9 checksum2a?
 
-mem_format = """
+MEM_FORMAT = """
 #seekto 0x7F4A;
 u8 checksum;
 
@@ -93,6 +93,7 @@
                 chirp_common.PowerLevel("Low", watts=0.10)]
 
 class VX3Bank(chirp_common.NamedBank):
+    """A VX3 Bank"""
     def get_name(self):
         _bank = self._model._radio._memobj.bank_names[self.index]
         name = ""
@@ -108,6 +109,7 @@
         _bank.name = [CHARSET.index(x) for x in name.ljust(6)[:6]]
 
 class VX3BankModel(chirp_common.BankModel):
+    """A VX-3 bank model"""
     def get_num_banks(self):
         return 24
 
@@ -121,8 +123,18 @@
             banks.append(bank)
         return banks
 
+def _wipe_memory(mem):
+    mem.set_raw("\x00" * (mem.size() / 8))
+    #the following settings are set to match the defaults
+    #on the radio, some of these fields are unknown
+    mem.name = [0xFF for _i in range(0, 6)]
+    mem.unknown5 = 0x0D #not sure what this is
+    mem.unknown7 = 0x01 #this likely is part of autostep
+    mem.automode = 0x01 #autoselect mode
+
 @directory.register
 class VX3Radio(yaesu_clone.YaesuCloneModeRadio):
+    """Yaesu VX-3"""
     BAUD_RATE = 19200
     VENDOR = "Yaesu"
     MODEL = "VX-3"
@@ -139,7 +151,7 @@
         return [ yaesu_clone.YaesuChecksum(0x0000, 0x7F49) ]
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_features(self):
         rf = chirp_common.RadioFeatures()
@@ -169,7 +181,7 @@
 
         nibble = ((number-1) % 2) and "even" or "odd"
         used = _flag["%s_masked" % nibble]
-        valid =_flag["%s_valid" % nibble]
+        valid = _flag["%s_valid" % nibble]
         pskip = _flag["%s_pskip" % nibble]
         skip = _flag["%s_skip" % nibble]
 
@@ -203,16 +215,6 @@
         mem.name = mem.name.rstrip()
         return mem
 
-    def _wipe_memory(self, mem):
-        mem.set_raw("\x00" * (mem.size() / 8))
-        #the following settings are set to match the defaults
-        #on the radio, some of these fields are unknown
-        mem.name = [0xFF for i in range(0, 6)]
-        mem.unknown5 = 0x0D #not sure what this is
-        mem.unknown7 = 0x01 #this likely is part of autostep
-        mem.automode = 0x01 #autoselect mode
-
-
     def set_memory(self, mem):
         _mem = self._memobj.memory[mem.number-1]
         _flag = self._memobj.flags[(mem.number-1)/2]
@@ -223,7 +225,7 @@
         valid = _flag["%s_valid" % nibble]
 
         if not mem.empty and not valid:
-            self._wipe_memory(_mem)
+            _wipe_memory(_mem)
 
         if mem.empty and valid and not used:
             _flag["%s_valid" % nibble] = False
@@ -251,7 +253,8 @@
 
         for i in range(0, 6):
             _mem.name[i] = CHARSET.index(mem.name.ljust(6)[i])
-        if mem.name.strip(): _mem.name[0] |= 0x80
+        if mem.name.strip():
+            _mem.name[0] |= 0x80
       
     def validate_memory(self, mem):
         msgs = yaesu_clone.YaesuCloneModeRadio.validate_memory(self, mem)
diff -r db82df47f205 -r f805c420592f chirp/vx5.py
--- a/chirp/vx5.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/vx5.py	Fri Apr 27 14:35:41 2012 -0700
@@ -14,10 +14,10 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from chirp import chirp_common, yaesu_clone, util, directory
+from chirp import chirp_common, yaesu_clone, directory
 from chirp import bitwise
 
-mem_format = """
+MEM_FORMAT = """
 #seekto 0x012A;
 struct {
   u8 zeros:4,
@@ -67,6 +67,7 @@
 
 @directory.register
 class VX5Radio(yaesu_clone.YaesuCloneModeRadio):
+    """Yaesu VX-5"""
     BAUD_RATE = 9600
     VENDOR = "Yaesu"
     MODEL = "VX-5"
@@ -97,7 +98,7 @@
         return rf
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_raw_memory(self, number):
         return repr(self._memobj.memory[number-1])
diff -r db82df47f205 -r f805c420592f chirp/vx6.py
--- a/chirp/vx6.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/vx6.py	Fri Apr 27 14:35:41 2012 -0700
@@ -27,14 +27,15 @@
 #   cpu_shifted:  CPU freq has been shifted (to move a birdie out of channel)
 #   power:        0-3: ["L1", "L2", "L3", "Hi"]
 #   pager:        Set if this is a paging memory
-#   tmodes:       0-7: ["", "Tone", "TSQL", "DTCS", "Rv Tn", "D Code", "T DCS", "D Tone"]
+#   tmodes:       0-7: ["", "Tone", "TSQL", "DTCS", "Rv Tn", "D Code",
+#                       "T DCS", "D Tone"]
 #                      Rv Tn: Reverse CTCSS - mutes receiver on tone
 #                      The final 3 are for split:
 #                      D Code: DCS Encode only
 #                      T DCS:  Encodes tone, decodes DCS code
 #                      D Tone: Encodes DCS code, decodes tone
 # }
-mem_format = """
+MEM_FORMAT = """
 #seekto 0x018A;
 u16 bank_sizes[24];
 
@@ -110,6 +111,7 @@
 
 @directory.register
 class VX6Radio(yaesu_clone.YaesuCloneModeRadio):
+    """Yaesu VX-6"""
     BAUD_RATE = 19200
     VENDOR = "Yaesu"
     MODEL = "VX-6"
@@ -123,7 +125,7 @@
         return [ yaesu_clone.YaesuChecksum(0x0000, 0x7F49) ]
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_features(self):
         rf = chirp_common.RadioFeatures()
@@ -225,35 +227,35 @@
         _flag["%s_pskip" % nibble] = mem.skip == "P"
         _flag["%s_skip" % nibble] = mem.skip == "S"
 
-        _mem.name == ("\xFF" * 6)
+        _mem.name = [0xFF] * 6
         for i in range(0, 6):
             _mem.name[i] = CHARSET.index(mem.name.ljust(6)[i])
 
         if mem.name.strip():
             _mem.name[0] |= 0x80
 
-    def get_banks(self):
-        _banks = self._memobj.bank_names
+#    def get_banks(self):
+#        _banks = self._memobj.bank_names
+#
+#        banks = []
+#        for bank in _banks:
+#            name = ""
+#            for i in bank.name:
+#                name += CHARSET[i & 0x7F]
+#            banks.append(name.rstrip())
+#
+#        return banks
+#
+#    # Return channels for a bank. Bank given as number
+#    def get_bank_channels(self, bank):
+#        nchannels = 0
+#        size = self._memobj.bank_sizes[bank]
+#        if size <= 198:
+#            nchannels = 1 + size/2
+#        _channels = self._memobj.bank_channels[bank]
+#        channels = []
+#        for i in range(0, nchannels):
+#            channels.append(int(_channels.channel[i]))
+#
+#        return channels
 
-        banks = []
-        for bank in _banks:
-            name = ""
-            for i in bank.name:
-                name += CHARSET[i & 0x7F]
-            banks.append(name.rstrip())
-
-        return banks
-
-    # Return channels for a bank. Bank given as number
-    def get_bank_channels(self, bank):
-        nchannels = 0
-        size = self._memobj.bank_sizes[bank]
-        if size <= 198:
-            nchannels = 1 + size/2
-        _channels = self._memobj.bank_channels[bank]
-        channels = []
-        for i in range(0, nchannels):
-            channels.append(int(_channels.channel[i]))
-
-        return channels
-
diff -r db82df47f205 -r f805c420592f chirp/vx7.py
--- a/chirp/vx7.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/vx7.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,10 +13,10 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from chirp import chirp_common, yaesu_clone, util, directory
+from chirp import chirp_common, yaesu_clone, directory
 from chirp import bitwise
 
-mem_format = """
+MEM_FORMAT = """
 #seekto 0x0611;
 u8 checksum1;
 
@@ -96,6 +96,7 @@
                     chirp_common.PowerLevel("L1", watts=0.05)]
 
 class VX7BankModel(chirp_common.BankModel):
+    """A VX-7 Bank model"""
     def get_num_banks(self):
         return 9
 
@@ -130,8 +131,8 @@
                 remaining_members += 1
 
         if not found:
-            raise Exception(_("Memory {num} not in "
-                              "bank {bank}").format(num=memory.number,
+            raise Exception("Memory {num} not in " +
+                            "bank {bank}".format(num=memory.number,
                                                     bank=bank))
         if not remaining_members:
             _bank_used.in_use = 0xFFFF
@@ -154,12 +155,19 @@
     def get_memory_banks(self, memory):
         banks = []
         for bank in self.get_banks():
-            if memory.number in [x.number for x in self.get_bank_memories(bank)]:
-                    banks.append(bank)
+            if memory.number in [x.number for x in
+                                 self.get_bank_memories(bank)]:
+                banks.append(bank)
         return banks
 
+def _wipe_memory(mem):
+    mem.set_raw("\x00" * (mem.size() / 8))
+    mem.unknown1 = 0x05
+    mem.ones = 0x03
+
 @directory.register
 class VX7Radio(yaesu_clone.YaesuCloneModeRadio):
+    """Yaesu VX-7"""
     BAUD_RATE = 19200
     VENDOR = "Yaesu"
     MODEL = "VX-7"
@@ -176,7 +184,7 @@
                  ]
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_features(self):
         rf = chirp_common.RadioFeatures()
@@ -243,11 +251,6 @@
 
         return mem
 
-    def _wipe_memory(self, mem):
-        mem.set_raw("\x00" * (mem.size() / 8))
-        mem.unknown1 = 0x05
-        mem.ones = 0x03
-
     def set_memory(self, mem):
         _mem = self._memobj.memory[mem.number-1]
         _flag = self._memobj.flags[(mem.number-1)/2]
@@ -258,7 +261,7 @@
         used = _flag["%s_masked" % nibble]
 
         if not mem.empty and not valid:
-            self._wipe_memory(_mem)
+            _wipe_memory(_mem)
             self._wipe_memory_banks(mem)
 
         if mem.empty and valid and not used:
@@ -294,7 +297,8 @@
         if mem.freq >= 222000000 and mem.freq <= 225000000:
             if mem.power not in POWER_LEVELS_220:
                 msgs.append(chirp_common.ValidationError(\
-                        "Power level %s not supported on 220MHz band" % mem.power))
+                        "Power level %s not supported on 220MHz band" % \
+                            mem.power))
 
         return msgs
 
diff -r db82df47f205 -r f805c420592f chirp/vx8.py
--- a/chirp/vx8.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/vx8.py	Fri Apr 27 14:35:41 2012 -0700
@@ -16,7 +16,7 @@
 from chirp import chirp_common, yaesu_clone, directory
 from chirp import bitwise
 
-mem_format = """
+MEM_FORMAT = """
 #seekto 0x54a;
 struct {
     u16 in_use;
@@ -88,6 +88,8 @@
                 chirp_common.PowerLevel("L1", watts=0.05)]
 
 class VX8Bank(chirp_common.NamedBank):
+    """A VX-8 bank"""
+
     def get_name(self):
         _bank = self._model._radio._memobj.bank_info[self.index]
         _bank_used = self._model._radio._memobj.bank_used[self.index]
@@ -104,6 +106,7 @@
         _bank.name = [CHARSET.index(x) for x in name.ljust(16)[:16]]
 
 class VX8BankModel(chirp_common.BankModel):
+    """A VX-8 bank model"""
     def get_num_banks(self):
         return 24
 
@@ -172,8 +175,13 @@
 
         return banks
 
+def _wipe_memory(mem):
+    mem.set_raw("\x00" * (mem.size() / 8))
+    mem.unknown1 = 0x05
+
 @directory.register
 class VX8Radio(yaesu_clone.YaesuCloneModeRadio):
+    """Yaesu VX-8"""
     BAUD_RATE = 38400
     VENDOR = "Yaesu"
     MODEL = "VX-8"
@@ -185,7 +193,7 @@
     _block_size = 32
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_features(self):
         rf = chirp_common.RadioFeatures()
@@ -242,10 +250,6 @@
 
         return mem
 
-    def _wipe_memory(self, mem):
-        mem.set_raw("\x00" * (mem.size() / 8))
-        mem.unknown1 = 0x05
-
     def _debank(self, mem):
         bm = self.get_bank_model()
         for bank in bm.get_memory_banks(mem):
@@ -256,7 +260,7 @@
         flag = self._memobj.flag[mem.number-1]
 
         if not mem.empty and not flag.valid:
-            self._wipe_memory(_mem)
+            _wipe_memory(_mem)
 
         if mem.empty and flag.valid and not flag.used:
             flag.valid = False
@@ -300,5 +304,6 @@
 
 @directory.register
 class VX8DRadio(VX8Radio):
+    """Yaesu VX-8DR"""
     _model = "AH29D"
     VARIANT = "DR"
diff -r db82df47f205 -r f805c420592f chirp/vxa700.py
--- a/chirp/vxa700.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/vxa700.py	Fri Apr 27 14:35:41 2012 -0700
@@ -19,21 +19,21 @@
 import time
 import struct
 
-def debug(string):
+def _debug(string):
     pass
     print string
 
-def send(radio, data):
-    debug("Sending %s" % repr(data))
+def _send(radio, data):
+    _debug("Sending %s" % repr(data))
     radio.pipe.write(data)
     radio.pipe.flush()
     echo = radio.pipe.read(len(data))
     if len(echo) != len(data):
         raise errors.RadioError("Invalid echo")
 
-def spoonfeed(radio, data):
-    count = 0
-    debug("Writing %i:\n%s" % (len(data), util.hexprint(data)))
+def _spoonfeed(radio, data):
+    #count = 0
+    _debug("Writing %i:\n%s" % (len(data), util.hexprint(data)))
     for byte in data:
         radio.pipe.write(byte)
         radio.pipe.flush()
@@ -45,12 +45,12 @@
         if echo != byte:
             print "%02x != %02x" % (ord(echo), ord(byte))
             raise errors.RadioError("No echo?")
-        count += 1
+        #count += 1
 
-def download(radio):
+def _download(radio):
     count = 0
     data = ""
-    while len(data) < radio._memsize:
+    while len(data) < radio.get_memsize():
         count += 1
         chunk = radio.pipe.read(133)
         if len(chunk) == 0 and len(data) == 0 and count < 30:
@@ -58,10 +58,9 @@
         if len(chunk) != 132:
             raise errors.RadioError("Got short block (length %i)" % len(chunk))
 
-        flag, length, block = struct.unpack("BBB", chunk[:3])
         checksum = ord(chunk[-1])
-
-        flag, length, block, _data, checksum = struct.unpack("BBB128sB", chunk)
+        _flag, _length, _block, _data, checksum = \
+            struct.unpack("BBB128sB", chunk)
 
         cs = 0
         for byte in chunk[:-1]:
@@ -70,32 +69,31 @@
             raise errors.RadioError("Invalid checksum at 0x%02x" % len(data))
 
         data += _data
-        send(radio, "\x06")
+        _send(radio, "\x06")
 
         if radio.status_fn:
             status = chirp_common.Status()
             status.msg = "Cloning from radio"
             status.cur = len(data)
-            status.max = radio._memsize
+            status.max = radio.get_memsize()
             radio.status_fn(status)
 
     return memmap.MemoryMap(data)
 
-def upload(radio):
-    for i in range(0, radio._memsize, 128):
-        chunk = radio._mmap[i:i+128]
+def _upload(radio):
+    for i in range(0, radio.get_memsize(), 128):
+        chunk = radio.get_mmap()[i:i+128]
         cs = 0x20 + 130 + (i / 128)
         for byte in chunk:
             cs += ord(byte)
-        spoonfeed(radio,
-                  struct.pack("BBB128sB",
-                              0x20,
-                              130,
-                              i / 128,
-                              chunk,
-                              cs % 256))
+        _spoonfeed(radio,
+                   struct.pack("BBB128sB",
+                               0x20,
+                               130,
+                               i / 128,
+                               chunk,
+                               cs % 256))
         radio.pipe.write("")
-        start = time.time()
         # This is really unreliable for some reason, so just
         # blindly proceed
         # ack = radio.pipe.read(1)
@@ -109,10 +107,10 @@
             status = chirp_common.Status()
             status.msg = "Cloning to radio"
             status.cur = i
-            status.max = radio._memsize
+            status.max = radio.get_memsize()
             radio.status_fn(status)
 
-mem_format = """
+MEM_FORMAT = """
 struct memory_struct {
   u8 unknown1;
   u8 unknown2:2,
@@ -158,19 +156,24 @@
          chirp_common.PowerLevel("Low3", watts=2.500),
          chirp_common.PowerLevel("High", watts=5.000)]
 
+def _wipe_memory(_mem):
+    _mem.set_raw("\x00" * (_mem.size() / 8))
+
 @directory.register
 class VXA700Radio(chirp_common.CloneModeRadio):
+    """Vertex Standard VXA-700"""
     VENDOR = "Vertex Standard"
     MODEL = "VXA-700"
     _memsize = 4096
 
     def sync_in(self):
         try:
-            self._mmap = download(self)
+            self._mmap = _download(self)
         except errors.RadioError:
             raise
         except Exception, e:
-            raise errors.RadioError("Failed to communicate with the radio: %s" % e)
+            raise errors.RadioError("Failed to communicate " +
+                                    "with the radio: %s" % e)
         self.process_mmap()
 
     def sync_out(self):
@@ -180,14 +183,15 @@
         #            0x02 <- air band only
         try:
             self.pipe.setTimeout(2)
-            upload(self)
+            _upload(self)
         except errors.RadioError:
             raise
         except Exception, e:
-            raise errors.RadioError("Failed to communicate with the radio: %s" % e)
+            raise errors.RadioError("Failed to communicate " +
+                                    "with the radio: %s" % e)
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(mem_format, self._mmap)
+        self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
 
     def get_features(self):
         rf = chirp_common.RadioFeatures()
@@ -203,7 +207,7 @@
         rf.valid_tuning_steps = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0]
         rf.valid_modes = ["AM", "FM"]
         rf.valid_power_levels = POWER
-        rf.memory_bounds = (1,100)
+        rf.memory_bounds = (1, 100)
         return rf
 
     def _get_mem(self, number):
@@ -215,8 +219,8 @@
 
     def get_memory(self, number):
         _mem = self._get_mem(number)
-        byte = (number - 1) / 8;
-        bit = 1 << ((number - 1) % 8);
+        byte = (number - 1) / 8
+        bit = 1 << ((number - 1) % 8)
 
         mem = chirp_common.Memory()
         mem.number = number
@@ -251,13 +255,10 @@
 
         return mem
 
-    def _wipe_memory(self, _mem):
-        _mem.set_raw("\x00" * (_mem.size() / 8))
-
     def set_memory(self, mem):
         _mem = self._get_mem(mem.number)
-        byte = (mem.number - 1) / 8;
-        bit = 1 << ((mem.number - 1) % 8);
+        byte = (mem.number - 1) / 8
+        bit = 1 << ((mem.number - 1) % 8)
 
         if mem.empty and self._memobj.invisible_bits[byte] & bit:
             self._memobj.invalid_bits[byte] |= bit
@@ -267,7 +268,7 @@
             return
 
         if self._memobj.invalid_bits[byte] & bit:
-            self._wipe_memory(_mem)
+            _wipe_memory(_mem)
 
         self._memobj.invisible_bits[byte] &= ~bit
         self._memobj.invalid_bits[byte] &= ~bit
@@ -293,7 +294,7 @@
         _mem.skip = mem.skip == "S"
         try:
             _mem.power = POWER.index(mem.power)
-        except:
+        except ValueError:
             _mem.power = 3 # High
 
         for i in range(0, 8):
diff -r db82df47f205 -r f805c420592f chirp/wouxun.py
--- a/chirp/wouxun.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/wouxun.py	Fri Apr 27 14:35:41 2012 -0700
@@ -23,7 +23,7 @@
 else:
     DEBUG = False
 
-wouxun_mem_format = """
+WOUXUN_MEM_FORMAT = """
 #seekto 0x0010;
 struct {
   lbcd rx_freq[4];
@@ -50,22 +50,24 @@
 """
 
 def wouxun_identify(radio):
-    for i in range(0, 5):
+    """Do the original wouxun identification dance"""
+    for _i in range(0, 5):
         radio.pipe.write("HiWOUXUN\x02")
-        r = radio.pipe.read(9)
-        if len(r) != 9:
+        resp = radio.pipe.read(9)
+        if len(resp) != 9:
             print "Retrying identification..."
             time.sleep(1)
             continue
-        if r[2:8] != radio._model:
+        if resp[2:8] != radio._model:
             raise Exception("I can't talk to this model")
         return
-    if len(r) == 0:
+    if len(resp) == 0:
         raise Exception("Radio not responding")
     else:
         raise Exception("Unable to identify radio")
 
 def wouxun_start_transfer(radio):
+    """Tell the radio to go into transfer mode"""
     radio.pipe.write("\x02\x06")
     time.sleep(0.05)
     ack = radio.pipe.read(1)
@@ -73,6 +75,7 @@
         raise Exception("Radio refused transfer mode")    
 
 def do_download(radio, start, end, blocksize):
+    """Initiate a download of @radio between @start and @end"""
     image = ""
     for i in range(start, end, blocksize):
         cmd = struct.pack(">cHb", "R", i, blocksize)
@@ -80,30 +83,32 @@
             print util.hexprint(cmd)
         radio.pipe.write(cmd)
         length = len(cmd) + blocksize
-        r = radio.pipe.read(length)
-        if len(r) != (len(cmd) + blocksize):
-            print util.hexprint(r)
-            raise Exception("Failed to read full block (%i!=%i)" % (len(r),
-                                                                    len(cmd)+blocksize))
+        resp = radio.pipe.read(length)
+        if len(resp) != (len(cmd) + blocksize):
+            print util.hexprint(resp)
+            raise Exception("Failed to read full block (%i!=%i)" % \
+                                (len(resp),
+                                 len(cmd) + blocksize))
         
         radio.pipe.write("\x06")
         radio.pipe.read(1)
-        image += r[4:]
+        image += resp[4:]
 
         if radio.status_fn:
-            s = chirp_common.Status()           
-            s.cur = i
-            s.max = end
-            s.msg = "Cloning from radio"
-            radio.status_fn(s)
+            status = chirp_common.Status()           
+            status.cur = i
+            status.max = end
+            status.msg = "Cloning from radio"
+            radio.status_fn(status)
     
     return memmap.MemoryMap(image)
 
 def do_upload(radio, start, end, blocksize):
+    """Initiate an upload of @radio between @start and @end"""
     ptr = start
     for i in range(start, end, blocksize):
         cmd = struct.pack(">cHb", "W", i, blocksize)
-        chunk = radio._mmap[ptr:ptr+blocksize]
+        chunk = radio.get_mmap()[ptr:ptr+blocksize]
         ptr += blocksize
         radio.pipe.write(cmd + chunk)
         if DEBUG:
@@ -115,13 +120,14 @@
         #radio.pipe.write(ack)
 
         if radio.status_fn:
-            s = chirp_common.Status()
-            s.cur = i
-            s.max = end
-            s.msg = "Cloning to radio"
-            radio.status_fn(s)
+            status = chirp_common.Status()
+            status.cur = i
+            status.max = end
+            status.msg = "Cloning to radio"
+            radio.status_fn(status)
 
 def wouxun_download(radio):
+    """Talk to an original wouxun and do a download"""
     try:
         wouxun_identify(radio)
         wouxun_start_transfer(radio)
@@ -132,6 +138,7 @@
         raise errors.RadioError("Failed to communicate with radio: %s" % e)
 
 def wouxun_upload(radio):
+    """Talk to an original wouxun and do an upload"""
     try:
         wouxun_identify(radio)
         wouxun_start_transfer(radio)
@@ -147,8 +154,12 @@
 POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00),
                 chirp_common.PowerLevel("Low", watts=1.00)]
 
+def wipe_memory(_mem, byte):
+    _mem.set_raw(byte * (_mem.size() / 8))
+
 @directory.register
 class KGUVD1PRadio(chirp_common.CloneModeRadio):
+    """Wouxun KG-UVD1P,UV2,UV3"""
     VENDOR = "Wouxun"
     MODEL = "KG-UVD1P"
     _model = "KG669V"
@@ -172,7 +183,7 @@
             # format, padding 16 bytes of 0xFF in front.
             self._mmap = memmap.MemoryMap(("\xFF" * 16) + \
                                               self._mmap.get_packed()[8:8184])
-        self._memobj = bitwise.parse(wouxun_mem_format, self._mmap)
+        self._memobj = bitwise.parse(WOUXUN_MEM_FORMAT, self._mmap)
 
     def get_features(self):
         rf = chirp_common.RadioFeatures()
@@ -194,14 +205,14 @@
     def get_raw_memory(self, number):
         return repr(self._memobj.memory[number - 1])
 
-    def get_tone(self, _mem, mem):
-        def get_dcs(val):
+    def _get_tone(self, _mem, mem):
+        def _get_dcs(val):
             code = int("%03o" % (val & 0x07FF))
             pol = (val & 0x8000) and "R" or "N"
             return code, pol
             
         if _mem.tx_tone != 0xFFFF and _mem.tx_tone > 0x2800:
-            tcode, tpol = get_dcs(_mem.tx_tone)
+            tcode, tpol = _get_dcs(_mem.tx_tone)
             mem.dtcs = tcode
             txmode = "DTCS"
         elif _mem.tx_tone != 0xFFFF:
@@ -211,7 +222,7 @@
             txmode = ""
 
         if _mem.rx_tone != 0xFFFF and _mem.rx_tone > 0x2800:
-            rcode, rpol = get_dcs(_mem.rx_tone)
+            rcode, rpol = _get_dcs(_mem.rx_tone)
             mem.dtcs = rcode
             rxmode = "DTCS"
         elif _mem.rx_tone != 0xFFFF:
@@ -268,7 +279,7 @@
         if not _mem.iswide:
             mem.mode = "NFM"
 
-        self.get_tone(_mem, mem)
+        self._get_tone(_mem, mem)
 
         mem.power = POWER_LEVELS[not _mem.power_high]
 
@@ -279,11 +290,8 @@
 
         return mem
 
-    def wipe_memory(self, _mem, byte):
-        _mem.set_raw(byte * (_mem.size() / 8))
-
-    def set_tone(self, mem, _mem):
-        def set_dcs(code, pol):
+    def _set_tone(self, mem, _mem):
+        def _set_dcs(code, pol):
             val = int("%i" % code, 8) + 0x2800
             if pol == "R":
                 val += 0xA000
@@ -299,7 +307,7 @@
 
 
         if tx_mode == "DTCS":
-            _mem.tx_tone = set_dcs(mem.dtcs, mem.dtcs_polarity[0])
+            _mem.tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0])
         elif tx_mode:
             _mem.tx_tone = tx_mode == "Tone" and \
                 int(mem.rtone * 10) or int(mem.ctone * 10)
@@ -307,7 +315,7 @@
             _mem.tx_tone = 0xFFFF
 
         if rx_mode == "DTCS":
-            _mem.rx_tone = set_dcs(mem.dtcs, mem.dtcs_polarity[1])
+            _mem.rx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1])
         elif rx_mode:
             _mem.rx_tone = int(mem.ctone * 10)
         else:
@@ -322,11 +330,11 @@
         _nam = self._memobj.names[mem.number - 1]
 
         if mem.empty:
-            self.wipe_memory(_mem, "\xFF")
+            wipe_memory(_mem, "\xFF")
             return
 
         if _mem.get_raw() == ("\xFF" * 16):
-            self.wipe_memory(_mem, "\x00")
+            wipe_memory(_mem, "\x00")
 
         _mem.rx_freq = int(mem.freq / 10)
         if mem.duplex == "split":
@@ -341,7 +349,7 @@
         _mem.skip = mem.skip != "S"
         _mem.iswide = mem.mode != "NFM"
 
-        self.set_tone(mem, _mem)
+        self._set_tone(mem, _mem)
 
         if mem.power:
             _mem.power_high = not POWER_LEVELS.index(mem.power)
@@ -386,7 +394,8 @@
         raise Exception("Radio did not ACK ident")
 
 def puxing_prep(radio):
-    for i in range(0, 10):
+    """Do the Puxing PX-777 identification dance"""
+    for _i in range(0, 10):
         try:
             return _puxing_prep(radio)
         except Exception, e:
@@ -395,6 +404,7 @@
     raise e
 
 def puxing_download(radio):
+    """Talk to a Puxing PX-777 and do a download"""
     try:
         puxing_prep(radio)
         return do_download(radio, 0x0000, 0x0C60, 0x0008)
@@ -404,6 +414,7 @@
         raise errors.RadioError("Failed to communicate with radio: %s" % e)
 
 def puxing_upload(radio):
+    """Talk to a Puxing PX-777 and do an upload"""
     try:
         puxing_prep(radio)
         return do_upload(radio, 0x0000, 0x0C40, 0x0008)
@@ -412,7 +423,7 @@
     except Exception, e:
         raise errors.RadioError("Failed to communicate with radio: %s" % e)
 
-puxing_mem_format = """
+PUXING_MEM_FORMAT = """
 #seekto 0x0000;
 struct {
   lbcd rx_freq[4];
@@ -477,6 +488,7 @@
 
 @directory.register
 class Puxing777Radio(KGUVD1PRadio):
+    """Puxing PX-777"""
     VENDOR = "Puxing"
     MODEL = "PX-777"
 
@@ -513,7 +525,7 @@
         return rf
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(puxing_mem_format, self._mmap)
+        self._memobj = bitwise.parse(PUXING_MEM_FORMAT, self._mmap)
 
     @classmethod
     def match_model(cls, filedata, filename):
@@ -526,16 +538,16 @@
         _mem = self._memobj.memory[number - 1]
         _nam = self._memobj.names[number - 1]
 
-        def is_empty():
-            for i in range(0,4):
+        def _is_empty():
+            for i in range(0, 4):
                 if _mem.rx_freq[i].get_raw() != "\xFF":
                     return False
             return True
 
-        def is_no_tone(field):
+        def _is_no_tone(field):
             return field[0].get_raw() == "\xFF"
 
-        def get_dtcs(value):
+        def _get_dtcs(value):
             # Upper nibble 0x80 -> DCS, 0xC0 -> Inv. DCS
             if value > 12000:
                 return "R", value - 12000
@@ -544,19 +556,19 @@
             else:
                 raise Exception("Unable to convert DCS value")
 
-        def do_dtcs(mem, txfield, rxfield):
+        def _do_dtcs(mem, txfield, rxfield):
             if int(txfield) < 8000 or int(rxfield) < 8000:
                 raise Exception("Split tone not supported")
 
             if txfield[0].get_raw() == "\xFF":
                 tp, tx = "N", None
             else:
-                tp, tx = get_dtcs(int(txfield))
+                tp, tx = _get_dtcs(int(txfield))
             
             if rxfield[0].get_raw() == "\xFF":
                 rp, rx = "N", None
             else:
-                rp, rx = get_dtcs(int(rxfield))
+                rp, rx = _get_dtcs(int(rxfield))
 
             if not rx:
                 rx = tx
@@ -572,7 +584,7 @@
         mem = chirp_common.Memory()
         mem.number = number
 
-        if is_empty():
+        if _is_empty():
             mem.empty = True
             return mem
 
@@ -588,15 +600,15 @@
         if not _mem.iswide:
             mem.mode = "NFM"
 
-        if is_no_tone(_mem.tx_tone):
+        if _is_no_tone(_mem.tx_tone):
             pass # No tone
         elif int(_mem.tx_tone) > 8000 or \
-                (not is_no_tone(_mem.rx_tone) and int(_mem.rx_tone) > 8000):
+                (not _is_no_tone(_mem.rx_tone) and int(_mem.rx_tone) > 8000):
             mem.tmode = "DTCS"
-            do_dtcs(mem, _mem.tx_tone, _mem.rx_tone)
+            _do_dtcs(mem, _mem.tx_tone, _mem.rx_tone)
         else:
             mem.rtone = int(_mem.tx_tone) / 10.0
-            mem.tmode = is_no_tone(_mem.rx_tone) and "Tone" or "TSQL"
+            mem.tmode = _is_no_tone(_mem.rx_tone) and "Tone" or "TSQL"
 
         mem.power = POWER_LEVELS[not _mem.power_high]
 
@@ -612,7 +624,7 @@
         _nam = self._memobj.names[mem.number - 1]
 
         if mem.empty:
-            self.wipe_memory(_mem, "\xFF")
+            wipe_memory(_mem, "\xFF")
             return
 
         _mem.rx_freq = mem.freq / 10
@@ -666,6 +678,7 @@
                 raise Exception("Character `%s' not supported")
 
 def puxing_2r_prep(radio):
+    """Do the Puxing 2R identification dance"""
     radio.pipe.setTimeout(0.2)
     radio.pipe.write("PROGRAM\x02")
     ack = radio.pipe.read(1)
@@ -677,6 +690,7 @@
     print "Radio ident: %s (%i)" % (repr(ident), len(ident))
 
 def puxing_2r_download(radio):
+    """Talk to a Puxing 2R and do a download"""
     try:
         puxing_2r_prep(radio)
         return do_download(radio, 0x0000, 0x0FE0, 0x0010)
@@ -686,6 +700,7 @@
         raise errors.RadioError("Failed to communicate with radio: %s" % e)
 
 def puxing_2r_upload(radio):
+    """Talk to a Puxing 2R and do an upload"""
     try:
         puxing_2r_prep(radio)
         return do_upload(radio, 0x0000, 0x0FE0, 0x0010)
@@ -694,7 +709,7 @@
     except Exception, e:
         raise errors.RadioError("Failed to communicate with radio: %s" % e)
 
-puxing_2r_mem_format = """
+PUXING_2R_MEM_FORMAT = """
 #seekto 0x0010;
 struct {
   lbcd freq[4];
@@ -719,6 +734,7 @@
 
 @directory.register
 class Puxing2RRadio(KGUVD1PRadio):
+    """Puxing PX-2R"""
     VENDOR = "Puxing"
     MODEL = "PX-2R"
     _memsize = 0x0FE0
@@ -753,7 +769,7 @@
         puxing_2r_upload(self)
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(puxing_2r_mem_format, self._mmap)
+        self._memobj = bitwise.parse(PUXING_2R_MEM_FORMAT, self._mmap)
 
     def get_memory(self, number):
         _mem = self._memobj.memory[number-1]
@@ -780,16 +796,17 @@
             mem.rtone = chirp_common.TONES[_mem.tx_tone - 1]
             mem.tmode = _mem.rx_tone and "TSQL" or "Tone"
 
-        c = 0
+        count = 0
         for i in _mem.name:
             if i == 0xFF:
                 break
             try:
                 mem.name += PX2R_CHARSET[i]
-            except:
-                print "Unknown name char %i: 0x%02x (mem %i)" % (c, i, number)
+            except Exception:
+                print "Unknown name char %i: 0x%02x (mem %i)" % (count,
+                                                                 i, number)
                 mem.name += " "
-            c += 1
+            count += 1
         mem.name = mem.name.rstrip()
 
         return mem
@@ -845,7 +862,8 @@
         raise errors.RadioError("Radio did not ACK ident")
 
 def uv3r_prep(radio):
-    for i in range(0, 10):
+    """Do the UV3R identification dance"""
+    for _i in range(0, 10):
         try:
             return _uv3r_prep(radio)
         except errors.RadioError, e:
@@ -854,6 +872,7 @@
     raise e
 
 def uv3r_download(radio):
+    """Talk to a UV3R and do a download"""
     try:
         uv3r_prep(radio)
         return do_download(radio, 0x0000, 0x0E40, 0x0010)
@@ -863,6 +882,7 @@
         raise errors.RadioError("Failed to communicate with radio: %s" % e)
 
 def uv3r_upload(radio):
+    """Talk to a UV3R and do an upload"""
     try:
         uv3r_prep(radio)
         return do_upload(radio, 0x0000, 0x0E40, 0x0010)
@@ -871,7 +891,7 @@
     except Exception, e:
         raise errors.RadioError("Failed to communicate with radio: %s" % e)
 
-uv3r_mem_format = """
+UV3R_MEM_FORMAT = """
 #seekto 0x0010;
 struct {
   lbcd rx_freq[4];
@@ -920,6 +940,7 @@
 
 @directory.register
 class UV3RRadio(KGUVD1PRadio):
+    """Baofeng UV-3R"""
     VENDOR = "Baofeng"
     MODEL = "UV-3R"
 
@@ -950,7 +971,7 @@
         uv3r_upload(self)
 
     def process_mmap(self):
-        self._memobj = bitwise.parse(uv3r_mem_format, self._mmap)
+        self._memobj = bitwise.parse(UV3R_MEM_FORMAT, self._mmap)
 
     def get_memory(self, number):
         _mem = self._memobj.rx_memory[number - 1]
@@ -962,7 +983,7 @@
             return mem
 
         mem.freq = int(_mem.rx_freq) * 10
-        mem.offset = int(_mem.offset) * 10;
+        mem.offset = int(_mem.offset) * 10
         mem.duplex = UV3R_DUPLEX[_mem.duplex]
         if mem.offset > 60000000:
             if mem.duplex == "+":
diff -r db82df47f205 -r f805c420592f chirp/xml_ll.py
--- a/chirp/xml_ll.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/xml_ll.py	Fri Apr 27 14:35:41 2012 -0700
@@ -13,12 +13,12 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import errors
 import re
 
-from chirp import chirp_common
+from chirp import chirp_common, errors
 
 def get_memory(doc, number):
+    """Extract a Memory object from @doc"""
     ctx = doc.xpathNewContext()
 
     base = "//radio/memories/memory[@location=%i]" % number
@@ -98,6 +98,7 @@
     return mem
 
 def set_memory(doc, mem):
+    """Set @mem in @doc"""
     ctx = doc.xpathNewContext()
 
     base = "//radio/memories/memory[@location=%i]" % mem.number
@@ -105,7 +106,7 @@
     fields = ctx.xpathEval(base)
     if len(fields) > 1:
         raise errors.RadioError("%i memories claiming to be %i" % (len(fields),
-                                                                   number))
+                                                                   mem.number))
     elif len(fields) == 1:
         fields[0].unlinkNode()
 
@@ -197,6 +198,7 @@
         dc.addContent(str(mem.dv_code))
 
 def del_memory(doc, number):
+    """Remove memory @number from @doc"""
     path = "//radio/memories/memory[@location=%i]" % number
     ctx = doc.xpathNewContext()
     fields = ctx.xpathEval(path)
@@ -206,11 +208,12 @@
     
 def _get_bank(node):
     bank = chirp_common.Bank(node.prop("label"))
-    id = int(node.prop("id"))
+    ident = int(node.prop("id"))
 
-    return id, bank
+    return ident, bank
 
 def get_banks(doc):
+    """Return a list of banks from @doc"""
     path = "//radio/banks/bank"
     ctx = doc.xpathNewContext()
     fields = ctx.xpathEval(path)
@@ -219,14 +222,15 @@
     for field in fields:
         banks.append(_get_bank(field))
 
-    def cmp(x, y):
-        return x[0] - y[0]
+    def _cmp(itema, itemb):
+        return itema[0] - itemb[0]
 
-    banks.sort(cmp=cmp)
+    banks.sort(cmp=_cmp)
 
     return [x[1] for x in banks]
 
 def set_banks(doc, banklist):
+    """Set the list of banks in @doc"""
     path = "//radio/banks/bank"
     ctx = doc.xpathNewContext()
     fields = ctx.xpathEval(path)
diff -r db82df47f205 -r f805c420592f chirp/yaesu_clone.py
--- a/chirp/yaesu_clone.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirp/yaesu_clone.py	Fri Apr 27 14:35:41 2012 -0700
@@ -18,10 +18,10 @@
 from chirp import chirp_common, util, memmap, errors
 import time, os
 
-def safe_read(pipe, count, times=60):
+def _safe_read(pipe, count):
     buf = ""
     first = True
-    for i in range(0, 60):
+    for _i in range(0, 60):
         buf += pipe.read(count - len(buf))
         #print "safe_read: %i/%i\n" % (len(buf), count)
         if buf:
@@ -34,17 +34,15 @@
     print util.hexprint(buf)
     return buf
 
-def chunk_read(pipe, count, status_fn):
+def _chunk_read(pipe, count, status_fn):
     block = 32
     data = ""
-    first = True
-    for i in range(0, count, block):
+    for _i in range(0, count, block):
         data += pipe.read(block)
         if data:
             if data[0] == chr(CMD_ACK):
                 data = data[1:] # Chew an echo'd ack if using a 2-pin cable
                 #print "Chewed an ack"
-            first = False
         status = chirp_common.Status()
         status.msg = "Cloning from radio"
         status.max = count
@@ -54,7 +52,7 @@
             print "Read %i/%i" % (len(data), count)
     return data        
 
-def _clone_in(radio):
+def __clone_in(radio):
     pipe = radio.pipe
 
     start = time.time()
@@ -64,28 +62,28 @@
     for block in radio._block_lengths:
         blocks += 1
         if blocks == len(radio._block_lengths):
-            chunk = chunk_read(pipe, block, radio.status_fn)
+            chunk = _chunk_read(pipe, block, radio.status_fn)
         else:
-            chunk = safe_read(pipe, block)
+            chunk = _safe_read(pipe, block)
             pipe.write(chr(CMD_ACK))
         if not chunk:
             raise errors.RadioError("No response from radio")
         data += chunk
 
-    if len(data) != radio._memsize:
+    if len(data) != radio.get_memsize():
         raise errors.RadioError("Received incomplete image from radio")
 
     print "Clone completed in %i seconds" % (time.time() - start)
 
     return memmap.MemoryMap(data)
 
-def clone_in(radio):
+def _clone_in(radio):
     try:
-        return _clone_in(radio)
+        return __clone_in(radio)
     except Exception, e:
         raise errors.RadioError("Failed to communicate with the radio: %s" % e)
 
-def chunk_write(pipe, data, status_fn, block):
+def _chunk_write(pipe, data, status_fn, block):
     delay = 0.03
     count = 0
     for i in range(0, len(data), block):
@@ -101,15 +99,15 @@
         status.cur = count
         status_fn(status)
         
-def _clone_out(radio):
+def __clone_out(radio):
     pipe = radio.pipe
-    l = radio._block_lengths
+    block_lengths = radio._block_lengths
     total_written = 0
 
-    def status():
+    def _status():
         status = chirp_common.Status()
         status.msg = "Cloning to radio"
-        status.max = l[0] + l[1] + l[2]
+        status.max = block_lengths[0] + block_lengths[1] + block_lengths[2]
         status.cur = total_written
         radio.status_fn(status)
 
@@ -121,28 +119,29 @@
         blocks += 1
         if blocks != len(radio._block_lengths):
             #print "Sending %i-%i" % (pos, pos+block)
-            pipe.write(radio._mmap[pos:pos+block])
+            pipe.write(radio.get_mmap()[pos:pos+block])
             buf = pipe.read(1)
             if buf and buf[0] != chr(CMD_ACK):
                 buf = pipe.read(block)
             if not buf or buf[-1] != chr(CMD_ACK):
                 raise Exception("Radio did not ack block %i" % blocks)
         else:
-            chunk_write(pipe, radio._mmap[pos:],
-                        radio.status_fn, radio._block_size)
+            _chunk_write(pipe, radio.get_mmap()[pos:],
+                         radio.status_fn, radio._block_size)
         pos += block
 
     pipe.read(pos) # Chew the echo if using a 2-pin cable
 
     print "Clone completed in %i seconds" % (time.time() - start)
 
-def clone_out(radio):
+def _clone_out(radio):
     try:
-        return _clone_out(radio)
+        return __clone_out(radio)
     except Exception, e:
         raise errors.RadioError("Failed to communicate with the radio: %s" % e)
 
 class YaesuChecksum:
+    """A Yaesu Checksum Object"""
     def __init__(self, start, stop, address=None):
         self._start = start
         self._stop = stop
@@ -156,12 +155,14 @@
         return ord(mmap[self._address])
 
     def get_calculated(self, mmap):
+        """Return the calculated value of the checksum"""
         cs = 0
         for i in range(self._start, self._stop+1):
             cs += ord(mmap[i])
         return cs % 256
 
     def update(self, mmap):
+        """Update the checksum with the data in @mmap"""
         mmap[self._address] = self.get_calculated(mmap)
 
     def __str__(self):
@@ -170,6 +171,7 @@
                                       self._address)
 
 class YaesuCloneModeRadio(chirp_common.CloneModeRadio):
+    """Base class for all Yaesu clone-mode radios"""
     _block_lengths = [8, 65536]
     _block_size = 8
 
@@ -181,10 +183,12 @@
         return []
 
     def update_checksums(self):
+        """Update the radio's checksums from the current memory map"""
         for checksum in self._checksums():
             checksum.update(self._mmap)
 
     def check_checksums(self):
+        """Validate the checksums stored in the memory map"""
         for checksum in self._checksums():
             if checksum.get_existing(self._mmap) != \
                     checksum.get_calculated(self._mmap):
@@ -192,13 +196,13 @@
             print "Checksum %s: OK" % checksum
 
     def sync_in(self):
-        self._mmap = clone_in(self)
+        self._mmap = _clone_in(self)
         self.check_checksums()
         self.process_mmap()
 
     def sync_out(self):
         self.update_checksums()
-        clone_out(self)
+        _clone_out(self)
 
     @classmethod
     def match_model(cls, filedata, filename):
@@ -209,24 +213,3 @@
         bm = self.get_bank_model()
         for bank in bm.get_memory_banks(mem):
             bm.remove_memory_from_bank(mem, bank)
-
-
-if __name__ == "__main__":
-    import sys, serial
-    s = serial.Serial(port=sys.argv[1], baudrate=19200, timeout=5)
-
-    d = s.read(20)
-    print util.hexprint(d)
-
-    s.write(chr(0x06))
-
-    d = ""
-    while True:
-        c = s.read(32)
-        if not c:
-            break
-        d += c
-
-    print len(d)
-
-    
diff -r db82df47f205 -r f805c420592f chirpui/clone.py
--- a/chirpui/clone.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirpui/clone.py	Fri Apr 27 14:35:41 2012 -0700
@@ -191,7 +191,7 @@
 class CloneCancelledException(Exception):
     pass
 
-class CloneThread(chirp_common.KillableThread):
+class CloneThread(threading.Thread):
     def __status(self, status):
         gobject.idle_add(self.__progw.status, status)
 
diff -r db82df47f205 -r f805c420592f chirpui/mainapp.py
--- a/chirpui/mainapp.py	Fri Apr 27 14:35:40 2012 -0700
+++ b/chirpui/mainapp.py	Fri Apr 27 14:35:41 2012 -0700
@@ -887,7 +887,7 @@
         else:
             from chirp import rfinder
             radio = rfinder.RFinderRadio(None)
-            radio.set_params(lat, lon, miles, email, passwd)
+            radio.set_params((lat, lon), miles, email, passwd)
             self.do_open_live(radio, read_only=True)
 
         self.window.set_cursor(None)



More information about the chirp_devel mailing list