[chirp_devel] [PATCH 06/22] Fix style issues in chirp_common.py (#2355)
Zach Welch
Sat Feb 28 22:54:43 PST 2015
# HG changeset patch
# User Zach Welch <zach at mandolincreekfarm.com>
# Fake Node ID 8ca493958755d28295808b2248f29883f98c9169
Fix style issues in chirp_common.py (#2355)
diff --git a/chirp/chirp_common.py b/chirp/chirp_common.py
index 5c4e4f3..1566cc5 100644
--- a/chirp/chirp_common.py
+++ b/chirp/chirp_common.py
@@ -13,24 +13,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-SEPCHAR = ","
-
-#print "Using separation character of '%s'" % SEPCHAR
-
import math
-
from chirp import errors, memmap
+SEPCHAR = ","
+
# 50 Tones
-TONES = [ 67.0, 69.3, 71.9, 74.4, 77.0, 79.7, 82.5,
- 85.4, 88.5, 91.5, 94.8, 97.4, 100.0, 103.5,
- 107.2, 110.9, 114.8, 118.8, 123.0, 127.3,
- 131.8, 136.5, 141.3, 146.2, 151.4, 156.7,
- 159.8, 162.2, 165.5, 167.9, 171.3, 173.8,
- 177.3, 179.9, 183.5, 186.2, 189.9, 192.8,
- 196.6, 199.5, 203.5, 206.5, 210.7, 218.1,
- 225.7, 229.1, 233.6, 241.8, 250.3, 254.1,
- ]
+TONES = [67.0, 69.3, 71.9, 74.4, 77.0, 79.7, 82.5,
+ 85.4, 88.5, 91.5, 94.8, 97.4, 100.0, 103.5,
+ 107.2, 110.9, 114.8, 118.8, 123.0, 127.3,
+ 131.8, 136.5, 141.3, 146.2, 151.4, 156.7,
+ 159.8, 162.2, 165.5, 167.9, 171.3, 173.8,
+ 177.3, 179.9, 183.5, 186.2, 189.9, 192.8,
+ 196.6, 199.5, 203.5, 206.5, 210.7, 218.1,
+ 225.7, 229.1, 233.6, 241.8, 250.3, 254.1,
+ ]
TONES_EXTRA = [62.5]
@@ -40,8 +37,8 @@ OLD_TONES = list(TONES)
# 104 DTCS Codes
DTCS_CODES = [
- 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54,
- 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131,
+ 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54,
+ 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131,
132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174,
205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252,
255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325,
@@ -50,7 +47,7 @@ DTCS_CODES = [
465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606,
612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723,
731, 732, 734, 743, 754,
- ]
+ ]
# 512 Possible DTCS Codes
ALL_DTCS_CODES = []
@@ -90,7 +87,7 @@ TUNING_STEPS = [
9.0, 1.0, 2.5,
]
-SKIP_VALUES = [ "", "S", "P" ]
+SKIP_VALUES = ["", "S", "P"]
CHARSET_UPPER_NUMERIC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890"
CHARSET_ALPHANUMERIC = \
@@ -143,14 +140,17 @@ APRS_SYMBOLS = (
"TDB", "[reserved]"
)
+
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):
@@ -188,6 +188,7 @@ class PowerLevel:
def __repr__(self):
return "%s (%i dBm)" % (self._label, self._power)
+
def parse_freq(freqstr):
"""Parse a frequency string and return the value in integral Hz"""
freqstr = freqstr.strip()
@@ -213,14 +214,17 @@ def parse_freq(freqstr):
return mhz + khz
+
def format_freq(freq):
"""Format a frequency given in Hz as a string"""
return "%i.%06i" % (freq / 1000000, freq % 1000000)
+
class ImmutableValueError(ValueError):
pass
+
class Memory:
"""Base class for a single radio memory"""
freq = 0
@@ -279,18 +283,18 @@ class Memory:
self.immutable = []
_valid_map = {
- "rtone" : TONES + TONES_EXTRA,
- "ctone" : TONES + TONES_EXTRA,
- "dtcs" : ALL_DTCS_CODES,
- "rx_dtcs" : ALL_DTCS_CODES,
- "tmode" : TONE_MODES,
- "dtcs_polarity" : ["NN", "NR", "RN", "RR"],
- "cross_mode" : CROSS_MODES,
- "mode" : MODES,
- "duplex" : ["", "+", "-", "split", "off"],
- "skip" : SKIP_VALUES,
- "empty" : [True, False],
- "dv_code" : [x for x in range(0, 100)],
+ "rtone": TONES + TONES_EXTRA,
+ "ctone": TONES + TONES_EXTRA,
+ "dtcs": ALL_DTCS_CODES,
+ "rx_dtcs": ALL_DTCS_CODES,
+ "tmode": TONE_MODES,
+ "dtcs_polarity": ["NN", "NR", "RN", "RR"],
+ "cross_mode": CROSS_MODES,
+ "mode": MODES,
+ "duplex": ["", "+", "-", "split", "off"],
+ "skip": SKIP_VALUES,
+ "empty": [True, False],
+ "dv_code": [x for x in range(0, 100)],
}
def __repr__(self):
@@ -324,10 +328,9 @@ class Memory:
raise ImmutableValueError("Field %s is not " % name +
"mutable on this memory")
- if self._valid_map.has_key(name) and val not in self._valid_map[name]:
- raise ValueError("`%s' is not in valid list: %s" % (\
- val,
- self._valid_map[name]))
+ if name in self._valid_map and val not in self._valid_map[name]:
+ raise ValueError("`%s' is not in valid list: %s" %
+ (val, self._valid_map[name]))
self.__dict__[name] = val
@@ -361,7 +364,7 @@ class Memory:
else:
dup = self.duplex
- return "Memory %i: %s%s%s %s (%s) r%.1f%s c%.1f%s d%03i%s%s [%.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,
@@ -380,20 +383,20 @@ class Memory:
def to_csv(self):
"""Return a CSV representation of this memory"""
return [
- "%i" % self.number,
- "%s" % self.name,
+ "%i" % self.number,
+ "%s" % self.name,
format_freq(self.freq),
- "%s" % self.duplex,
+ "%s" % self.duplex,
format_freq(self.offset),
- "%s" % self.tmode,
+ "%s" % self.tmode,
"%.1f" % self.rtone,
"%.1f" % self.ctone,
"%03i" % self.dtcs,
- "%s" % self.dtcs_polarity,
- "%s" % self.mode,
+ "%s" % self.dtcs_polarity,
+ "%s" % self.mode,
"%.2f" % self.tuning_step,
- "%s" % self.skip,
- "%s" % self.comment,
+ "%s" % self.skip,
+ "%s" % self.comment,
"", "", "", ""]
@classmethod
@@ -442,7 +445,8 @@ class Memory:
self.tmode = vals[5]
if self.tmode not in TONE_MODES:
- raise errors.InvalidDataError("Invalid tone mode `%s'" % self.tmode)
+ raise errors.InvalidDataError("Invalid tone mode `%s'" %
+ self.tmode)
try:
self.rtone = float(vals[6])
@@ -494,6 +498,7 @@ class Memory:
return True
+
class DVMemory(Memory):
"""A Memory with D-STAR attributes"""
dv_urcall = "CQCQCQ"
@@ -512,24 +517,24 @@ class DVMemory(Memory):
def to_csv(self):
return [
- "%i" % self.number,
- "%s" % self.name,
+ "%i" % self.number,
+ "%s" % self.name,
format_freq(self.freq),
- "%s" % self.duplex,
+ "%s" % self.duplex,
format_freq(self.offset),
- "%s" % self.tmode,
+ "%s" % self.tmode,
"%.1f" % self.rtone,
"%.1f" % self.ctone,
"%03i" % self.dtcs,
- "%s" % self.dtcs_polarity,
- "%s" % self.mode,
+ "%s" % self.dtcs_polarity,
+ "%s" % self.mode,
"%.2f" % self.tuning_step,
- "%s" % self.skip,
+ "%s" % self.skip,
"%s" % self.comment,
- "%s" % self.dv_urcall,
- "%s" % self.dv_rpt1call,
- "%s" % self.dv_rpt2call,
- "%i" % self.dv_code]
+ "%s" % self.dv_urcall,
+ "%s" % self.dv_rpt1call,
+ "%s" % self.dv_rpt2call,
+ "%i" % self.dv_code]
def really_from_csv(self, vals):
Memory.really_from_csv(self, vals)
@@ -542,6 +547,7 @@ class DVMemory(Memory):
except Exception:
self.dv_code = 0
+
class MemoryMapping(object):
"""Base class for a memory mapping"""
def __init__(self, model, index, name):
@@ -566,6 +572,7 @@ class MemoryMapping(object):
def __eq__(self, other):
return self.get_index() == other.get_index()
+
class MappingModel(object):
"""Base class for a memory mapping model"""
@@ -602,20 +609,24 @@ class MappingModel(object):
"""Return a list of mappings that @memory is in"""
raise NotImplementedError()
+
class Bank(MemoryMapping):
"""Base class for a radio's Bank"""
+
class NamedBank(Bank):
"""A bank that can have a name"""
def set_name(self, name):
"""Changes the user-adjustable bank name"""
self._name = name
+
class BankModel(MappingModel):
"""A bank model where one memory is in zero or one banks at any point"""
def __init__(self, radio, name='Banks'):
super(BankModel, self).__init__(radio, name)
+
class MappingModelIndexInterface:
"""Interface for mappings with index capabilities"""
def get_index_bounds(self):
@@ -635,10 +646,12 @@ class MappingModelIndexInterface:
Exception if full"""
raise NotImplementedError()
+
class MTOBankModel(BankModel):
"""A bank model where one memory can be in multiple banks at once """
pass
+
def console_status(status):
"""Write a status object to the console"""
import sys
@@ -656,76 +669,77 @@ class RadioPrompts:
BOOLEAN = [True, False]
+
class RadioFeatures:
"""Radio Feature Flags"""
_valid_map = {
# General
- "has_bank_index" : BOOLEAN,
- "has_dtcs" : BOOLEAN,
- "has_rx_dtcs" : BOOLEAN,
- "has_dtcs_polarity" : BOOLEAN,
- "has_mode" : BOOLEAN,
- "has_offset" : BOOLEAN,
- "has_name" : BOOLEAN,
- "has_bank" : BOOLEAN,
- "has_bank_names" : BOOLEAN,
- "has_tuning_step" : BOOLEAN,
- "has_ctone" : BOOLEAN,
- "has_cross" : BOOLEAN,
- "has_infinite_number" : BOOLEAN,
- "has_nostep_tuning" : BOOLEAN,
- "has_comment" : BOOLEAN,
- "has_settings" : BOOLEAN,
+ "has_bank_index": BOOLEAN,
+ "has_dtcs": BOOLEAN,
+ "has_rx_dtcs": BOOLEAN,
+ "has_dtcs_polarity": BOOLEAN,
+ "has_mode": BOOLEAN,
+ "has_offset": BOOLEAN,
+ "has_name": BOOLEAN,
+ "has_bank": BOOLEAN,
+ "has_bank_names": BOOLEAN,
+ "has_tuning_step": BOOLEAN,
+ "has_ctone": BOOLEAN,
+ "has_cross": BOOLEAN,
+ "has_infinite_number": BOOLEAN,
+ "has_nostep_tuning": BOOLEAN,
+ "has_comment": BOOLEAN,
+ "has_settings": BOOLEAN,
# Attributes
- "valid_modes" : [],
- "valid_tmodes" : [],
- "valid_duplexes" : [],
- "valid_tuning_steps" : [],
- "valid_bands" : [],
- "valid_skips" : [],
- "valid_power_levels" : [],
- "valid_characters" : "",
- "valid_name_length" : 0,
- "valid_cross_modes" : [],
- "valid_dtcs_pols" : [],
- "valid_dtcs_codes" : [],
- "valid_special_chans" : [],
-
- "has_sub_devices" : BOOLEAN,
- "memory_bounds" : (0, 0),
- "can_odd_split" : BOOLEAN,
+ "valid_modes": [],
+ "valid_tmodes": [],
+ "valid_duplexes": [],
+ "valid_tuning_steps": [],
+ "valid_bands": [],
+ "valid_skips": [],
+ "valid_power_levels": [],
+ "valid_characters": "",
+ "valid_name_length": 0,
+ "valid_cross_modes": [],
+ "valid_dtcs_pols": [],
+ "valid_dtcs_codes": [],
+ "valid_special_chans": [],
+
+ "has_sub_devices": BOOLEAN,
+ "memory_bounds": (0, 0),
+ "can_odd_split": BOOLEAN,
# D-STAR
- "requires_call_lists" : BOOLEAN,
- "has_implicit_calls" : BOOLEAN,
+ "requires_call_lists": BOOLEAN,
+ "has_implicit_calls": BOOLEAN,
}
def __setattr__(self, name, val):
if name.startswith("_"):
self.__dict__[name] = val
return
- elif not name in self._valid_map.keys():
+ elif name not in self._valid_map.keys():
raise ValueError("No such attribute `%s'" % name)
if type(self._valid_map[name]) == tuple:
# Tuple, cardinality must match
if type(val) != tuple or len(val) != len(self._valid_map[name]):
- raise ValueError("Invalid value `%s' for attribute `%s'" % \
- (val, name))
+ raise ValueError("Invalid value `%s' for attribute `%s'" %
+ (val, name))
elif type(self._valid_map[name]) == list and not self._valid_map[name]:
# Empty list, must be another list
if type(val) != list:
- raise ValueError("Invalid value `%s' for attribute `%s'" % \
- (val, name))
+ raise ValueError("Invalid value `%s' for attribute `%s'" %
+ (val, name))
elif type(self._valid_map[name]) == str:
if type(val) != str:
- raise ValueError("Invalid value `%s' for attribute `%s'" % \
- (val, name))
+ raise ValueError("Invalid value `%s' for attribute `%s'" %
+ (val, name))
elif type(self._valid_map[name]) == int:
if type(val) != int:
- raise ValueError("Invalid value `%s' for attribute `%s'" % \
- (val, name))
+ raise ValueError("Invalid value `%s' for attribute `%s'" %
+ (val, name))
elif val not in self._valid_map[name]:
# Value not in the list of valid values
raise ValueError("Invalid value `%s' for attribute `%s'" % (val,
@@ -753,7 +767,8 @@ class RadioFeatures:
self.init("has_dtcs", True,
"Indicates that DTCS tone mode is available")
self.init("has_rx_dtcs", False,
- "Indicates that radio can use two different DTCS codes for rx and tx")
+ "Indicates that radio can use two different " +
+ "DTCS codes for rx and tx")
self.init("has_dtcs_polarity", True,
"Indicates that the DTCS polarity can be changed")
self.init("has_mode", True,
@@ -851,8 +866,8 @@ class RadioFeatures:
msgs.append(msg)
if (self.valid_modes and
- mem.mode not in self.valid_modes and
- mem.mode != "Auto"):
+ mem.mode not in self.valid_modes and
+ mem.mode != "Auto"):
msg = ValidationError("Mode %s not supported" % mem.mode)
msgs.append(msg)
@@ -863,14 +878,14 @@ class RadioFeatures:
if mem.tmode == "Cross":
if self.valid_cross_modes and \
mem.cross_mode not in self.valid_cross_modes:
- msg = ValidationError("Cross tone mode %s not supported" % \
- mem.cross_mode)
+ msg = ValidationError("Cross tone mode %s not supported" %
+ mem.cross_mode)
msgs.append(msg)
if self.has_dtcs_polarity and \
mem.dtcs_polarity not in self.valid_dtcs_pols:
- msg = ValidationError("DTCS Polarity %s not supported" % \
- mem.dtcs_polarity)
+ msg = ValidationError("DTCS Polarity %s not supported" %
+ mem.dtcs_polarity)
msgs.append(msg)
if self.valid_dtcs_codes and \
@@ -912,8 +927,8 @@ class RadioFeatures:
try:
step = required_step(mem.freq)
if step not in self.valid_tuning_steps:
- msg = ValidationError("Frequency requires %.2fkHz step" %\
- required_step(mem.freq))
+ msg = ValidationError("Frequency requires %.2fkHz step" %
+ required_step(mem.freq))
msgs.append(msg)
except errors.InvalidDataError, e:
msgs.append(str(e))
@@ -928,18 +943,22 @@ class RadioFeatures:
return msgs
+
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(object):
"""Base class for all Radio drivers"""
BAUD_RATE = 9600
@@ -1042,6 +1061,7 @@ class Radio(object):
should be True and get_settings() must be implemented as well."""
pass
+
class FileBackedRadio(Radio):
"""A file-backed radio stores its data in a file"""
FILE_EXTENSION = "img"
@@ -1086,7 +1106,6 @@ class FileBackedRadio(Radio):
return self._mmap
-
class CloneModeRadio(FileBackedRadio):
"""A clone-mode radio does a full memory dump in and out and we store
an image of the radio into an image file"""
@@ -1131,16 +1150,19 @@ class CloneModeRadio(FileBackedRadio):
"Initiate a PC-to-radio clone operation"
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)
@@ -1171,6 +1193,7 @@ class IcomDstarSupport:
"""Set the MYCALL callsign list"""
pass
+
class ExperimentalRadio:
"""Interface for experimental radios"""
@classmethod
@@ -1178,6 +1201,7 @@ class ExperimentalRadio:
return ("This radio's driver is marked as experimental and may " +
"be unstable or unsafe to use.")
+
class Status:
"""Clone status object for conveying clone progress to the UI"""
name = "Job"
@@ -1196,26 +1220,32 @@ class Status:
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):
@@ -1228,9 +1258,9 @@ def required_step(freq):
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
@@ -1259,8 +1289,9 @@ def fix_rounded_step(freq):
except errors.InvalidDataError:
pass
- raise errors.InvalidDataError("Unable to correct rounded frequency " + \
- format_freq(freq))
+ raise errors.InvalidDataError("Unable to correct rounded frequency " +
+ format_freq(freq))
+
def _name(name, len, just_upper):
"""Justify @name to @len, optionally converting to all uppercase"""
@@ -1268,42 +1299,52 @@ def _name(name, len, 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)
+
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
+
def split_tone_decode(mem, txtone, rxtone):
"""
Set tone mode and values on @mem based on txtone and rxtone specs like:
@@ -1349,6 +1390,7 @@ def split_tone_decode(mem, txtone, rxtone):
elif rxmode == "DTCS":
mem.rx_dtcs = rxval
+
def split_tone_encode(mem):
"""
Returns TX, RX tone specs based on @mem like:
diff --git a/tools/cpep8.blacklist b/tools/cpep8.blacklist
index aad6343..5213d75 100644
--- a/tools/cpep8.blacklist
+++ b/tools/cpep8.blacklist
@@ -13,7 +13,6 @@
./chirp/baofeng_uv3r.py
./chirp/bitwise.py
./chirp/bjuv55.py
-./chirp/chirp_common.py
./chirp/elib_intl.py
./chirp/ft1802.py
./chirp/ft1d.py
More information about the chirp_devel
mailing list