summaryrefslogtreecommitdiff
path: root/grc/core/params/param.py
diff options
context:
space:
mode:
authorSebastian Koslowski <sebastian.koslowski@gmail.com>2017-11-08 21:28:35 +0100
committerSebastian Koslowski <sebastian.koslowski@gmail.com>2017-11-09 19:26:43 +0100
commit14d79b777e773e299a1ffa0dd12d2508a46370a0 (patch)
tree7fd696fbf2435f5b2d672332d4f8253611726e8f /grc/core/params/param.py
parentcd9c3479e17fbdb84918e255cf6de74edf0ceab1 (diff)
grc: move some of the param checkers to separate file
Diffstat (limited to 'grc/core/params/param.py')
-rw-r--r--grc/core/params/param.py154
1 files changed, 38 insertions, 116 deletions
diff --git a/grc/core/params/param.py b/grc/core/params/param.py
index 787be9a19f..30a48bb434 100644
--- a/grc/core/params/param.py
+++ b/grc/core/params/param.py
@@ -18,28 +18,19 @@
from __future__ import absolute_import
import ast
-import numbers
-import re
import collections
import textwrap
import six
-from six.moves import builtins, range
+from six.moves import range
-from .. import Constants, blocks
+from .. import Constants
from ..base import Element
from ..utils.descriptors import Evaluated, EvaluatedEnum, setup_names
+from . import dtypes
from .template_arg import TemplateArg
-# Blacklist certain ids, its not complete, but should help
-ID_BLACKLIST = ['self', 'options', 'gr', 'math', 'firdes'] + dir(builtins)
-try:
- from gnuradio import gr
- ID_BLACKLIST.extend(attr for attr in dir(gr.top_block()) if not attr.startswith('_'))
-except (ImportError, AttributeError):
- pass
-
@setup_names
class Param(Element):
@@ -147,6 +138,10 @@ class Param(Element):
except Exception as e:
self.add_error_message(str(e))
+ rewriter = getattr(dtypes, 'rewrite_' + self.dtype, None)
+ if rewriter:
+ rewriter(self)
+
def validate(self):
"""
Validate the param.
@@ -156,6 +151,13 @@ class Param(Element):
if self.dtype not in Constants.PARAM_TYPE_NAMES:
self.add_error_message('Type "{}" is not a possible type.'.format(self.dtype))
+ validator = dtypes.validators.get(self.dtype, None)
+ if self._init and validator:
+ try:
+ validator(self)
+ except dtypes.ValidateError as e:
+ self.add_error_message(e.message)
+
def get_evaluated(self):
return self._evaluated
@@ -173,68 +175,41 @@ class Param(Element):
expr = self.get_value()
#########################
- # Enum Type
+ # ID and Enum types (not evaled)
#########################
- if self.is_enum():
+ if dtype in ('id', 'stream_id') or self.is_enum():
return expr
#########################
# Numeric Types
#########################
elif dtype in ('raw', 'complex', 'real', 'float', 'int', 'hex', 'bool'):
- # Raise exception if python cannot evaluate this value
- try:
- value = self.parent_flowgraph.evaluate(expr)
- except Exception as value:
- raise Exception('Value "{}" cannot be evaluated:\n{}'.format(expr, value))
- # Raise an exception if the data is invalid
- if dtype == 'raw':
- return value
- elif dtype == 'complex':
- if not isinstance(value, Constants.COMPLEX_TYPES):
- raise Exception('Expression "{}" is invalid for type complex.'.format(str(value)))
- return value
- elif dtype in ('real', 'float'):
- if not isinstance(value, Constants.REAL_TYPES):
- raise Exception('Expression "{}" is invalid for type float.'.format(str(value)))
- return value
- elif dtype == 'int':
- if not isinstance(value, Constants.INT_TYPES):
- raise Exception('Expression "{}" is invalid for type integer.'.format(str(value)))
- return value
- elif dtype == 'hex':
- return hex(value)
- elif dtype == 'bool':
- if not isinstance(value, bool):
- raise Exception('Expression "{}" is invalid for type bool.'.format(str(value)))
- return value
+ if expr:
+ try:
+ value = self.parent_flowgraph.evaluate(expr)
+ except Exception as e:
+ raise Exception('Value "{}" cannot be evaluated:\n{}'.format(expr, e))
else:
- raise TypeError('Type "{}" not handled'.format(dtype))
+ value = 0
+ if dtype == 'hex':
+ value = hex(value)
+ elif dtype == 'bool':
+ value = bool(value)
+ return value
+
#########################
# Numeric Vector Types
#########################
elif dtype in ('complex_vector', 'real_vector', 'float_vector', 'int_vector'):
- default = []
-
if not expr:
- return default # Turn a blank string into an empty list, so it will eval
-
+ return [] # Turn a blank string into an empty list, so it will eval
try:
value = self.parent.parent.evaluate(expr)
except Exception as value:
raise Exception('Value "{}" cannot be evaluated:\n{}'.format(expr, value))
-
if not isinstance(value, Constants.VECTOR_TYPES):
self._lisitify_flag = True
value = [value]
-
- # Raise an exception if the data is invalid
- if dtype == 'complex_vector' and not all(isinstance(item, numbers.Complex) for item in value):
- raise Exception('Expression "{}" is invalid for type complex vector.'.format(value))
- elif dtype in ('real_vector', 'float_vector') and not all(isinstance(item, numbers.Real) for item in value):
- raise Exception('Expression "{}" is invalid for type float vector.'.format(value))
- elif dtype == 'int_vector' and not all(isinstance(item, Constants.INT_TYPES) for item in value):
- raise Exception('Expression "{}" is invalid for type integer vector.'.format(str(value)))
return value
#########################
# String Types
@@ -242,7 +217,7 @@ class Param(Element):
elif dtype in ('string', 'file_open', 'file_save', '_multiline', '_multiline_python_external'):
# Do not check if file/directory exists, that is a runtime issue
try:
- value = self.parent.parent.evaluate(expr)
+ value = self.parent_flowgraph.evaluate(expr)
if not isinstance(value, str):
raise Exception()
except:
@@ -252,28 +227,10 @@ class Param(Element):
ast.parse(value) # Raises SyntaxError
return value
#########################
- # Unique ID Type
- #########################
- elif dtype == 'id':
- self.validate_block_id()
- return expr
-
- #########################
- # Stream ID Type
- #########################
- elif dtype == 'stream_id':
- self.validate_stream_id()
- return expr
-
- #########################
# GUI Position/Hint
#########################
elif dtype == 'gui_hint':
- if self.parent_block.state == 'disabled':
- return ''
- else:
- return self.parse_gui_hint(expr)
-
+ return self.parse_gui_hint(expr) if self.parent_block.state == 'enabled' else ''
#########################
# Import Type
#########################
@@ -292,37 +249,6 @@ class Param(Element):
else:
raise TypeError('Type "{}" not handled'.format(dtype))
- def validate_block_id(self):
- value = self.value
- # Can python use this as a variable?
- if not re.match(r'^[a-z|A-Z]\w*$', value):
- raise Exception('ID "{}" must begin with a letter and may contain letters, numbers, '
- 'and underscores.'.format(value))
- if value in ID_BLACKLIST:
- raise Exception('ID "{}" is blacklisted.'.format(value))
- block_names = [block.name for block in self.parent_flowgraph.iter_enabled_blocks()]
- # Id should only appear once, or zero times if block is disabled
- if self.key == 'id' and block_names.count(value) > 1:
- raise Exception('ID "{}" is not unique.'.format(value))
- elif value not in block_names:
- raise Exception('ID "{}" does not exist.'.format(value))
- return value
-
- def validate_stream_id(self):
- value = self.value
- stream_ids = [
- block.params['stream_id'].value
- for block in self.parent_flowgraph.iter_enabled_blocks()
- if isinstance(block, blocks.VirtualSink)
- ]
- # Check that the virtual sink's stream id is unique
- if isinstance(self.parent_block, blocks.VirtualSink) and stream_ids.count(value) >= 2:
- # Id should only appear once, or zero times if block is disabled
- raise Exception('Stream ID "{}" is not unique.'.format(value))
- # Check that the virtual source's steam id is found
- elif isinstance(self.parent_block, blocks.VirtualSource) and value not in stream_ids:
- raise Exception('Stream ID "{}" is not found.'.format(value))
-
def to_code(self):
"""
Convert the value to code.
@@ -333,24 +259,20 @@ class Param(Element):
a string representing the code
"""
self._init = True
- v = self.get_value()
- t = self.dtype
+ value = self.get_value()
# String types
- if t in ('string', 'file_open', 'file_save', '_multiline', '_multiline_python_external'):
+ if self.dtype in ('string', 'file_open', 'file_save', '_multiline', '_multiline_python_external'):
if not self._init:
self.evaluate()
- return repr(v) if self._stringify_flag else v
+ return repr(value) if self._stringify_flag else value
# Vector types
- elif t in ('complex_vector', 'real_vector', 'float_vector', 'int_vector'):
+ elif self.dtype in ('complex_vector', 'real_vector', 'float_vector', 'int_vector'):
if not self._init:
self.evaluate()
- if self._lisitify_flag:
- return '(%s, )' % v
- else:
- return '(%s)' % v
+ return '[' + value + ']' if self._lisitify_flag else value
else:
- return v
+ return value
def get_opt(self, item):
return self.options.attributes[self.get_value()][item]
@@ -470,7 +392,7 @@ class Param(Element):
optionally a given key
Args:
- type: the specified type
+ dtype: the specified type
key: the key to match against
Returns: