summaryrefslogtreecommitdiff
path: root/grc/core/Param.py
diff options
context:
space:
mode:
Diffstat (limited to 'grc/core/Param.py')
-rw-r--r--grc/core/Param.py153
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