diff options
Diffstat (limited to 'grc/core')
36 files changed, 454 insertions, 282 deletions
diff --git a/grc/core/Config.py b/grc/core/Config.py index 73cc135861..374a3f2316 100644 --- a/grc/core/Config.py +++ b/grc/core/Config.py @@ -17,13 +17,16 @@ class Config(object): license = __doc__.strip() website = 'https://www.gnuradio.org/' - hier_block_lib_dir = os.environ.get('GRC_HIER_PATH', Constants.DEFAULT_HIER_BLOCK_LIB_DIR) + hier_block_lib_dir = os.environ.get( + 'GRC_HIER_PATH', Constants.DEFAULT_HIER_BLOCK_LIB_DIR) def __init__(self, version, version_parts=None, name=None, prefs=None): self._gr_prefs = prefs if prefs else DummyPrefs() self.version = version - self.version_parts = version_parts or version[1:].split('-', 1)[0].split('.')[:3] - self.enabled_components = self._gr_prefs.get_string('grc', 'enabled_components', '') + self.version_parts = version_parts or version[1:].split( + '-', 1)[0].split('.')[:3] + self.enabled_components = self._gr_prefs.get_string( + 'grc', 'enabled_components', '') if name: self.name = name diff --git a/grc/core/Connection.py b/grc/core/Connection.py index b1c7196e3d..a341abe72a 100644 --- a/grc/core/Connection.py +++ b/grc/core/Connection.py @@ -96,12 +96,14 @@ class Connection(Element): if source_dtype != sink_dtype and source_dtype not in ALIASES_OF.get( sink_dtype, set() ): - self.add_error_message('Source IO type "{}" does not match sink IO type "{}".'.format(source_dtype, sink_dtype)) + self.add_error_message('Source IO type "{}" does not match sink IO type "{}".'.format( + source_dtype, sink_dtype)) source_size = self.source_port.item_size sink_size = self.sink_port.item_size if source_size != sink_size: - self.add_error_message('Source IO size "{}" does not match sink IO size "{}".'.format(source_size, sink_size)) + self.add_error_message( + 'Source IO size "{}" does not match sink IO size "{}".'.format(source_size, sink_size)) ############################################## # Import/Export Methods diff --git a/grc/core/Constants.py b/grc/core/Constants.py index 953676ffde..93adec26be 100644 --- a/grc/core/Constants.py +++ b/grc/core/Constants.py @@ -41,7 +41,7 @@ DEFAULT_DOMAIN = GR_STREAM_DOMAIN # File creation modes TOP_BLOCK_FILE_MODE = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | \ - stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH + stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH HIER_BLOCK_FILE_MODE = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH PARAM_TYPE_NAMES = { @@ -50,7 +50,7 @@ PARAM_TYPE_NAMES = { 'complex_vector', 'real_vector', 'float_vector', 'int_vector', 'hex', 'string', 'bool', 'file_open', 'file_save', 'dir_select', '_multiline', '_multiline_python_external', - 'id', 'stream_id','name', + 'id', 'stream_id', 'name', 'gui_hint', 'import', } @@ -89,31 +89,31 @@ GRC_COLOR_GREY = '#BDBDBD' GRC_COLOR_WHITE = '#FFFFFF' CORE_TYPES = ( # name, key, sizeof, color - ('Complex Float 64', 'fc64', 16, GRC_COLOR_BROWN), - ('Complex Float 32', 'fc32', 8, GRC_COLOR_BLUE), - ('Complex Integer 64', 'sc64', 16, GRC_COLOR_LIGHT_GREEN), - ('Complex Integer 32', 'sc32', 8, GRC_COLOR_GREEN), - ('Complex Integer 16', 'sc16', 4, GRC_COLOR_AMBER), - ('Complex Integer 8', 'sc8', 2, GRC_COLOR_PURPLE), - ('Float 64', 'f64', 8, GRC_COLOR_CYAN), - ('Float 32', 'f32', 4, GRC_COLOR_ORANGE), - ('Integer 64', 's64', 8, GRC_COLOR_LIME), - ('Integer 32', 's32', 4, GRC_COLOR_TEAL), - ('Integer 16', 's16', 2, GRC_COLOR_YELLOW), - ('Integer 8', 's8', 1, GRC_COLOR_PURPLE_A400), - ('Bits (unpacked byte)', 'bit', 1, GRC_COLOR_PURPLE_A100), - ('Async Message', 'message', 0, GRC_COLOR_GREY), - ('Bus Connection', 'bus', 0, GRC_COLOR_WHITE), - ('Wildcard', '', 0, GRC_COLOR_WHITE), + ('Complex Float 64', 'fc64', 16, GRC_COLOR_BROWN), + ('Complex Float 32', 'fc32', 8, GRC_COLOR_BLUE), + ('Complex Integer 64', 'sc64', 16, GRC_COLOR_LIGHT_GREEN), + ('Complex Integer 32', 'sc32', 8, GRC_COLOR_GREEN), + ('Complex Integer 16', 'sc16', 4, GRC_COLOR_AMBER), + ('Complex Integer 8', 'sc8', 2, GRC_COLOR_PURPLE), + ('Float 64', 'f64', 8, GRC_COLOR_CYAN), + ('Float 32', 'f32', 4, GRC_COLOR_ORANGE), + ('Integer 64', 's64', 8, GRC_COLOR_LIME), + ('Integer 32', 's32', 4, GRC_COLOR_TEAL), + ('Integer 16', 's16', 2, GRC_COLOR_YELLOW), + ('Integer 8', 's8', 1, GRC_COLOR_PURPLE_A400), + ('Bits (unpacked byte)', 'bit', 1, GRC_COLOR_PURPLE_A100), + ('Async Message', 'message', 0, GRC_COLOR_GREY), + ('Bus Connection', 'bus', 0, GRC_COLOR_WHITE), + ('Wildcard', '', 0, GRC_COLOR_WHITE), ) ALIAS_TYPES = { 'complex': (8, GRC_COLOR_BLUE), - 'float': (4, GRC_COLOR_ORANGE), - 'int': (4, GRC_COLOR_TEAL), - 'short': (2, GRC_COLOR_YELLOW), - 'byte': (1, GRC_COLOR_PURPLE_A400), - 'bits': (1, GRC_COLOR_PURPLE_A100), + 'float': (4, GRC_COLOR_ORANGE), + 'int': (4, GRC_COLOR_TEAL), + 'short': (2, GRC_COLOR_YELLOW), + 'byte': (1, GRC_COLOR_PURPLE_A400), + 'bits': (1, GRC_COLOR_PURPLE_A100), } ALIASES_OF = { @@ -135,4 +135,5 @@ ALIASES_OF = { } TYPE_TO_SIZEOF = {key: sizeof for name, key, sizeof, color in CORE_TYPES} -TYPE_TO_SIZEOF.update((key, sizeof) for key, (sizeof, _) in ALIAS_TYPES.items()) +TYPE_TO_SIZEOF.update((key, sizeof) + for key, (sizeof, _) in ALIAS_TYPES.items()) diff --git a/grc/core/FlowGraph.py b/grc/core/FlowGraph.py index ad42371bb8..ae567d003d 100644 --- a/grc/core/FlowGraph.py +++ b/grc/core/FlowGraph.py @@ -68,7 +68,8 @@ class FlowGraph(Element): Returns: a sorted list of variable blocks in order of dependency (indep -> dep) """ - variables = [block for block in self.iter_enabled_blocks() if block.is_variable] + variables = [block for block in self.iter_enabled_blocks() + if block.is_variable] return expr_utils.sort_objects(variables, attrgetter('name'), methodcaller('get_var_make')) def get_parameters(self): @@ -78,7 +79,8 @@ class FlowGraph(Element): Returns: a list of parameterized variables """ - parameters = [b for b in self.iter_enabled_blocks() if b.key == 'parameter'] + parameters = [b for b in self.iter_enabled_blocks() + if b.key == 'parameter'] return parameters def get_snippets(self): @@ -126,7 +128,8 @@ class FlowGraph(Element): """ Get a list of all ControlPort monitors """ - monitors = [b for b in self.iter_enabled_blocks() if 'ctrlport_monitor' in b.key] + monitors = [b for b in self.iter_enabled_blocks() + if 'ctrlport_monitor' in b.key] return monitors def get_python_modules(self): @@ -189,7 +192,8 @@ class FlowGraph(Element): filename=shlex.quote(file_path)) return shlex.split(run_command) if split else run_command except Exception as e: - raise ValueError("Can't parse run command {!r}: {}".format(run_command, e)) + raise ValueError( + "Can't parse run command {!r}: {}".format(run_command, e)) def get_imported_names(self): """ @@ -241,7 +245,8 @@ class FlowGraph(Element): # this is ok behavior, unfortunately we could be hiding other import bugs pass except Exception: - log.exception('Failed to evaluate import expression "{0}"'.format(expr), exc_info=True) + log.exception('Failed to evaluate import expression "{0}"'.format( + expr), exc_info=True) pass self.imported_names = list(namespace.keys()) @@ -252,17 +257,20 @@ class FlowGraph(Element): exec(expr, module.__dict__) namespace[id] = module except Exception: - log.exception('Failed to evaluate expression in module {0}'.format(id), exc_info=True) + log.exception( + 'Failed to evaluate expression in module {0}'.format(id), exc_info=True) pass # Load parameters np = {} # params don't know each other for parameter_block in self.get_parameters(): try: - value = eval(parameter_block.params['value'].to_code(), namespace) + value = eval( + parameter_block.params['value'].to_code(), namespace) np[parameter_block.name] = value except Exception: - log.exception('Failed to evaluate parameter block {0}'.format(parameter_block.name), exc_info=True) + log.exception('Failed to evaluate parameter block {0}'.format( + parameter_block.name), exc_info=True) pass namespace.update(np) # Merge param namespace @@ -273,13 +281,16 @@ class FlowGraph(Element): for variable_block in self.get_variables(): try: variable_block.rewrite() - value = eval(variable_block.value, namespace, variable_block.namespace) + value = eval(variable_block.value, namespace, + variable_block.namespace) namespace[variable_block.name] = value - self.namespace.update(namespace) # rewrite on subsequent blocks depends on an updated self.namespace - except TypeError: #Type Errors may happen, but that doesn't matter as they are displayed in the gui + # rewrite on subsequent blocks depends on an updated self.namespace + self.namespace.update(namespace) + except TypeError: # Type Errors may happen, but that doesn't matter as they are displayed in the gui pass except Exception: - log.exception('Failed to evaluate variable block {0}'.format(variable_block.name), exc_info=True) + log.exception('Failed to evaluate variable block {0}'.format( + variable_block.name), exc_info=True) pass self._eval_cache.clear() @@ -397,7 +408,8 @@ class FlowGraph(Element): cwd=self.grc_file_path ) if file_path: # grc file found. load and get block - self.parent_platform.load_and_generate_flow_graph(file_path, hier_only=True) + self.parent_platform.load_and_generate_flow_graph( + file_path, hier_only=True) return self.new_block(block_id) # can be None def import_data(self, data): @@ -424,7 +436,8 @@ class FlowGraph(Element): block = ( self.new_block(block_id) or self._build_depending_hier_block(block_id) or - self.new_block(block_id='_dummy', missing_block_id=block_id, **block_data) + self.new_block(block_id='_dummy', + missing_block_id=block_id, **block_data) ) block.import_data(**block_data) @@ -443,7 +456,8 @@ class FlowGraph(Element): if block.is_dummy_block: port = block.add_missing_port(key, dir) else: - raise LookupError('%s key %r not in %s block keys' % (dir, key, dir)) + raise LookupError( + '%s key %r not in %s block keys' % (dir, key, dir)) return port had_connect_errors = False @@ -461,8 +475,10 @@ class FlowGraph(Element): src_port_id, snk_port_id, source_block, sink_block) # build the connection - source_port = verify_and_get_port(src_port_id, source_block, 'source') - sink_port = verify_and_get_port(snk_port_id, sink_block, 'sink') + source_port = verify_and_get_port( + src_port_id, source_block, 'source') + sink_port = verify_and_get_port( + snk_port_id, sink_block, 'sink') self.connect(source_port, sink_port) @@ -478,7 +494,8 @@ class FlowGraph(Element): # Flowgraph errors depending on disabled blocks are not displayed # in the error dialog box # So put a message into the Property window of the dummy block - block.add_error_message('Block id "{}" not found.'.format(block.key)) + block.add_error_message( + 'Block id "{}" not found.'.format(block.key)) self.rewrite() # global rewrite return had_connect_errors diff --git a/grc/core/Messages.py b/grc/core/Messages.py index e6297d98c8..778a6baaab 100644 --- a/grc/core/Messages.py +++ b/grc/core/Messages.py @@ -5,7 +5,6 @@ # - import traceback import sys @@ -43,6 +42,7 @@ def send(message): for messenger in MESSENGERS_LIST: messenger(_indent + message) + # register stdout by default register_messenger(sys.stdout.write) @@ -117,7 +117,8 @@ def send_fail_save(file_path): def send_fail_connection(msg=''): - send('>>> Error: Cannot create connection.\n' + ('\t{}\n'.format(msg) if msg else '')) + send('>>> Error: Cannot create connection.\n' + + ('\t{}\n'.format(msg) if msg else '')) def send_fail_load_preferences(prefs_file_path): diff --git a/grc/core/__init__.py b/grc/core/__init__.py index 8b13789179..e69de29bb2 100644 --- a/grc/core/__init__.py +++ b/grc/core/__init__.py @@ -1 +0,0 @@ - diff --git a/grc/core/blocks/__init__.py b/grc/core/blocks/__init__.py index a80121e8bf..cc5297ece4 100644 --- a/grc/core/blocks/__init__.py +++ b/grc/core/blocks/__init__.py @@ -21,6 +21,7 @@ def register_build_in(cls): build_ins[cls.key] = cls return cls + from .dummy import DummyBlock from .embedded_python import EPyBlock, EPyModule from .virtual import VirtualSink, VirtualSource diff --git a/grc/core/blocks/_build.py b/grc/core/blocks/_build.py index 40155fc84f..91ebef1a42 100644 --- a/grc/core/blocks/_build.py +++ b/grc/core/blocks/_build.py @@ -79,7 +79,8 @@ def build_ports(ports_raw, direction): port_id = port.setdefault('id', str(next(stream_port_ids))) if port_id in port_ids: - raise Exception('Port id "{}" already exists in {}s'.format(port_id, direction)) + raise Exception( + 'Port id "{}" already exists in {}s'.format(port_id, direction)) port_ids.add(port_id) ports.append(port) @@ -137,16 +138,19 @@ def _single_mako_expr(value, block_id): return None value = value.strip() if not (value.startswith('${') and value.endswith('}')): - raise ValueError('{} is not a mako substitution in {}'.format(value, block_id)) + raise ValueError( + '{} is not a mako substitution in {}'.format(value, block_id)) return value[2:-1].strip() def _validate_option_attributes(param_data, block_id): if param_data['dtype'] != 'enum': - send_warning('{} - option_attributes are for enums only, ignoring'.format(block_id)) + send_warning( + '{} - option_attributes are for enums only, ignoring'.format(block_id)) del param_data['option_attributes'] else: for key in list(param_data['option_attributes'].keys()): if key in dir(str): del param_data['option_attributes'][key] - send_warning('{} - option_attribute "{}" overrides str, ignoring'.format(block_id, key)) + send_warning( + '{} - option_attribute "{}" overrides str, ignoring'.format(block_id, key)) diff --git a/grc/core/blocks/_templates.py b/grc/core/blocks/_templates.py index 37775cea1d..8ed69c6eac 100644 --- a/grc/core/blocks/_templates.py +++ b/grc/core/blocks/_templates.py @@ -16,12 +16,15 @@ from ..errors import TemplateError # The utils dict contains convenience functions # that can be called from any template + + def no_quotes(string, fallback=None): if len(string) > 2: if str(string)[0] + str(string)[-1] in ("''", '""'): return str(string)[1:-1] return str(fallback if fallback else string) + utils = {'no_quotes': no_quotes} diff --git a/grc/core/blocks/block.py b/grc/core/blocks/block.py index 86c408f617..89f96f96c8 100644 --- a/grc/core/blocks/block.py +++ b/grc/core/blocks/block.py @@ -22,6 +22,7 @@ from ._flags import Flags from ..base import Element from ..utils.descriptors import lazy_property + def _get_elem(iterable, key): items = list(iterable) for item in items: @@ -39,7 +40,7 @@ class Block(Element): key = '' label = '' category = [] - vtype = '' # This is only used for variables when we want C++ output + vtype = '' # This is only used for variables when we want C++ output flags = Flags('') documentation = {'': ''} @@ -67,13 +68,16 @@ class Block(Element): if self.key == 'options': self.params['id'].hide = 'part' - self.sinks = [port_factory(parent=self, **params) for params in self.inputs_data] - self.sources = [port_factory(parent=self, **params) for params in self.outputs_data] + self.sinks = [port_factory(parent=self, **params) + for params in self.inputs_data] + self.sources = [port_factory(parent=self, **params) + for params in self.outputs_data] self.active_sources = [] # on rewrite self.active_sinks = [] # on rewrite - self.states = {'state': True, 'bus_source': False, 'bus_sink': False, 'bus_structure': None} + self.states = {'state': True, 'bus_source': False, + 'bus_sink': False, 'bus_structure': None} self.block_namespace = {} self.deprecated = self.is_deprecated() @@ -81,7 +85,8 @@ class Block(Element): # This is a workaround to allow embedded python blocks/modules to load as there is # currently 'cpp' in the flags by default caused by the other built-in blocks if hasattr(self, 'cpp_templates'): - self.orig_cpp_templates = self.cpp_templates # The original template, in case we have to edit it when transpiling to C++ + # The original template, in case we have to edit it when transpiling to C++ + self.orig_cpp_templates = self.cpp_templates self.current_bus_structure = {'source': None, 'sink': None} @@ -100,8 +105,8 @@ class Block(Element): except: return None - # region Rewrite_and_Validation + def rewrite(self): """ Add and remove ports to adjust for the nports. @@ -125,7 +130,8 @@ class Block(Element): self.update_bus_logic() # disconnect hidden ports - self.parent_flowgraph.disconnect(*[p for p in self.ports() if p.hidden]) + self.parent_flowgraph.disconnect( + *[p for p in self.ports() if p.hidden]) self.active_sources = [p for p in self.sources if not p.hidden] self.active_sinks = [p for p in self.sinks if not p.hidden] @@ -142,11 +148,12 @@ class Block(Element): # this is ok behavior, unfortunately we could be hiding other import bugs pass except Exception: - self.add_error_message(f'Failed to evaluate import expression {imports!r}') + self.add_error_message( + f'Failed to evaluate import expression {imports!r}') def update_bus_logic(self): ############################### - ## Bus Logic + # Bus Logic ############################### for direc in {'source', 'sink'}: @@ -170,13 +177,12 @@ class Block(Element): removed_bus_connections.append(c) ports.remove(port) - if (bus_state): struct = self.form_bus_structure(direc) self.current_bus_structure[direc] = struct # Hide ports that are not part of the bus structure - #TODO: Blocks where it is desired to only have a subset + # TODO: Blocks where it is desired to only have a subset # of ports included in the bus still has some issues for idx, port in enumerate(ports): if any([idx in bus for bus in self.current_bus_structure[direc]]): @@ -187,19 +193,20 @@ class Block(Element): # Add the Bus Ports to the list of ports for i in range(len(struct)): # self.sinks = [port_factory(parent=self, **params) for params in self.inputs_data] - port = self.parent.parent.make_port(self, direction=direc, id=str(len(ports)), label='bus', dtype='bus', bus_struct=struct[i]) + port = self.parent.parent.make_port(self, direction=direc, id=str( + len(ports)), label='bus', dtype='bus', bus_struct=struct[i]) ports.append(port) for (saved_port, connection) in zip(removed_bus_ports, removed_bus_connections): if port.key == saved_port.key: - self.parent_flowgraph.connections.remove(connection) + self.parent_flowgraph.connections.remove( + connection) if saved_port.is_source: connection.source_port = port if saved_port.is_sink: connection.sink_port = port self.parent_flowgraph.connections.add(connection) - else: self.current_bus_structure[direc] = None @@ -209,8 +216,6 @@ class Block(Element): port.hidden = port.stored_hidden_state port.stored_hidden_state = None - - def _rewrite_nports(self, ports): for port in ports: if hasattr(port, 'master_port'): # Not a master port and no left-over clones @@ -218,7 +223,7 @@ class Block(Element): port.vlen = port.master_port.vlen continue nports = port.multiplicity - for clone in port.clones[nports-1:]: + for clone in port.clones[nports - 1:]: # Remove excess connections self.parent_flowgraph.disconnect(clone) port.remove_clone(clone) @@ -245,9 +250,11 @@ class Block(Element): for expr in self.asserts: try: if not self.evaluate(expr): - self.add_error_message('Assertion "{}" failed.'.format(expr)) + self.add_error_message( + 'Assertion "{}" failed.'.format(expr)) except Exception: - self.add_error_message('Assertion "{}" did not evaluate.'.format(expr)) + self.add_error_message( + 'Assertion "{}" did not evaluate.'.format(expr)) def _validate_generate_mode_compat(self): """check if this is a GUI block and matches the selected generate option""" @@ -261,7 +268,8 @@ class Block(Element): self.add_error_message("Can't generate this block in mode: {} ".format( repr(current_generate_option))) - check_generate_mode('QT GUI', Flags.NEED_QT_GUI, ('qt_gui', 'hb_qt_gui')) + check_generate_mode('QT GUI', Flags.NEED_QT_GUI, + ('qt_gui', 'hb_qt_gui')) def _validate_output_language_compat(self): """check if this block supports the selected output language""" @@ -269,19 +277,23 @@ class Block(Element): if current_output_language == 'cpp': if 'cpp' not in self.flags: - self.add_error_message("This block does not support C++ output.") + self.add_error_message( + "This block does not support C++ output.") if self.key == 'parameter': if not self.params['type'].value: - self.add_error_message("C++ output requires you to choose a parameter type.") + self.add_error_message( + "C++ output requires you to choose a parameter type.") def _validate_var_value(self): """or variables check the value (only if var_value is used)""" if self.is_variable and self.value != 'value': try: - self.parent_flowgraph.evaluate(self.value, local_namespace=self.namespace) + self.parent_flowgraph.evaluate( + self.value, local_namespace=self.namespace) except Exception as err: - self.add_error_message('Value "{}" cannot be evaluated:\n{}'.format(self.value, err)) + self.add_error_message( + 'Value "{}" cannot be evaluated:\n{}'.format(self.value, err)) # endregion # region Properties @@ -458,7 +470,7 @@ class Block(Element): # For container types we must also determine the type of the template parameter(s) return 'std::vector<' + get_type(str(evaluated[0]), type(evaluated[0])) + '>' - except IndexError: # empty list + except IndexError: # empty list return 'std::vector<std::string>' if _vtype == dict: @@ -466,9 +478,9 @@ class Block(Element): # For container types we must also determine the type of the template parameter(s) key = list(evaluated)[0] val = list(evaluated.values())[0] - return 'std::map<' + get_type(str(key), type(key)) + ', ' + get_type(str(val), type(val)) +'>' + return 'std::map<' + get_type(str(key), type(key)) + ', ' + get_type(str(val), type(val)) + '>' - except IndexError: # empty dict + except IndexError: # empty dict return 'std::map<std::string, std::string>' else: @@ -480,12 +492,12 @@ class Block(Element): # The r-value for these types must be transformed to create legal C++ syntax. if self.vtype in ['bool', 'gr_complex'] or 'std::map' in self.vtype or 'std::vector' in self.vtype: evaluated = ast.literal_eval(value) - self.cpp_templates['var_make'] = self.cpp_templates['var_make'].replace('${value}', self.get_cpp_value(evaluated)) + self.cpp_templates['var_make'] = self.cpp_templates['var_make'].replace( + '${value}', self.get_cpp_value(evaluated)) if 'string' in self.vtype: self.cpp_templates['includes'].append('#include <string>') - def get_cpp_value(self, pyval): if type(pyval) == int or type(pyval) == float: @@ -494,8 +506,10 @@ class Block(Element): # Check for PI and replace with C++ constant pi_re = r'^(math|numpy|np|scipy|sp)\.pi$' if re.match(pi_re, str(pyval)): - val_str = re.sub(pi_re, 'boost::math::constants::pi<double>()', val_str) - self.cpp_templates['includes'].append('#include <boost/math/constants/constants.hpp>') + val_str = re.sub( + pi_re, 'boost::math::constants::pi<double>()', val_str) + self.cpp_templates['includes'].append( + '#include <boost/math/constants/constants.hpp>') return str(pyval) @@ -503,7 +517,8 @@ class Block(Element): return str(pyval)[0].lower() + str(pyval)[1:] elif type(pyval) == complex: - self.cpp_templates['includes'].append('#include <gnuradio/gr_complex.h>') + self.cpp_templates['includes'].append( + '#include <gnuradio/gr_complex.h>') evaluated = ast.literal_eval(str(pyval).strip()) return '{' + str(evaluated.real) + ', ' + str(evaluated.imag) + '}' @@ -523,7 +538,8 @@ class Block(Element): self.cpp_templates['includes'].append('#include <map>') val_str = '{' for key in pyval: - val_str += '{' + self.get_cpp_value(key) + ', ' + self.get_cpp_value(pyval[key]) + '}, ' + val_str += '{' + self.get_cpp_value(key) + \ + ', ' + self.get_cpp_value(pyval[key]) + '}, ' if len(val_str) > 1: # truncate to trim superfluous ', ' from the end @@ -535,7 +551,6 @@ class Block(Element): self.cpp_templates['includes'].append('#include <string>') return '"' + pyval + '"' - def is_virtual_sink(self): return self.key == 'virtual_sink' @@ -561,8 +576,8 @@ class Block(Element): print(exception.message) return False - # Block bypassing + def get_bypassed(self): """ Check if the block is bypassed @@ -618,7 +633,8 @@ class Block(Element): @property def namespace(self): # update block namespace - self.block_namespace.update({key:param.get_evaluated() for key, param in self.params.items()}) + self.block_namespace.update( + {key: param.get_evaluated() for key, param in self.params.items()}) return self.block_namespace @property @@ -721,7 +737,7 @@ class Block(Element): struct = [range(len(ports))] # struct = list(range(len(ports))) - #TODO for more complicated port structures, this code is needed but not working yet + # TODO for more complicated port structures, this code is needed but not working yet if any([p.multiplicity for p in ports]): structlet = [] last = 0 @@ -736,8 +752,8 @@ class Block(Element): continue if p.multiplicity > 1: - cnt = p.multiplicity-1 - structlet.append([idx+j for j in range(p.multiplicity)]) + cnt = p.multiplicity - 1 + structlet.append([idx + j for j in range(p.multiplicity)]) else: structlet.append([idx]) diff --git a/grc/core/blocks/dummy.py b/grc/core/blocks/dummy.py index 5cdc05a9df..8147eededb 100644 --- a/grc/core/blocks/dummy.py +++ b/grc/core/blocks/dummy.py @@ -9,6 +9,7 @@ from . import Block, register_build_in from ._build import build_params + @register_build_in class DummyBlock(Block): @@ -19,12 +20,14 @@ class DummyBlock(Block): def __init__(self, parent, missing_block_id, parameters, **_): self.key = missing_block_id - self.parameters_data = build_params([], False, False, self.flags, self.key) + self.parameters_data = build_params( + [], False, False, self.flags, self.key) super(DummyBlock, self).__init__(parent=parent) param_factory = self.parent_platform.make_param for param_id in parameters: - self.params.setdefault(param_id, param_factory(parent=self, id=param_id, dtype='string')) + self.params.setdefault(param_id, param_factory( + parent=self, id=param_id, dtype='string')) def is_valid(self): return False diff --git a/grc/core/blocks/embedded_python.py b/grc/core/blocks/embedded_python.py index 051ba70317..893dcda948 100644 --- a/grc/core/blocks/embedded_python.py +++ b/grc/core/blocks/embedded_python.py @@ -122,7 +122,8 @@ class EPyBlock(Block): self.label = blk_io.name or blk_io.cls self.documentation = {'': blk_io.doc} - self.module_name = "{}_{}".format(self.parent_flowgraph.get_option("id"), self.name) + self.module_name = "{}_{}".format( + self.parent_flowgraph.get_option("id"), self.name) self.templates['imports'] = 'import {} as {} # embedded python block'.format( self.module_name, self.name) self.templates['make'] = '{mod}.{cls}({args})'.format( @@ -131,7 +132,7 @@ class EPyBlock(Block): args=', '.join('{0}=${{ {0} }}'.format(key) for key, _ in blk_io.params)) self.templates['callbacks'] = [ '{0} = ${{ {0} }}'.format(attr) for attr in blk_io.callbacks - ] + ] self._update_params(blk_io.params) self._update_ports('in', self.sinks, blk_io.sinks, 'sink') @@ -195,7 +196,8 @@ class EPyBlock(Block): def validate(self): super(EPyBlock, self).validate() if self._epy_reload_error: - self.params['_source_code'].add_error_message(str(self._epy_reload_error)) + self.params['_source_code'].add_error_message( + str(self._epy_reload_error)) @register_build_in @@ -240,6 +242,7 @@ class EPyModule(Block): def rewrite(self): super(EPyModule, self).rewrite() - self.module_name = "{}_{}".format(self.parent_flowgraph.get_option("id"), self.name) + self.module_name = "{}_{}".format( + self.parent_flowgraph.get_option("id"), self.name) self.templates['imports'] = 'import {} as {} # embedded python module'.format( self.module_name, self.name) diff --git a/grc/core/blocks/virtual.py b/grc/core/blocks/virtual.py index 9d1387dbbb..34e0feb34b 100644 --- a/grc/core/blocks/virtual.py +++ b/grc/core/blocks/virtual.py @@ -21,7 +21,8 @@ class VirtualSink(Block): flags.set('cpp') parameters_data = build_params( - params_raw=[dict(label='Stream ID', id='stream_id', dtype='stream_id')], + params_raw=[ + dict(label='Stream ID', id='stream_id', dtype='stream_id')], have_inputs=False, have_outputs=False, flags=flags, block_id=key ) inputs_data = [dict(domain='stream', dtype='', direction='sink', id="0")] @@ -45,10 +46,12 @@ class VirtualSource(Block): flags.set('cpp') parameters_data = build_params( - params_raw=[dict(label='Stream ID', id='stream_id', dtype='stream_id')], + params_raw=[ + dict(label='Stream ID', id='stream_id', dtype='stream_id')], have_inputs=False, have_outputs=False, flags=flags, block_id=key ) - outputs_data = [dict(domain='stream', dtype='', direction='source', id="0")] + outputs_data = [dict(domain='stream', dtype='', + direction='source', id="0")] def __init__(self, parent, **kwargs): super(VirtualSource, self).__init__(parent, **kwargs) diff --git a/grc/core/cache.py b/grc/core/cache.py index ab2cc4465b..59daa4b5ce 100644 --- a/grc/core/cache.py +++ b/grc/core/cache.py @@ -16,7 +16,7 @@ logger = logging.getLogger(__name__) class Cache(object): - def __init__(self, filename, version = None): + def __init__(self, filename, version=None): self.cache_file = filename self.version = version self.cache = {} @@ -57,7 +57,7 @@ class Cache(object): if modtime <= self._converter_mtime: try: cached = self.cache[filename] - if int(cached["cached-at"]+0.5) >= modtime: + if int(cached["cached-at"] + 0.5) >= modtime: return cached["data"] logger.info(f"Cache for {filename} outdated, loading yaml") except KeyError: diff --git a/grc/core/errors.py b/grc/core/errors.py index 59f3e0c436..0b9aefccb7 100644 --- a/grc/core/errors.py +++ b/grc/core/errors.py @@ -5,7 +5,6 @@ # - class GRCError(Exception): """Generic error class""" diff --git a/grc/core/generator/FlowGraphProxy.py b/grc/core/generator/FlowGraphProxy.py index 38d44e5b13..dad36c9240 100644 --- a/grc/core/generator/FlowGraphProxy.py +++ b/grc/core/generator/FlowGraphProxy.py @@ -8,6 +8,7 @@ from ..utils import expr_utils from operator import methodcaller, attrgetter + class FlowGraphProxy(object): # TODO: move this in a refactored Generator def __init__(self, fg): @@ -59,8 +60,8 @@ class FlowGraphProxy(object): # TODO: move this in a refactored Generator 'label': str(pad.params['label'].get_evaluated()), 'type': str(pad.params['type'].get_evaluated()), 'vlen': str(pad.params['vlen'].get_value()), - 'size': type_param.options.attributes[type_param.get_value()]['size'], - 'cpp_size': type_param.options.attributes[type_param.get_value()]['cpp_size'], + 'size': type_param.options.attributes[type_param.get_value()]['size'], + 'cpp_size': type_param.options.attributes[type_param.get_value()]['cpp_size'], 'optional': bool(pad.params['optional'].get_evaluated()), } num_ports = pad.params['num_streams'].get_evaluated() @@ -127,7 +128,8 @@ class FlowGraphProxy(object): # TODO: move this in a refactored Generator Returns: a sorted list of variable blocks in order of dependency (indep -> dep) """ - variables = [block for block in self.iter_enabled_blocks() if block.is_variable] + variables = [block for block in self.iter_enabled_blocks() + if block.is_variable] return expr_utils.sort_objects(variables, attrgetter('name'), methodcaller('get_cpp_var_make')) def includes(self): @@ -157,6 +159,7 @@ class FlowGraphProxy(object): # TODO: move this in a refactored Generator """ return [block.cpp_templates.render('packages') for block in self.iter_enabled_blocks() if not (block.is_virtual_sink() or block.is_virtual_source())] + def get_hier_block_io(flow_graph, direction, domain=None): """ Get a list of io ports for this flow graph. @@ -172,7 +175,7 @@ def get_hier_block_io(flow_graph, direction, domain=None): 'label': str(pad.params['label'].get_evaluated()), 'type': str(pad.params['type'].get_evaluated()), 'vlen': str(pad.params['vlen'].get_value()), - 'size': type_param.options.attributes[type_param.get_value()]['size'], + 'size': type_param.options.attributes[type_param.get_value()]['size'], 'optional': bool(pad.params['optional'].get_evaluated()), } num_ports = pad.params['num_streams'].get_evaluated() diff --git a/grc/core/generator/Generator.py b/grc/core/generator/Generator.py index 3f1831cc1b..8932419249 100644 --- a/grc/core/generator/Generator.py +++ b/grc/core/generator/Generator.py @@ -5,7 +5,6 @@ # - from .hier_block import HierBlockGenerator, QtHierBlockGenerator from .top_block import TopBlockGenerator from .cpp_top_block import CppTopBlockGenerator diff --git a/grc/core/generator/cpp_hier_block.py b/grc/core/generator/cpp_hier_block.py index 67f001568c..688af19348 100644 --- a/grc/core/generator/cpp_hier_block.py +++ b/grc/core/generator/cpp_hier_block.py @@ -8,6 +8,7 @@ from .cpp_top_block import CppTopBlockGenerator from .. import Constants from ..io import yaml + class CppHierBlockGenerator(CppTopBlockGenerator): """Extends the top block generator to also generate a block YML file""" @@ -27,7 +28,8 @@ class CppHierBlockGenerator(CppTopBlockGenerator): os.mkdir(hier_block_lib_dir) self._mode = Constants.HIER_BLOCK_FILE_MODE - self.file_path = os.path.join(hier_block_lib_dir, self._flow_graph.get_option('id')) + self.file_path = os.path.join( + hier_block_lib_dir, self._flow_graph.get_option('id')) self.file_path_yml = self.file_path + '.block.yml' def write(self): @@ -55,7 +57,6 @@ class CppHierBlockGenerator(CppTopBlockGenerator): # Windows only supports S_IREAD and S_IWRITE, other flags are ignored os.chmod(self.file_path_yml, self._mode) - def _build_block_n_from_flow_graph_io(self): """ Generate a block YML nested data from the flow graph IO @@ -136,7 +137,8 @@ class CppHierBlockGenerator(CppTopBlockGenerator): t_cpp = data['cpp_templates'] = collections.OrderedDict() t_cpp['includes'] = [] - t_cpp['includes'].append('#include "{id}/{id}.hpp"'.format(id=self._flow_graph.get_option('id'))) + t_cpp['includes'].append( + '#include "{id}/{id}.hpp"'.format(id=self._flow_graph.get_option('id'))) # Make data if parameters: @@ -147,7 +149,8 @@ class CppHierBlockGenerator(CppTopBlockGenerator): ), ) else: - t_cpp['make'] = 'this->${{id}} = {cls}_sptr(make_{cls}());'.format(cls=block_id) + t_cpp['make'] = 'this->${{id}} = {cls}_sptr(make_{cls}());'.format( + cls=block_id) t_cpp['declarations'] = '{cls}_sptr ${{id}};'.format(cls=block_id) # Callback data @@ -206,7 +209,8 @@ def get_hier_block_io(flow_graph, direction, domain=None): Returns a list of dicts with: type, label, vlen, size, optional """ - pads = flow_graph.get_pad_sources() if direction == 'inputs' else flow_graph.get_pad_sinks() + pads = flow_graph.get_pad_sources( + ) if direction == 'inputs' else flow_graph.get_pad_sinks() for pad in pads: for port in (pad.sources if direction == 'inputs' else pad.sinks): diff --git a/grc/core/generator/cpp_top_block.py b/grc/core/generator/cpp_top_block.py index ee9dc1a314..3ee712553f 100644 --- a/grc/core/generator/cpp_top_block.py +++ b/grc/core/generator/cpp_top_block.py @@ -38,7 +38,8 @@ class CppTopBlockGenerator(object): """ self._flow_graph = FlowGraphProxy(flow_graph) - self._generate_options = self._flow_graph.get_option('generate_options') + self._generate_options = self._flow_graph.get_option( + 'generate_options') self._mode = TOP_BLOCK_FILE_MODE # Handle the case where the directory is read-only @@ -48,25 +49,26 @@ class CppTopBlockGenerator(object): filename = self._flow_graph.get_option('id') self.file_path = os.path.join(output_dir, filename) self.output_dir = output_dir - + def _warnings(self): throttling_blocks = [b for b in self._flow_graph.get_enabled_blocks() - if b.flags.throttle] + if b.flags.throttle] if not throttling_blocks and not self._generate_options.startswith('hb'): Messages.send_warning("This flow graph may not have flow control: " - "no audio or RF hardware blocks found. " - "Add a Misc->Throttle block to your flow " - "graph to avoid CPU congestion.") + "no audio or RF hardware blocks found. " + "Add a Misc->Throttle block to your flow " + "graph to avoid CPU congestion.") if len(throttling_blocks) > 1: keys = set([b.key for b in throttling_blocks]) if len(keys) > 1 and 'blocks_throttle' in keys: Messages.send_warning("This flow graph contains a throttle " - "block and another rate limiting block, " - "e.g. a hardware source or sink. " - "This is usually undesired. Consider " - "removing the throttle block.") + "block and another rate limiting block, " + "e.g. a hardware source or sink. " + "This is usually undesired. Consider " + "removing the throttle block.") - deprecated_block_keys = {b.name for b in self._flow_graph.get_enabled_blocks() if b.flags.deprecated} + deprecated_block_keys = { + b.name for b in self._flow_graph.get_enabled_blocks() if b.flags.deprecated} for key in deprecated_block_keys: Messages.send_warning("The block {!r} is deprecated.".format(key)) @@ -76,7 +78,8 @@ class CppTopBlockGenerator(object): fg = self._flow_graph platform = fg.parent - self.title = fg.get_option('title') or fg.get_option('id').replace('_', ' ').title() + self.title = fg.get_option('title') or fg.get_option( + 'id').replace('_', ' ').title() variables = fg.get_cpp_variables() parameters = fg.get_parameters() monitors = fg.get_monitors() @@ -119,7 +122,8 @@ class CppTopBlockGenerator(object): Returns: a string of C++ code """ - file_path = self.file_path + '/' + self._flow_graph.get_option('id') + '.cpp' + file_path = self.file_path + '/' + \ + self._flow_graph.get_option('id') + '.cpp' output = [] @@ -132,12 +136,12 @@ class CppTopBlockGenerator(object): **self.namespace ) # strip trailing white-space - flow_graph_code = "\n".join(line.rstrip() for line in flow_graph_code.split("\n")) + flow_graph_code = "\n".join(line.rstrip() + for line in flow_graph_code.split("\n")) output.append((file_path, flow_graph_code)) return output - def _build_cpp_header_code_from_template(self): """ Convert the flow graph to a C++ header file. @@ -145,7 +149,8 @@ class CppTopBlockGenerator(object): Returns: a string of C++ code """ - file_path = self.file_path + '/' + self._flow_graph.get_option('id') + '.hpp' + file_path = self.file_path + '/' + \ + self._flow_graph.get_option('id') + '.hpp' output = [] @@ -158,7 +163,8 @@ class CppTopBlockGenerator(object): **self.namespace ) # strip trailing white-space - flow_graph_code = "\n".join(line.rstrip() for line in flow_graph_code.split("\n")) + flow_graph_code = "\n".join(line.rstrip() + for line in flow_graph_code.split("\n")) output.append((file_path, flow_graph_code)) return output @@ -175,7 +181,7 @@ class CppTopBlockGenerator(object): cmake_tuples = [] cmake_opt = self._flow_graph.get_option("cmake_opt") - cmake_opt = " " + cmake_opt # To make sure we get rid of the "-D"s when splitting + cmake_opt = " " + cmake_opt # To make sure we get rid of the "-D"s when splitting for opt_string in cmake_opt.split(" -D"): opt_string = opt_string.strip() @@ -196,7 +202,8 @@ class CppTopBlockGenerator(object): **self.namespace ) # strip trailing white-space - flow_graph_code = "\n".join(line.rstrip() for line in flow_graph_code.split("\n")) + flow_graph_code = "\n".join(line.rstrip() + for line in flow_graph_code.split("\n")) output.append((file_path, flow_graph_code)) return output @@ -255,7 +262,8 @@ class CppTopBlockGenerator(object): def _get_block_sort_text(block): code = block.cpp_templates.render('declarations') try: - code += block.params['gui_hint'].get_value() # Newer gui markup w/ qtgui + # Newer gui markup w/ qtgui + code += block.params['gui_hint'].get_value() except: pass return code @@ -265,7 +273,8 @@ class CppTopBlockGenerator(object): if b.enabled and not (b.get_bypassed() or b.is_import or b in parameters or b.key == 'options' or b.is_virtual_source() or b.is_virtual_sink()) ] - blocks = expr_utils.sort_objects(blocks, operator.attrgetter('name'), _get_block_sort_text) + blocks = expr_utils.sort_objects( + blocks, operator.attrgetter('name'), _get_block_sort_text) blocks_make = [] for block in blocks: translations = block.cpp_templates.render('translations') @@ -279,7 +288,8 @@ class CppTopBlockGenerator(object): {r"gr\.sizeof_([\w_]+)": r"sizeof(\1)"} ) for key in translations: - make = re.sub(key.replace("\\\\", "\\"), translations[key], make) + make = re.sub(key.replace("\\\\", "\\"), + translations[key], make) declarations = declarations.replace(key, translations[key]) if make: blocks_make.append((block, make, declarations)) @@ -293,7 +303,8 @@ class CppTopBlockGenerator(object): fg = self._flow_graph variables = fg.get_cpp_variables() - type_translation = {'complex': 'gr_complex', 'real': 'double', 'float': 'float', 'int': 'int', 'complex_vector': 'std::vector<gr_complex>', 'real_vector': 'std::vector<double>', 'float_vector': 'std::vector<float>', 'int_vector': 'std::vector<int>', 'string': 'std::string', 'bool': 'bool'} + type_translation = {'complex': 'gr_complex', 'real': 'double', 'float': 'float', 'int': 'int', 'complex_vector': 'std::vector<gr_complex>', + 'real_vector': 'std::vector<double>', 'float_vector': 'std::vector<float>', 'int_vector': 'std::vector<int>', 'string': 'std::string', 'bool': 'bool'} # If the type is explcitly specified, translate to the corresponding C++ type for var in list(variables): if var.params['value'].dtype != 'raw': @@ -304,26 +315,28 @@ class CppTopBlockGenerator(object): # Create an executable fragment of code containing all 'raw' variables in # order to infer the lvalue types. # - # Note that this differs from using ast.literal_eval() as literal_eval evaluates one - # variable at a time. The code fragment below evaluates all variables together which + # Note that this differs from using ast.literal_eval() as literal_eval evaluates one + # variable at a time. The code fragment below evaluates all variables together which # allows the variables to reference each other (i.e. a = b * c). prog = 'def get_decl_types():\n' prog += '\tvar_types = {}\n' for var in variables: - prog += '\t' + str(var.params['id'].value) + '=' + str(var.params['value'].value) + '\n' - prog += '\tvar_types = {}\n'; + prog += '\t' + str(var.params['id'].value) + \ + '=' + str(var.params['value'].value) + '\n' + prog += '\tvar_types = {}\n' for var in variables: - prog += '\tvar_types[\'' + str(var.params['id'].value) + '\'] = type(' + str(var.params['id'].value) + ')\n' + prog += '\tvar_types[\'' + str(var.params['id'].value) + \ + '\'] = type(' + str(var.params['id'].value) + ')\n' prog += '\treturn var_types' # Execute the code fragment in a separate namespace and retrieve the lvalue types var_types = {} namespace = {} try: - exec(prog, namespace) - var_types = namespace['get_decl_types']() + exec(prog, namespace) + var_types = namespace['get_decl_types']() except Exception as excp: - print('Failed to get parameter lvalue types: %s' %(excp)) + print('Failed to get parameter lvalue types: %s' % (excp)) # Format the rvalue of each variable expression for var in variables: @@ -334,20 +347,22 @@ class CppTopBlockGenerator(object): parameters = fg.get_parameters() for param in parameters: - type_translation = {'eng_float' : 'double', 'intx' : 'int', 'str' : 'std::string', 'complex': 'gr_complex'}; + type_translation = {'eng_float': 'double', 'intx': 'int', + 'str': 'std::string', 'complex': 'gr_complex'} param.vtype = type_translation[param.params['type'].value] if param.vtype == 'gr_complex': - evaluated = ast.literal_eval(param.params['value'].value.strip()) - cpp_cmplx = '{' + str(evaluated.real) + ', ' + str(evaluated.imag) + '}' + evaluated = ast.literal_eval( + param.params['value'].value.strip()) + cpp_cmplx = '{' + str(evaluated.real) + \ + ', ' + str(evaluated.imag) + '}' # Update the 'var_make' entry in the cpp_templates dictionary d = param.cpp_templates cpp_expr = d['var_make'].replace('${value}', cpp_cmplx) - d.update({'var_make':cpp_expr}) + d.update({'var_make': cpp_expr}) param.cpp_templates = d - def _callbacks(self): fg = self._flow_graph variables = fg.get_cpp_variables() @@ -361,16 +376,19 @@ class CppTopBlockGenerator(object): callbacks_all = [] for block in fg.iter_enabled_blocks(): if not (block.is_virtual_sink() or block.is_virtual_source()): - callbacks_all.extend(expr_utils.expr_replace(cb, replace_dict) for cb in block.get_cpp_callbacks()) + callbacks_all.extend(expr_utils.expr_replace( + cb, replace_dict) for cb in block.get_cpp_callbacks()) # Map var id to callbacks def uses_var_id(callback): used = expr_utils.get_variable_dependencies(callback, [var_id]) - return used and ('this->' + var_id in callback) # callback might contain var_id itself + # callback might contain var_id itself + return used and ('this->' + var_id in callback) callbacks = {} for var_id in var_ids: - callbacks[var_id] = [callback for callback in callbacks_all if uses_var_id(callback)] + callbacks[var_id] = [ + callback for callback in callbacks_all if uses_var_id(callback)] return callbacks @@ -402,14 +420,17 @@ class CppTopBlockGenerator(object): # Get the virtual blocks and resolve their connections connection_factory = fg.parent_platform.Connection - virtual_source_connections = [c for c in connections if isinstance(c.source_block, blocks.VirtualSource)] + virtual_source_connections = [c for c in connections if isinstance( + c.source_block, blocks.VirtualSource)] for connection in virtual_source_connections: sink = connection.sink_port for source in connection.source_port.resolve_virtual_source(): - resolved = connection_factory(fg.orignal_flowgraph, source, sink) + resolved = connection_factory( + fg.orignal_flowgraph, source, sink) connections.append(resolved) - virtual_connections = [c for c in connections if (isinstance(c.source_block, blocks.VirtualSource) or isinstance(c.sink_block, blocks.VirtualSink))] + virtual_connections = [c for c in connections if (isinstance( + c.source_block, blocks.VirtualSource) or isinstance(c.sink_block, blocks.VirtualSink))] for connection in virtual_connections: # Remove the virtual connection connections.remove(connection) @@ -423,7 +444,8 @@ class CppTopBlockGenerator(object): for block in bypassed_blocks: # Get the upstream connection (off of the sink ports) # Use *connections* not get_connections() - source_connection = [c for c in connections if c.sink_port == block.sinks[0]] + source_connection = [ + c for c in connections if c.sink_port == block.sinks[0]] # The source connection should never have more than one element. assert (len(source_connection) == 1) @@ -435,7 +457,8 @@ class CppTopBlockGenerator(object): if not sink.enabled: # Ignore disabled connections continue - connection = connection_factory(fg.orignal_flowgraph, source_port, sink.sink_port) + connection = connection_factory( + fg.orignal_flowgraph, source_port, sink.sink_port) connections.append(connection) # Remove this sink connection connections.remove(sink) @@ -451,7 +474,8 @@ class CppTopBlockGenerator(object): template = templates[con.type] if con.source_port.dtype != 'bus': - code = template.render(make_port_sig=make_port_sig, source=con.source_port, sink=con.sink_port) + code = template.render( + make_port_sig=make_port_sig, source=con.source_port, sink=con.sink_port) if not self._generate_options.startswith('hb'): code = 'this->tb->' + code rendered.append(code) @@ -470,7 +494,8 @@ class CppTopBlockGenerator(object): hidden_portb = portb.parent.sinks[port_num] connection = fg.parent_platform.Connection( parent=self, source=hidden_porta, sink=hidden_portb) - code = template.render(make_port_sig=make_port_sig, source=hidden_porta, sink=hidden_portb) + code = template.render( + make_port_sig=make_port_sig, source=hidden_porta, sink=hidden_portb) if not self._generate_options.startswith('hb'): code = 'this->tb->' + code rendered.append(code) diff --git a/grc/core/generator/hier_block.py b/grc/core/generator/hier_block.py index d609a50ff9..0985437ed4 100644 --- a/grc/core/generator/hier_block.py +++ b/grc/core/generator/hier_block.py @@ -128,7 +128,6 @@ class HierBlockGenerator(TopBlockGenerator): 'set_{key}(${{ {key} }})'.format(key=param_block.name) for param_block in parameters ] - # Documentation data['documentation'] = "\n".join(field for field in ( self._flow_graph.get_option('author'), @@ -178,7 +177,8 @@ def get_hier_block_io(flow_graph, direction, domain=None): Returns a list of blocks """ - pads = flow_graph.get_pad_sources() if direction == 'inputs' else flow_graph.get_pad_sinks() + pads = flow_graph.get_pad_sources( + ) if direction == 'inputs' else flow_graph.get_pad_sinks() for pad in pads: for port in (pad.sources if direction == 'inputs' else pad.sinks): diff --git a/grc/core/generator/top_block.py b/grc/core/generator/top_block.py index 275921da51..2abfd0fbb4 100644 --- a/grc/core/generator/top_block.py +++ b/grc/core/generator/top_block.py @@ -30,7 +30,8 @@ class TopBlockGenerator(object): """ self._flow_graph = FlowGraphProxy(flow_graph) - self._generate_options = self._flow_graph.get_option('generate_options') + self._generate_options = self._flow_graph.get_option( + 'generate_options') self._mode = TOP_BLOCK_FILE_MODE # Handle the case where the directory is read-only @@ -58,7 +59,8 @@ class TopBlockGenerator(object): "This is usually undesired. Consider " "removing the throttle block.") - deprecated_block_keys = {b.name for b in self._flow_graph.get_enabled_blocks() if b.flags.deprecated} + deprecated_block_keys = { + b.name for b in self._flow_graph.get_enabled_blocks() if b.flags.deprecated} for key in deprecated_block_keys: Messages.send_warning("The block {!r} is deprecated.".format(key)) @@ -67,7 +69,8 @@ class TopBlockGenerator(object): self._warnings() fg = self._flow_graph - self.title = fg.get_option('title') or fg.get_option('id').replace('_', ' ').title() + self.title = fg.get_option('title') or fg.get_option( + 'id').replace('_', ' ').title() variables = fg.get_variables() parameters = fg.get_parameters() monitors = fg.get_monitors() @@ -97,7 +100,8 @@ class TopBlockGenerator(object): fg = self._flow_graph platform = fg.parent - title = fg.get_option('title') or fg.get_option('id').replace('_', ' ').title() + title = fg.get_option('title') or fg.get_option( + 'id').replace('_', ' ').title() variables = fg.get_variables() parameters = fg.get_parameters() monitors = fg.get_monitors() @@ -110,7 +114,8 @@ class TopBlockGenerator(object): else: continue - file_path = os.path.join(self.output_dir, block.module_name + ".py") + file_path = os.path.join( + self.output_dir, block.module_name + ".py") output.append((file_path, src)) self.namespace = { @@ -131,7 +136,8 @@ class TopBlockGenerator(object): **self.namespace ) # strip trailing white-space - flow_graph_code = "\n".join(line.rstrip() for line in flow_graph_code.split("\n")) + flow_graph_code = "\n".join(line.rstrip() + for line in flow_graph_code.split("\n")) output.append((self.file_path, flow_graph_code)) return output @@ -142,7 +148,8 @@ class TopBlockGenerator(object): seen = set() output = [] - need_path_hack = any(imp.endswith("# grc-generated hier_block") for imp in imports) + need_path_hack = any(imp.endswith( + "# grc-generated hier_block") for imp in imports) if need_path_hack: output.insert(0, textwrap.dedent("""\ import os @@ -184,7 +191,8 @@ class TopBlockGenerator(object): def _get_block_sort_text(block): code = block.templates.render('make').replace(block.name, ' ') try: - code += block.params['gui_hint'].get_value() # Newer gui markup w/ qtgui + # Newer gui markup w/ qtgui + code += block.params['gui_hint'].get_value() except KeyError: # No gui hint pass @@ -195,7 +203,8 @@ class TopBlockGenerator(object): if b.enabled and not (b.get_bypassed() or b.is_import or b.is_snippet or b in parameters or b.key == 'options') ] - blocks = expr_utils.sort_objects(blocks, operator.attrgetter('name'), _get_block_sort_text) + blocks = expr_utils.sort_objects( + blocks, operator.attrgetter('name'), _get_block_sort_text) blocks_make = [] for block in blocks: make = block.templates.render('make') @@ -217,16 +226,19 @@ class TopBlockGenerator(object): callbacks_all = [] for block in fg.iter_enabled_blocks(): - callbacks_all.extend(expr_utils.expr_replace(cb, replace_dict) for cb in block.get_callbacks()) + callbacks_all.extend(expr_utils.expr_replace( + cb, replace_dict) for cb in block.get_callbacks()) # Map var id to callbacks def uses_var_id(callback): used = expr_utils.get_variable_dependencies(callback, [var_id]) - return used and (('self.' + var_id in callback) or ('this->' + var_id in callback)) # callback might contain var_id itself + # callback might contain var_id itself + return used and (('self.' + var_id in callback) or ('this->' + var_id in callback)) callbacks = {} for var_id in var_ids: - callbacks[var_id] = [callback for callback in callbacks_all if uses_var_id(callback)] + callbacks[var_id] = [ + callback for callback in callbacks_all if uses_var_id(callback)] return callbacks @@ -253,14 +265,17 @@ class TopBlockGenerator(object): # Get the virtual blocks and resolve their connections connection_factory = fg.parent_platform.Connection - virtual_source_connections = [c for c in connections if isinstance(c.source_block, blocks.VirtualSource)] + virtual_source_connections = [c for c in connections if isinstance( + c.source_block, blocks.VirtualSource)] for connection in virtual_source_connections: sink = connection.sink_port for source in connection.source_port.resolve_virtual_source(): - resolved = connection_factory(fg.orignal_flowgraph, source, sink) + resolved = connection_factory( + fg.orignal_flowgraph, source, sink) connections.append(resolved) - virtual_connections = [c for c in connections if (isinstance(c.source_block, blocks.VirtualSource) or isinstance(c.sink_block, blocks.VirtualSink))] + virtual_connections = [c for c in connections if (isinstance( + c.source_block, blocks.VirtualSource) or isinstance(c.sink_block, blocks.VirtualSink))] for connection in virtual_connections: # Remove the virtual connection connections.remove(connection) @@ -274,7 +289,8 @@ class TopBlockGenerator(object): for block in bypassed_blocks: # Get the upstream connection (off of the sink ports) # Use *connections* not get_connections() - source_connection = [c for c in connections if c.sink_port == block.sinks[0]] + source_connection = [ + c for c in connections if c.sink_port == block.sinks[0]] # The source connection should never have more than one element. assert (len(source_connection) == 1) @@ -286,7 +302,8 @@ class TopBlockGenerator(object): if not sink.enabled: # Ignore disabled connections continue - connection = connection_factory(fg.orignal_flowgraph, source_port, sink.sink_port) + connection = connection_factory( + fg.orignal_flowgraph, source_port, sink.sink_port) connections.append(connection) # Remove this sink connection connections.remove(sink) @@ -301,7 +318,8 @@ class TopBlockGenerator(object): for con in sorted(connections, key=by_domain_and_blocks): template = templates[con.type] if con.source_port.dtype != 'bus': - code = template.render(make_port_sig=make_port_sig, source=con.source_port, sink=con.sink_port) + code = template.render( + make_port_sig=make_port_sig, source=con.source_port, sink=con.sink_port) rendered.append(code) else: # Bus ports need to iterate over the underlying connections and then render @@ -318,10 +336,8 @@ class TopBlockGenerator(object): hidden_portb = portb.parent.sinks[port_num_b] connection = fg.parent_platform.Connection( parent=self, source=hidden_porta, sink=hidden_portb) - code = template.render(make_port_sig=make_port_sig, source=hidden_porta, sink=hidden_portb) + code = template.render( + make_port_sig=make_port_sig, source=hidden_porta, sink=hidden_portb) rendered.append(code) - - - return rendered diff --git a/grc/core/io/yaml.py b/grc/core/io/yaml.py index d653dc5f77..3e10af55d1 100644 --- a/grc/core/io/yaml.py +++ b/grc/core/io/yaml.py @@ -11,6 +11,7 @@ import yaml from ..params.param import attributed_str + class GRCDumper(yaml.SafeDumper): @classmethod def add(cls, data_type): @@ -21,7 +22,8 @@ class GRCDumper(yaml.SafeDumper): def represent_ordered_mapping(self, data): value = [] - node = yaml.MappingNode(u'tag:yaml.org,2002:map', value, flow_style=False) + node = yaml.MappingNode(u'tag:yaml.org,2002:map', + value, flow_style=False) if self.alias_key is not None: self.represented_objects[self.alias_key] = node @@ -62,7 +64,8 @@ class MultiLineString(str): GRCDumper.add_representer(OrderedDict, GRCDumper.represent_ordered_mapping) -GRCDumper.add_representer(OrderedDictFlowing, GRCDumper.represent_ordered_mapping_flowing) +GRCDumper.add_representer( + OrderedDictFlowing, GRCDumper.represent_ordered_mapping_flowing) GRCDumper.add_representer(ListFlowing, GRCDumper.represent_list_flowing) GRCDumper.add_representer(tuple, GRCDumper.represent_list) GRCDumper.add_representer(MultiLineString, GRCDumper.represent_ml_string) @@ -71,7 +74,8 @@ GRCDumper.add_representer(attributed_str, GRCDumper.represent_str) def dump(data, stream=None, **kwargs): - config = dict(stream=stream, default_flow_style=False, indent=4, Dumper=GRCDumper) + config = dict(stream=stream, default_flow_style=False, + indent=4, Dumper=GRCDumper) config.update(kwargs) return yaml.dump_all([data], **config) diff --git a/grc/core/params/dtypes.py b/grc/core/params/dtypes.py index 1c851c4d2c..a582bcae85 100644 --- a/grc/core/params/dtypes.py +++ b/grc/core/params/dtypes.py @@ -16,7 +16,8 @@ from .. import Constants ID_BLACKLIST = ['self', 'default'] + dir(builtins) try: from gnuradio import gr - ID_BLACKLIST.extend(attr for attr in dir(gr.top_block()) if not attr.startswith('_')) + ID_BLACKLIST.extend(attr for attr in dir( + gr.top_block()) if not attr.startswith('_')) except (ImportError, AttributeError): pass @@ -32,12 +33,13 @@ def validates(*dtypes): return func return decorator + class ValidateError(Exception): """Raised by validate functions""" @validates('id') -def validate_block_id(param,black_listed_ids): +def validate_block_id(param, black_listed_ids): value = param.value # Can python use this as a variable? @@ -45,10 +47,11 @@ def validate_block_id(param,black_listed_ids): raise ValidateError('ID "{}" must begin with a letter and may contain letters, numbers, ' 'and underscores.'.format(value)) if value in (black_listed_ids + ID_BLACKLIST) and \ - not getattr(param.parent_block, 'exempt_from_id_validation', False): + not getattr(param.parent_block, 'exempt_from_id_validation', False): # Grant blacklist exemption to epy blocks and modules raise ValidateError('ID "{}" is blacklisted.'.format(value)) - block_names = [block.name for block in param.parent_flowgraph.iter_enabled_blocks()] + block_names = [ + block.name for block in param.parent_flowgraph.iter_enabled_blocks()] # Id should only appear once, or zero times if block is disabled if param.key == 'id' and block_names.count(value) > 1: raise ValidateError('ID "{}" is not unique.'.format(value)) @@ -58,7 +61,7 @@ def validate_block_id(param,black_listed_ids): @validates('name') -def validate_name(param,black_listed_ids): +def validate_name(param, black_listed_ids): # Name of a function or other block that will be generated literally not as a string value = param.value @@ -71,7 +74,7 @@ def validate_name(param,black_listed_ids): @validates('stream_id') -def validate_stream_id(param,black_listed_ids): +def validate_stream_id(param, black_listed_ids): value = param.value stream_ids = [ block.params['stream_id'].value @@ -88,7 +91,7 @@ def validate_stream_id(param,black_listed_ids): @validates('complex', 'real', 'float', 'int') -def validate_scalar(param,black_listed_ids): +def validate_scalar(param, black_listed_ids): valid_types = Constants.PARAM_TYPE_MAP[param.dtype] if not isinstance(param.get_evaluated(), valid_types): raise ValidateError('Expression {!r} is invalid for type {!r}.'.format( @@ -96,19 +99,21 @@ def validate_scalar(param,black_listed_ids): @validates('complex_vector', 'real_vector', 'float_vector', 'int_vector') -def validate_vector(param,black_listed_ids): +def validate_vector(param, black_listed_ids): # todo: check vector types if param.get_evaluated() is None: - raise ValidateError('Expression {!r} is invalid for type{!r}.'.format(param.get_evaluated(), param.dtype)) + raise ValidateError('Expression {!r} is invalid for type{!r}.'.format( + param.get_evaluated(), param.dtype)) valid_types = Constants.PARAM_TYPE_MAP[param.dtype.split('_', 1)[0]] if not all(isinstance(item, valid_types) for item in param.get_evaluated()): raise ValidateError('Expression {!r} is invalid for type {!r}.'.format( param.get_evaluated(), param.dtype)) + @validates('gui_hint') -def validate_gui_hint(param,black_listed_ids): +def validate_gui_hint(param, black_listed_ids): try: param.parse_gui_hint(param.value) except Exception as e: diff --git a/grc/core/params/param.py b/grc/core/params/param.py index 122480dfa2..2cde1facdb 100644 --- a/grc/core/params/param.py +++ b/grc/core/params/param.py @@ -18,6 +18,7 @@ from .template_arg import TemplateArg attributed_str = type('attributed_str', (str,), {}) + @setup_names class Param(Element): @@ -73,12 +74,14 @@ class Param(Element): options.attributes = collections.defaultdict(dict) padding = [''] * max(len(values), len(labels)) - attributes = {key: value + padding for key, value in attributes.items()} + attributes = {key: value + padding for key, + value in attributes.items()} for i, option in enumerate(values): # Test against repeated keys if option in options: - raise KeyError('Value "{}" already exists in options'.format(option)) + raise KeyError( + 'Value "{}" already exists in options'.format(option)) # get label try: label = str(labels[i]) @@ -86,7 +89,8 @@ class Param(Element): label = str(option) # Store the option options[option] = label - options.attributes[option] = {attrib: values[i] for attrib, values in attributes.items()} + options.attributes[option] = {attrib: values[i] + for attrib, values in attributes.items()} default = next(iter(options)) if options else '' if not self.value: @@ -151,12 +155,13 @@ class Param(Element): """ Element.validate(self) if self.dtype not in Constants.PARAM_TYPE_NAMES: - self.add_error_message('Type "{}" is not a possible type.'.format(self.dtype)) + 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,self.parent_flowgraph.get_imported_names()) + validator(self, self.parent_flowgraph.get_imported_names()) except dtypes.ValidateError as e: self.add_error_message(str(e)) @@ -207,12 +212,14 @@ class Param(Element): if expr: try: if isinstance(expr, str) and self.is_float(expr[:-1]): - scale_factor = expr[-1:] - if scale_factor in self.scale: - expr = str(float(expr[:-1])*self.scale[scale_factor]) + scale_factor = expr[-1:] + if scale_factor in self.scale: + expr = str(float(expr[:-1]) * + self.scale[scale_factor]) value = self.parent_flowgraph.evaluate(expr) except Exception as e: - raise Exception('Value "{}" cannot be evaluated:\n{}'.format(expr, e)) + raise Exception( + 'Value "{}" cannot be evaluated:\n{}'.format(expr, e)) else: value = None # No parameter value provided if dtype == 'hex': @@ -230,7 +237,8 @@ class Param(Element): try: value = self.parent.parent.evaluate(expr) except Exception as value: - raise Exception('Value "{}" cannot be evaluated:\n{}'.format(expr, value)) + raise Exception( + 'Value "{}" cannot be evaluated:\n{}'.format(expr, value)) if not isinstance(value, Constants.VECTOR_TYPES): self._lisitify_flag = True value = [value] @@ -339,7 +347,8 @@ class Param(Element): e = self.parent_flowgraph.evaluate(pos) if not isinstance(e, (list, tuple)) or len(e) not in (2, 4) or not all(isinstance(ei, int) for ei in e): - raise Exception('Invalid GUI Hint entered: {e!r} (Must be a list of {{2,4}} non-negative integers).'.format(e=e)) + raise Exception( + 'Invalid GUI Hint entered: {e!r} (Must be a list of {{2,4}} non-negative integers).'.format(e=e)) if len(e) == 2: row, col = e @@ -348,10 +357,12 @@ class Param(Element): row, col, row_span, col_span = e if (row < 0) or (col < 0): - raise Exception('Invalid GUI Hint entered: {e!r} (non-negative integers only).'.format(e=e)) + raise Exception( + 'Invalid GUI Hint entered: {e!r} (non-negative integers only).'.format(e=e)) if (row_span < 1) or (col_span < 1): - raise Exception('Invalid GUI Hint entered: {e!r} (positive row/column span required).'.format(e=e)) + raise Exception( + 'Invalid GUI Hint entered: {e!r} (positive row/column span required).'.format(e=e)) return row, col, row_span, col_span @@ -360,7 +371,8 @@ class Param(Element): if block.key == 'qtgui_tab_widget' and block.name == tab) tab_block = next(iter(tabs), None) if not tab_block: - raise Exception('Invalid tab name entered: {tab} (Tab name not found).'.format(tab=tab)) + raise Exception( + 'Invalid tab name entered: {tab} (Tab name not found).'.format(tab=tab)) tab_index_size = int(tab_block.params['num_tabs'].value) if index >= tab_index_size: @@ -369,7 +381,8 @@ class Param(Element): # Collision Detection def collision_detection(row, col, row_span, col_span): - my_parent = '{tab}@{index}'.format(tab=tab, index=index) if tab else 'main' + my_parent = '{tab}@{index}'.format(tab=tab, + index=index) if tab else 'main' # Calculate hostage cells for r in range(row, row + row_span): for c in range(col, col + col_span): @@ -378,7 +391,8 @@ class Param(Element): for other in self.get_all_params('gui_hint'): if other is self: continue - collision = next(iter(self.hostage_cells & other.hostage_cells), None) + collision = next( + iter(self.hostage_cells & other.hostage_cells), None) if collision: raise Exception('Block {block!r} is also using parent {parent!r}, cell {cell!r}.'.format( block=other.parent_block.name, parent=collision[0], cell=collision[1] @@ -390,7 +404,8 @@ class Param(Element): if not pos: layout = '{tab}_layout_{index}'.format(tab=tab, index=index) else: - layout = '{tab}_grid_layout_{index}'.format(tab=tab, index=index) + layout = '{tab}_grid_layout_{index}'.format( + tab=tab, index=index) else: if not pos: layout = 'top_layout' @@ -412,8 +427,8 @@ class Param(Element): self.{layout}.setColumnStretch(c, 1) """.strip('\n')).format( layout=layout, widget=widget, - row=row, row_span=row_span, row_end=row+row_span, - col=col, col_span=col_span, col_end=col+col_span, + row=row, row_span=row_span, row_end=row + row_span, + col=col, col_span=col_span, col_end=col + col_span, ) elif self.parent_flowgraph.get_option('output_language') == 'cpp': widget_str = textwrap.dedent(""" @@ -424,17 +439,19 @@ class Param(Element): {layout}->setColumnStretch(c, 1); """.strip('\n')).format( layout=layout, widget=widget, - row=row, row_span=row_span, row_end=row+row_span, - col=col, col_span=col_span, col_end=col+col_span, + row=row, row_span=row_span, row_end=row + row_span, + col=col, col_span=col_span, col_end=col + col_span, ) else: widget_str = '' else: if self.parent_flowgraph.get_option('output_language') == 'python': - widget_str = 'self.{layout}.addWidget({widget})'.format(layout=layout, widget=widget) + widget_str = 'self.{layout}.addWidget({widget})'.format( + layout=layout, widget=widget) elif self.parent_flowgraph.get_option('output_language') == 'cpp': - widget_str = '{layout}->addWidget({widget});'.format(layout=layout, widget=widget) + widget_str = '{layout}->addWidget({widget});'.format( + layout=layout, widget=widget) else: widget_str = '' diff --git a/grc/core/params/template_arg.py b/grc/core/params/template_arg.py index 7250a71827..53adb740d4 100644 --- a/grc/core/params/template_arg.py +++ b/grc/core/params/template_arg.py @@ -5,7 +5,6 @@ # - class TemplateArg(str): """ A cheetah template argument created from a param. diff --git a/grc/core/platform.py b/grc/core/platform.py index cc825ec953..7eeb192ece 100644 --- a/grc/core/platform.py +++ b/grc/core/platform.py @@ -36,7 +36,8 @@ class Platform(Element): self.config = self.Config(*args, **kwargs) self.block_docstrings = {} - self.block_docstrings_loaded_callback = lambda: None # dummy to be replaced by BlockTreeWindow + # dummy to be replaced by BlockTreeWindow + self.block_docstrings_loaded_callback = lambda: None self._docstring_extractor = utils.extract_docs.SubprocessLoader( callback_query_result=self._save_docstring_extraction_result, @@ -108,7 +109,8 @@ class Platform(Element): Messages.send('>>> Generating: {}\n'.format(generator.file_path)) generator.write() except Exception as e: - Messages.send('>>> Generate Error: {}: {}\n'.format(file_path, str(e))) + Messages.send( + '>>> Generate Error: {}: {}\n'.format(file_path, str(e))) return None, None return flow_graph, generator.file_path @@ -126,8 +128,8 @@ class Platform(Element): self.connection_templates.clear() self.cpp_connection_templates.clear() self._block_categories.clear() - - with Cache(Constants.CACHE_FILE, version = self.config.version) as cache: + + with Cache(Constants.CACHE_FILE, version=self.config.version) as cache: for file_path in self._iter_files_in_block_path(path): if file_path.endswith('.block.yml'): @@ -147,9 +149,11 @@ class Platform(Element): data = cache.get_or_load(file_path) passed = checker.run(data) for msg in checker.messages: - logger.warning('{:<40s} {}'.format(os.path.basename(file_path), msg)) + logger.warning('{:<40s} {}'.format( + os.path.basename(file_path), msg)) if not passed: - logger.info('YAML schema check failed for: ' + file_path) + logger.info( + 'YAML schema check failed for: ' + file_path) loader(data, file_path) except Exception as error: @@ -184,8 +188,8 @@ class Platform(Element): raise RuntimeError(errstr) else: # might have some cleanup to do on the options block in particular - utils.hide_bokeh_gui_options_if_not_installed(self.blocks['options']) - + utils.hide_bokeh_gui_options_if_not_installed( + self.blocks['options']) def _iter_files_in_block_path(self, path=None, ext='yml'): """Iterator for block descriptions and category trees""" @@ -220,13 +224,15 @@ class Platform(Element): # don't load future block format versions file_format = data['file_format'] if file_format < 1 or file_format > Constants.BLOCK_DESCRIPTION_FILE_FORMAT_VERSION: - log.error('Unknown format version %d in %s', file_format, file_path) + log.error('Unknown format version %d in %s', + file_format, file_path) return block_id = data['id'] = data['id'].rstrip('_') if block_id in self.block_classes_build_in: - log.warning('Not overwriting build-in block %s with %s', block_id, file_path) + log.warning('Not overwriting build-in block %s with %s', + block_id, file_path) return if block_id in self.blocks: log.warning('Block with id "%s" loaded from\n %s\noverwritten by\n %s', @@ -256,7 +262,8 @@ class Platform(Element): try: tuple(int(color[o:o + 2], 16) / 255.0 for o in range(1, 6, 2)) except ValueError: - log.warning('Cannot parse color code "%s" in %s', color, file_path) + log.warning('Cannot parse color code "%s" in %s', + color, file_path) return self.domains[domain_id] = self.Domain( @@ -272,8 +279,10 @@ class Platform(Element): log.warn('Invalid connection template.') continue connection_id = str(source_id), str(sink_id) - self.connection_templates[connection_id] = connection.get('connect', '') - self.cpp_connection_templates[connection_id] = connection.get('cpp_connect', '') + self.connection_templates[connection_id] = connection.get( + 'connect', '') + self.cpp_connection_templates[connection_id] = connection.get( + 'cpp_connect', '') def load_category_tree_description(self, data, file_path): """Parse category tree file and add it to list""" @@ -326,7 +335,8 @@ class Platform(Element): # todo: try if not is_xml: data = yaml.safe_load(fp) - validator = schema_checker.Validator(schema_checker.FLOW_GRAPH_SCHEME) + validator = schema_checker.Validator( + schema_checker.FLOW_GRAPH_SCHEME) validator.run(data) if is_xml: @@ -340,13 +350,15 @@ class Platform(Element): data = flow_graph.export_data() try: - data['connections'] = [yaml.ListFlowing(i) for i in data['connections']] + data['connections'] = [yaml.ListFlowing( + i) for i in data['connections']] except KeyError: pass try: for d in chain([data['options']], data['blocks']): - d['states']['coordinate'] = yaml.ListFlowing(d['states']['coordinate']) + d['states']['coordinate'] = yaml.ListFlowing( + d['states']['coordinate']) except KeyError: pass @@ -393,7 +405,8 @@ class Platform(Element): Connection = Connection block_classes_build_in = blocks.build_ins - block_classes = utils.backports.ChainMap({}, block_classes_build_in) # separates build-in from loaded blocks) + # separates build-in from loaded blocks) + block_classes = utils.backports.ChainMap({}, block_classes_build_in) port_classes = { None: ports.Port, # default diff --git a/grc/core/ports/_virtual_connections.py b/grc/core/ports/_virtual_connections.py index a0e7b05a81..a328531b1a 100644 --- a/grc/core/ports/_virtual_connections.py +++ b/grc/core/ports/_virtual_connections.py @@ -2,7 +2,7 @@ # This file is part of GNU Radio # # SPDX-License-Identifier: GPL-2.0-or-later -# +# from itertools import chain @@ -28,10 +28,12 @@ def _sources_from_virtual_sink_port(sink_port, _traversed=None): """ source_ports_per_virtual_connection = ( # there can be multiple ports per virtual connection - _sources_from_virtual_source_port(c.source_port, _traversed) # type: list + _sources_from_virtual_source_port( + c.source_port, _traversed) # type: list for c in sink_port.connections(enabled=True) ) - return list(chain(*source_ports_per_virtual_connection)) # concatenate generated lists of ports + # concatenate generated lists of ports + return list(chain(*source_ports_per_virtual_connection)) def _sources_from_virtual_source_port(source_port, _traversed=None): @@ -62,7 +64,8 @@ def _sources_from_virtual_source_port(source_port, _traversed=None): _sources_from_virtual_sink_port(b.sinks[0], _traversed) # type: list for b in connected_virtual_sink_blocks ) - return list(chain(*source_ports_per_virtual_connection)) # concatenate generated lists of ports + # concatenate generated lists of ports + return list(chain(*source_ports_per_virtual_connection)) def downstream_ports(port): @@ -82,7 +85,8 @@ def _sinks_from_virtual_source_port(source_port, _traversed=None): _sinks_from_virtual_sink_port(c.sink_port, _traversed) # type: list for c in source_port.connections(enabled=True) ) - return list(chain(*sink_ports_per_virtual_connection)) # concatenate generated lists of ports + # concatenate generated lists of ports + return list(chain(*sink_ports_per_virtual_connection)) def _sinks_from_virtual_sink_port(sink_port, _traversed=None): @@ -111,4 +115,5 @@ def _sinks_from_virtual_sink_port(sink_port, _traversed=None): _sinks_from_virtual_source_port(b.sources[0], _traversed) # type: list for b in connected_virtual_source_blocks ) - return list(chain(*sink_ports_per_virtual_connection)) # concatenate generated lists of ports + # concatenate generated lists of ports + return list(chain(*sink_ports_per_virtual_connection)) diff --git a/grc/core/ports/port.py b/grc/core/ports/port.py index ade961e296..534f2138e6 100644 --- a/grc/core/ports/port.py +++ b/grc/core/ports/port.py @@ -34,17 +34,21 @@ class Port(Element): self._dir = direction self.key = id if not label: - label = id if not id.isdigit() else {'sink': 'in', 'source': 'out'}[direction] + label = id if not id.isdigit() else {'sink': 'in', 'source': 'out'}[ + direction] if dtype == 'bus': # Look for existing busses to give proper index - busses = [p for p in self.parent.ports() if p._dir == self._dir and p.dtype == 'bus'] + busses = [p for p in self.parent.ports() if p._dir == + self._dir and p.dtype == 'bus'] bus_structure = self.parent.current_bus_structure[self._dir] bus_index = len(busses) if len(bus_structure) > bus_index: - number = str(len(busses)) + '#' + str(len(bus_structure[bus_index])) + number = str(len(busses)) + '#' + \ + str(len(bus_structure[bus_index])) label = dtype + number else: - raise ValueError('Could not initialize bus port due to incompatible bus structure') + raise ValueError( + 'Could not initialize bus port due to incompatible bus structure') self.name = self._base_name = label @@ -102,7 +106,8 @@ class Port(Element): self.add_error_message('Port is not connected.') if self.dtype not in Constants.TYPE_TO_SIZEOF.keys(): - self.add_error_message('Type "{}" is not a possible type.'.format(self.dtype)) + self.add_error_message( + 'Type "{}" is not a possible type.'.format(self.dtype)) try: domain = platform.domains[self.domain] @@ -113,7 +118,8 @@ class Port(Element): self.add_error_message('Domain "{}" can have only one downstream block' ''.format(self.domain)) except KeyError: - self.add_error_message('Domain key "{}" is not registered.'.format(self.domain)) + self.add_error_message( + 'Domain key "{}" is not registered.'.format(self.domain)) def rewrite(self): del self.vlen @@ -150,9 +156,11 @@ class Port(Element): try: port = find_port(_virtual_connections.upstream_ports) or \ - find_port(_virtual_connections.downstream_ports) - self.set_evaluated('dtype', port.dtype) # we don't want to override the template - self.set_evaluated('vlen', port.vlen) # we don't want to override the template + find_port(_virtual_connections.downstream_ports) + # we don't want to override the template + self.set_evaluated('dtype', port.dtype) + # we don't want to override the template + self.set_evaluated('vlen', port.vlen) self.domain = port.domain except AttributeError: self.domain = Constants.DEFAULT_DOMAIN @@ -206,7 +214,7 @@ class Port(Element): enabled: None for all, True for enabled only, False for disabled only """ for con in self.parent_flowgraph.connections: - #TODO clean this up - but how to get past this validation + # TODO clean this up - but how to get past this validation # things don't compare simply with an x in y because # bus ports are created differently. port_in_con = False @@ -242,5 +250,6 @@ class Port(Element): if bus_structure: busses = [i for i in get_ports if i.dtype == 'bus'] bus_index = busses.index(self) - ports = filter(lambda a: ports.index(a) in bus_structure[bus_index], ports) + ports = filter(lambda a: ports.index( + a) in bus_structure[bus_index], ports) return ports diff --git a/grc/core/schema_checker/block.py b/grc/core/schema_checker/block.py index f336fc4fdb..801c68b906 100644 --- a/grc/core/schema_checker/block.py +++ b/grc/core/schema_checker/block.py @@ -12,7 +12,8 @@ PARAM_SCHEME = expand( options=list, option_labels=list, - option_attributes=Spec(types=dict, required=False, item_scheme=(str, list)), + option_attributes=Spec(types=dict, required=False, + item_scheme=(str, list)), hide=str, ) @@ -59,7 +60,8 @@ BLOCK_SCHEME = expand( value=str, templates=Spec(types=dict, required=False, item_scheme=TEMPLATES_SCHEME), - cpp_templates=Spec(types=dict, required=False, item_scheme=CPP_TEMPLATES_SCHEME), + cpp_templates=Spec(types=dict, required=False, + item_scheme=CPP_TEMPLATES_SCHEME), documentation=str, grc_source=str, diff --git a/grc/core/utils/backports/chainmap.py b/grc/core/utils/backports/chainmap.py index 1f4f4a96fb..a89c42cddd 100644 --- a/grc/core/utils/backports/chainmap.py +++ b/grc/core/utils/backports/chainmap.py @@ -30,16 +30,19 @@ class ChainMap(MutableMapping): def __getitem__(self, key): for mapping in self.maps: try: - return mapping[key] # can't use 'key in mapping' with defaultdict + # can't use 'key in mapping' with defaultdict + return mapping[key] except KeyError: pass - return self.__missing__(key) # support subclasses that define __missing__ + # support subclasses that define __missing__ + return self.__missing__(key) def get(self, key, default=None): return self[key] if key in self else default def __len__(self): - return len(set().union(*self.maps)) # reuses stored hash values if possible + # reuses stored hash values if possible + return len(set().union(*self.maps)) def __iter__(self): return iter(set().union(*self.maps)) @@ -85,7 +88,8 @@ class ChainMap(MutableMapping): try: del self.maps[0][key] except KeyError: - raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + raise KeyError( + 'Key not found in the first mapping: {!r}'.format(key)) def popitem(self): """Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.""" @@ -99,7 +103,8 @@ class ChainMap(MutableMapping): try: return self.maps[0].pop(key, *args) except KeyError: - raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + raise KeyError( + 'Key not found in the first mapping: {!r}'.format(key)) def clear(self): """Clear maps[0], leaving maps[1:] intact.""" diff --git a/grc/core/utils/descriptors/_lazy.py b/grc/core/utils/descriptors/_lazy.py index 280b128365..7d5c2c49c0 100644 --- a/grc/core/utils/descriptors/_lazy.py +++ b/grc/core/utils/descriptors/_lazy.py @@ -23,6 +23,7 @@ class lazy_property(object): def nop_write(prop): """Make this a property with a nop setter""" + def nop(self, value): pass return prop.setter(nop) diff --git a/grc/core/utils/descriptors/evaluated.py b/grc/core/utils/descriptors/evaluated.py index a9735fb861..e22ff5fc5b 100644 --- a/grc/core/utils/descriptors/evaluated.py +++ b/grc/core/utils/descriptors/evaluated.py @@ -23,7 +23,8 @@ class Evaluated(object): value = instance.parent_block.evaluate(raw) except Exception as error: if raw: - instance.add_error_message("Failed to eval '{}': {}".format(raw, error)) + instance.add_error_message( + "Failed to eval '{}': {}".format(raw, error)) return self.default if not isinstance(value, self.expected_type): @@ -68,13 +69,15 @@ class EvaluatedEnum(Evaluated): if isinstance(allowed_values, str): allowed_values = set(allowed_values.split()) self.allowed_values = allowed_values - default = default if default is not None else next(iter(self.allowed_values)) + default = default if default is not None else next( + iter(self.allowed_values)) super(EvaluatedEnum, self).__init__(str, default, name) def default_eval_func(self, instance): value = super(EvaluatedEnum, self).default_eval_func(instance) if value not in self.allowed_values: - instance.add_error_message("Value '{}' not in allowed values".format(value)) + instance.add_error_message( + "Value '{}' not in allowed values".format(value)) return self.default return value diff --git a/grc/core/utils/epy_block_io.py b/grc/core/utils/epy_block_io.py index 58becc4f2b..9947fa4831 100644 --- a/grc/core/utils/epy_block_io.py +++ b/grc/core/utils/epy_block_io.py @@ -12,7 +12,8 @@ TYPE_MAP = { 'int8': 'byte', 'uint8': 'byte', } -BlockIO = collections.namedtuple('BlockIO', 'name cls params sinks sources doc callbacks') +BlockIO = collections.namedtuple( + 'BlockIO', 'name cls params sinks sources doc callbacks') def _ports(sigs, msgs): @@ -72,11 +73,13 @@ def extract(cls): def settable(attr): try: - return callable(getattr(cls, attr).fset) # check for a property with setter + # check for a property with setter + return callable(getattr(cls, attr).fset) except AttributeError: return attr in instance.__dict__ # not dir() - only the instance attribs - callbacks = [attr for attr in dir(instance) if attr in init_args and settable(attr)] + callbacks = [attr for attr in dir( + instance) if attr in init_args and settable(attr)] sinks = _ports(instance.in_sig(), pmt.to_python(instance.message_ports_in())) diff --git a/grc/core/utils/expr_utils.py b/grc/core/utils/expr_utils.py index bc669cc7c8..cfb1274049 100644 --- a/grc/core/utils/expr_utils.py +++ b/grc/core/utils/expr_utils.py @@ -7,6 +7,7 @@ SPDX-License-Identifier: GPL-2.0-or-later """ +import ast import string @@ -64,12 +65,10 @@ def sort_objects(objects, get_id, get_expr): return [id2obj[id] for id in sorted_ids] -import ast - - def dependencies(expr, names=None): node = ast.parse(expr, mode='eval') - used_ids = frozenset([n.id for n in ast.walk(node) if isinstance(n, ast.Name)]) + used_ids = frozenset( + [n.id for n in ast.walk(node) if isinstance(n, ast.Name)]) return used_ids & names if names else used_ids @@ -93,8 +92,6 @@ def sort_objects2(objects, id_getter, expr_getter, check_circular=True): return objects - - VAR_CHARS = string.ascii_letters + string.digits + '_' @@ -205,7 +202,8 @@ def _sort_variables(exprs): # Determine dependency order while var_graph.get_nodes(): # Get a list of nodes with no edges - indep_vars = [var for var in var_graph.get_nodes() if not var_graph.get_edges(var)] + indep_vars = [var for var in var_graph.get_nodes() + if not var_graph.get_edges(var)] if not indep_vars: raise Exception('circular dependency caught in sort_variables') # Add the indep vars to the end of the list diff --git a/grc/core/utils/extract_docs.py b/grc/core/utils/extract_docs.py index 09bcaeb7c7..a92ce1777e 100644 --- a/grc/core/utils/extract_docs.py +++ b/grc/core/utils/extract_docs.py @@ -55,7 +55,8 @@ def docstring_guess_from_key(key): else: return doc_strings - pattern = re.compile('^' + init_name.replace('_', '_*').replace('x', r'\w') + r'\w*$') + pattern = re.compile( + '^' + init_name.replace('_', '_*').replace('x', r'\w') + r'\w*$') for match in filter(pattern.match, dir(module)): try: doc_strings[match] = getattr(module, match).__doc__ @@ -135,7 +136,8 @@ class SubprocessLoader(object): break try: self._worker = subprocess.Popen( - args=(sys.executable, '-uc', self.BOOTSTRAP.format(__file__)), + args=(sys.executable, '-uc', + self.BOOTSTRAP.format(__file__)), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) @@ -286,7 +288,8 @@ elif __name__ == '__main__': # r.query('uhd_source') r.query('expr_utils_graph') r.query('blocks_add_cc') - r.query('blocks_add_cc', ['import gnuradio.blocks'], 'gnuradio.blocks.add_cc(') + r.query('blocks_add_cc', ['import gnuradio.blocks'], + 'gnuradio.blocks.add_cc(') # r.query('analog_feedforward_agc_cc') # r.query('uhd_source') # r.query('uhd_source') diff --git a/grc/core/utils/flow_graph_complexity.py b/grc/core/utils/flow_graph_complexity.py index e8962b0ae3..5731769a19 100644 --- a/grc/core/utils/flow_graph_complexity.py +++ b/grc/core/utils/flow_graph_complexity.py @@ -37,17 +37,20 @@ def calculate(flowgraph): # Disabled multiplier if enabled > 0: - disabled_multi = 1 / (max(1 - ((blocks - enabled) / max(blocks, 1)), 0.05)) + disabled_multi = 1 / \ + (max(1 - ((blocks - enabled) / max(blocks, 1)), 0.05)) else: disabled_multi = 1 # Connection multiplier (How many connections ) if (connections - disabled_connections) > 0: - conn_multi = 1 / (max(1 - (disabled_connections / max(connections, 1)), 0.05)) + conn_multi = 1 / \ + (max(1 - (disabled_connections / max(connections, 1)), 0.05)) else: conn_multi = 1 - final = round(max((dbal - 1) * disabled_multi * conn_multi * connections, 0.0) / 1000000, 6) + final = round(max((dbal - 1) * disabled_multi * + conn_multi * connections, 0.0) / 1000000, 6) return final except Exception: |