diff options
Diffstat (limited to 'grc/core/Param.py')
-rw-r--r-- | grc/core/Param.py | 153 |
1 files changed, 61 insertions, 92 deletions
diff --git a/grc/core/Param.py b/grc/core/Param.py index d155800c43..35bb176744 100644 --- a/grc/core/Param.py +++ b/grc/core/Param.py @@ -17,20 +17,20 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA """ +from __future__ import absolute_import + import ast import weakref import re +import collections + +from six.moves import builtins, filter, map, range, zip from . import Constants -from .Constants import VECTOR_TYPES, COMPLEX_TYPES, REAL_TYPES, INT_TYPES from .Element import Element -from .utils import odict # Blacklist certain ids, its not complete, but should help -import __builtin__ - - -ID_BLACKLIST = ['self', 'options', 'gr', 'blks2', 'wxgui', 'wx', 'math', 'forms', 'firdes'] + dir(__builtin__) +ID_BLACKLIST = ['self', 'options', 'gr', 'blks2', 'wxgui', 'wx', 'math', 'forms', 'firdes'] + dir(builtins) try: from gnuradio import gr ID_BLACKLIST.extend(attr for attr in dir(gr.top_block()) if not attr.startswith('_')) @@ -64,7 +64,7 @@ def num_to_str(num): return template.format(value / factor, symbol.strip()) return template.format(value, '') - if isinstance(num, COMPLEX_TYPES): + if isinstance(num, Constants.COMPLEX_TYPES): num = complex(num) # Cast to python complex if num == 0: return '0' @@ -79,12 +79,12 @@ class Option(Element): def __init__(self, param, n): Element.__init__(self, param) - self._name = n.find('name') - self._key = n.find('key') + self._name = n.get('name') + self._key = n.get('key') self._opts = dict() - opts = n.findall('opt') + opts = n.get('opt', []) # Test against opts when non enum - if not self.get_parent().is_enum() and opts: + if not self.parent.is_enum() and opts: raise Exception('Options for non-enum types cannot have sub-options') # Extract opts for opt in opts: @@ -112,13 +112,13 @@ class Option(Element): # Access Opts ############################################## def get_opt_keys(self): - return self._opts.keys() + return list(self._opts.keys()) def get_opt(self, key): return self._opts[key] def get_opts(self): - return self._opts.values() + return list(self._opts.values()) class TemplateArg(object): @@ -155,7 +155,7 @@ class Param(Element): n: the nested odict """ # If the base key is a valid param key, copy its data and overlay this params data - base_key = n.find('base_key') + base_key = n.get('base_key') if base_key and base_key in block.get_param_keys(): n_expanded = block.get_param(base_key)._n.copy() n_expanded.update(n) @@ -163,20 +163,21 @@ class Param(Element): # Save odict in case this param will be base for another self._n = n # Parse the data - self._name = n.find('name') - self._key = n.find('key') - value = n.find('value') or '' - self._type = n.find('type') or 'raw' - self._hide = n.find('hide') or '' - self._tab_label = n.find('tab') or block.get_param_tab_labels()[0] + self._name = n['name'] + self._key = n['key'] + value = n.get('value', '') + self._type = n.get('type', 'raw') + self._hide = n.get('hide', '') + self._tab_label = n.get('tab', block.get_param_tab_labels()[0]) if self._tab_label not in block.get_param_tab_labels(): block.get_param_tab_labels().append(self._tab_label) # Build the param - Element.__init__(self, block) + Element.__init__(self, parent=block) # Create the Option objects from the n data self._options = list() self._evaluated = None - for option in map(lambda o: Option(param=self, n=o), n.findall('option')): + for o_n in n.get('option', []): + option = Option(param=self, n=o_n) key = option.get_key() # Test against repeated keys if key in self.get_option_keys(): @@ -257,9 +258,9 @@ class Param(Element): t = self.get_type() if isinstance(e, bool): return str(e) - elif isinstance(e, COMPLEX_TYPES): + elif isinstance(e, Constants.COMPLEX_TYPES): dt_str = num_to_str(e) - elif isinstance(e, VECTOR_TYPES): + elif isinstance(e, Constants.VECTOR_TYPES): # Vector types if len(e) > 8: # Large vectors use code @@ -292,38 +293,6 @@ class Param(Element): def __str__(self): return 'Param - {}({})'.format(self.get_name(), self.get_key()) - def get_color(self): - """ - Get the color that represents this param's type. - - Returns: - a hex color code. - """ - try: - return { - # Number types - 'complex': Constants.COMPLEX_COLOR_SPEC, - 'real': Constants.FLOAT_COLOR_SPEC, - 'float': Constants.FLOAT_COLOR_SPEC, - 'int': Constants.INT_COLOR_SPEC, - # Vector types - 'complex_vector': Constants.COMPLEX_VECTOR_COLOR_SPEC, - 'real_vector': Constants.FLOAT_VECTOR_COLOR_SPEC, - 'float_vector': Constants.FLOAT_VECTOR_COLOR_SPEC, - 'int_vector': Constants.INT_VECTOR_COLOR_SPEC, - # Special - 'bool': Constants.INT_COLOR_SPEC, - 'hex': Constants.INT_COLOR_SPEC, - 'string': Constants.BYTE_VECTOR_COLOR_SPEC, - 'id': Constants.ID_COLOR_SPEC, - 'stream_id': Constants.ID_COLOR_SPEC, - 'grid_pos': Constants.INT_VECTOR_COLOR_SPEC, - 'notebook': Constants.INT_VECTOR_COLOR_SPEC, - 'raw': Constants.WILDCARD_COLOR_SPEC, - }[self.get_type()] - except: - return '#FFFFFF' - def get_hide(self): """ Get the hide value from the base class. @@ -335,20 +304,17 @@ class Param(Element): Returns: hide the hide property string """ - hide = self.get_parent().resolve_dependencies(self._hide).strip() + hide = self.parent.resolve_dependencies(self._hide).strip() if hide: return hide # Hide ID in non variable blocks - if self.get_key() == 'id' and not _show_id_matcher.match(self.get_parent().get_key()): + if self.get_key() == 'id' and not _show_id_matcher.match(self.parent.get_key()): return 'part' # Hide port controllers for type and nports - if self.get_key() in ' '.join(map(lambda p: ' '.join([p._type, p._nports]), - self.get_parent().get_ports())): + if self.get_key() in ' '.join([' '.join([p._type, p._nports]) for p in self.parent.get_ports()]): return 'part' # Hide port controllers for vlen, when == 1 - if self.get_key() in ' '.join(map( - lambda p: p._vlen, self.get_parent().get_ports()) - ): + if self.get_key() in ' '.join(p._vlen for p in self.parent.get_ports()): try: if int(self.get_evaluated()) == 1: return 'part' @@ -371,7 +337,7 @@ class Param(Element): self._evaluated = None try: self._evaluated = self.evaluate() - except Exception, e: + except Exception as e: self.add_error_message(str(e)) def get_evaluated(self): @@ -403,22 +369,22 @@ class Param(Element): elif t in ('raw', 'complex', 'real', 'float', 'int', 'hex', 'bool'): # Raise exception if python cannot evaluate this value try: - e = self.get_parent().get_parent().evaluate(v) - except Exception, e: + e = self.parent_flowgraph.evaluate(v) + except Exception as e: raise Exception('Value "{}" cannot be evaluated:\n{}'.format(v, e)) # Raise an exception if the data is invalid if t == 'raw': return e elif t == 'complex': - if not isinstance(e, COMPLEX_TYPES): + if not isinstance(e, Constants.COMPLEX_TYPES): raise Exception('Expression "{}" is invalid for type complex.'.format(str(e))) return e elif t == 'real' or t == 'float': - if not isinstance(e, REAL_TYPES): + if not isinstance(e, Constants.REAL_TYPES): raise Exception('Expression "{}" is invalid for type float.'.format(str(e))) return e elif t == 'int': - if not isinstance(e, INT_TYPES): + if not isinstance(e, Constants.INT_TYPES): raise Exception('Expression "{}" is invalid for type integer.'.format(str(e))) return e elif t == 'hex': @@ -438,29 +404,29 @@ class Param(Element): v = '()' # Raise exception if python cannot evaluate this value try: - e = self.get_parent().get_parent().evaluate(v) - except Exception, e: + e = self.parent.parent.evaluate(v) + except Exception as e: raise Exception('Value "{}" cannot be evaluated:\n{}'.format(v, e)) # Raise an exception if the data is invalid if t == 'complex_vector': - if not isinstance(e, VECTOR_TYPES): + if not isinstance(e, Constants.VECTOR_TYPES): self._lisitify_flag = True e = [e] - if not all([isinstance(ei, COMPLEX_TYPES) for ei in e]): + if not all([isinstance(ei, Constants.COMPLEX_TYPES) for ei in e]): raise Exception('Expression "{}" is invalid for type complex vector.'.format(str(e))) return e elif t == 'real_vector' or t == 'float_vector': - if not isinstance(e, VECTOR_TYPES): + if not isinstance(e, Constants.VECTOR_TYPES): self._lisitify_flag = True e = [e] - if not all([isinstance(ei, REAL_TYPES) for ei in e]): + if not all([isinstance(ei, Constants.REAL_TYPES) for ei in e]): raise Exception('Expression "{}" is invalid for type float vector.'.format(str(e))) return e elif t == 'int_vector': - if not isinstance(e, VECTOR_TYPES): + if not isinstance(e, Constants.VECTOR_TYPES): self._lisitify_flag = True e = [e] - if not all([isinstance(ei, INT_TYPES) for ei in e]): + if not all([isinstance(ei, Constants.INT_TYPES) for ei in e]): raise Exception('Expression "{}" is invalid for type integer vector.'.format(str(e))) return e ######################### @@ -469,7 +435,7 @@ class Param(Element): elif t in ('string', 'file_open', 'file_save', '_multiline', '_multiline_python_external'): # Do not check if file/directory exists, that is a runtime issue try: - e = self.get_parent().get_parent().evaluate(v) + e = self.parent.parent.evaluate(v) if not isinstance(e, str): raise Exception() except: @@ -500,16 +466,16 @@ class Param(Element): elif t == 'stream_id': # Get a list of all stream ids used in the virtual sinks ids = [param.get_value() for param in filter( - lambda p: p.get_parent().is_virtual_sink(), + lambda p: p.parent.is_virtual_sink(), self.get_all_params(t), )] # Check that the virtual sink's stream id is unique - if self.get_parent().is_virtual_sink(): + if self.parent.is_virtual_sink(): # Id should only appear once, or zero times if block is disabled if ids.count(v) > 1: raise Exception('Stream ID "{}" is not unique.'.format(v)) # Check that the virtual source's steam id is found - if self.get_parent().is_virtual_source(): + if self.parent.is_virtual_source(): if v not in ids: raise Exception('Stream ID "{}" is not found.'.format(v)) return v @@ -557,7 +523,7 @@ class Param(Element): if not v: # Allow for empty grid pos return '' - e = self.get_parent().get_parent().evaluate(v) + e = self.parent_flowgraph.evaluate(v) if not isinstance(e, (list, tuple)) or len(e) != 4 or not all([isinstance(ei, int) for ei in e]): raise Exception('A grid position must be a list of 4 integers.') row, col, row_span, col_span = e @@ -569,7 +535,7 @@ class Param(Element): raise Exception('Row and column span must be greater than zero.') # Get hostage cell parent try: - my_parent = self.get_parent().get_param('notebook').evaluate() + my_parent = self.parent.get_param('notebook').evaluate() except: my_parent = '' # Calculate hostage cells @@ -577,7 +543,7 @@ class Param(Element): for c in range(col_span): self._hostage_cells.append((my_parent, (row+r, col+c))) # Avoid collisions - params = filter(lambda p: p is not self, self.get_all_params('grid_pos')) + params = [p for p in self.get_all_params('grid_pos') if p is not self] for param in params: for parent, cell in param._hostage_cells: if (parent, cell) in self._hostage_cells: @@ -592,7 +558,7 @@ class Param(Element): return '' # Get a list of all notebooks - notebook_blocks = filter(lambda b: b.get_key() == 'notebook', self.get_parent().get_parent().get_enabled_blocks()) + notebook_blocks = [b for b in self.parent_flowgraph.get_enabled_blocks() if b.get_key() == 'notebook'] # Check for notebook param syntax try: notebook_id, page_index = map(str.strip, v.split(',')) @@ -600,7 +566,7 @@ class Param(Element): raise Exception('Bad notebook page format.') # Check that the notebook id is valid try: - notebook_block = filter(lambda b: b.get_id() == notebook_id, notebook_blocks)[0] + notebook_block = [b for b in notebook_blocks if b.get_id() == notebook_id][0] except: raise Exception('Notebook id "{}" is not an existing notebook id.'.format(notebook_id)) @@ -616,12 +582,12 @@ class Param(Element): # New namespace n = dict() try: - exec v in n + exec(v, n) except ImportError: raise Exception('Import "{}" failed.'.format(v)) except Exception: raise Exception('Bad import syntax: "{}".'.format(v)) - return filter(lambda k: str(k) != '__builtins__', n.keys()) + return [k for k in list(n.keys()) if str(k) != '__builtins__'] ######################### else: @@ -667,7 +633,10 @@ class Param(Element): Returns: a list of params """ - return sum([filter(lambda p: p.get_type() == type, block.get_params()) for block in self.get_parent().get_parent().get_enabled_blocks()], []) + params = [] + for block in self.parent_flowgraph.get_enabled_blocks(): + params.extend(p for p in block.get_params() if p.get_type() == type) + return params def is_enum(self): return self._type == 'enum' @@ -689,13 +658,13 @@ class Param(Element): self._default = str(value) def get_type(self): - return self.get_parent().resolve_dependencies(self._type) + return self.parent.resolve_dependencies(self._type) def get_tab_label(self): return self._tab_label def get_name(self): - return self.get_parent().resolve_dependencies(self._name).strip() + return self.parent.resolve_dependencies(self._name).strip() def get_key(self): return self._key @@ -734,7 +703,7 @@ class Param(Element): Returns: a nested data odict """ - n = odict() + n = collections.OrderedDict() n['key'] = self.get_key() n['value'] = self.get_value() return n |