From 7f7fa2f91467fdb2b11312be8562e7b51fdeb199 Mon Sep 17 00:00:00 2001
From: Sebastian Koslowski <sebastian.koslowski@gmail.com>
Date: Tue, 3 May 2016 17:13:08 +0200
Subject: grc: added yaml/mako support

Includes basic converter from XML/Cheetah to YAML/Mako based block format.
---
 grc/core/Block.py | 784 ------------------------------------------------------
 1 file changed, 784 deletions(-)
 delete mode 100644 grc/core/Block.py

(limited to 'grc/core/Block.py')

diff --git a/grc/core/Block.py b/grc/core/Block.py
deleted file mode 100644
index 087815b941..0000000000
--- a/grc/core/Block.py
+++ /dev/null
@@ -1,784 +0,0 @@
-"""
-Copyright 2008-2015 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
-"""
-
-from __future__ import absolute_import
-
-import collections
-import itertools
-import ast
-
-import six
-from six.moves import map, range
-
-from Cheetah.Template import Template
-
-from . import utils
-
-from . Constants import (
-    BLOCK_FLAG_NEED_QT_GUI,
-    ADVANCED_PARAM_TAB,
-    BLOCK_FLAG_THROTTLE, BLOCK_FLAG_DISABLE_BYPASS,
-    BLOCK_FLAG_DEPRECATED,
-)
-from . Element import Element, lazy_property
-
-
-def _get_elem(iterable, key):
-    items = list(iterable)
-    for item in items:
-        if item.key == key:
-            return item
-    return ValueError('Key "{}" not found in {}.'.format(key, items))
-
-
-class Block(Element):
-
-    is_block = True
-
-    STATE_LABELS = ['disabled', 'enabled', 'bypassed']
-
-    def __init__(self, parent, key, name, **n):
-        """Make a new block from nested data."""
-        super(Block, self).__init__(parent)
-
-        self.key = key
-        self.name = name
-        self.category = [cat.strip() for cat in n.get('category', '').split('/') if cat.strip()]
-        self.flags = n.get('flags', '')
-        self._doc = n.get('doc', '').strip('\n').replace('\\\n', '')
-
-        # Backwards compatibility
-        if n.get('throttle') and BLOCK_FLAG_THROTTLE not in self.flags:
-            self.flags += BLOCK_FLAG_THROTTLE
-
-        self._imports = [i.strip() for i in n.get('import', [])]
-        self._make = n.get('make')
-        self._var_make = n.get('var_make')
-        self._var_value = n.get('var_value', '$value')
-        self._checks = n.get('check', [])
-        self._callbacks = n.get('callback', [])
-
-        self._grc_source = n.get('grc_source', '')
-        self.block_wrapper_path = n.get('block_wrapper_path')
-
-        # Virtual source/sink and pad source/sink blocks are
-        # indistinguishable from normal GR blocks. Make explicit
-        # checks for them here since they have no work function or
-        # buffers to manage.
-        self.is_virtual_or_pad = self.key in (
-            "virtual_source", "virtual_sink", "pad_source", "pad_sink")
-        self.is_variable = self.key.startswith('variable')
-        self.is_import = (self.key == 'import')
-
-        # Disable blocks that are virtual/pads or variables
-        if self.is_virtual_or_pad or self.is_variable:
-            self.flags += BLOCK_FLAG_DISABLE_BYPASS
-
-        params_n = n.get('param', [])
-        sources_n = n.get('source', [])
-        sinks_n = n.get('sink', [])
-
-        # Get list of param tabs
-        self.params = collections.OrderedDict()
-        self._init_params(
-            params_n=params_n,
-            has_sinks=len(sinks_n),
-            has_sources=len(sources_n)
-        )
-
-        self.sources = self._init_ports(sources_n, direction='source')
-        self.sinks = self._init_ports(sinks_n, direction='sink')
-        self.active_sources = []  # on rewrite
-        self.active_sinks = []  # on rewrite
-
-        self.states = {'_enabled': True}
-
-        self._init_bus_ports(n)
-
-    def _init_params(self, params_n, has_sources, has_sinks):
-        param_factory = self.parent_platform.get_new_param
-
-        def add_param(key, **kwargs):
-            self.params[key] = param_factory(self, key=key, **kwargs)
-
-        add_param(key='id', name='ID', type='id')
-
-        if not (self.is_virtual_or_pad or self.is_variable or self.key == 'options'):
-            add_param(key='alias', name='Block Alias', type='string',
-                      hide='part', tab=ADVANCED_PARAM_TAB)
-
-        if not self.is_virtual_or_pad and (has_sources or has_sinks):
-            add_param(key='affinity', name='Core Affinity', type='int_vector',
-                      hide='part', tab=ADVANCED_PARAM_TAB)
-
-        if not self.is_virtual_or_pad and has_sources:
-            add_param(key='minoutbuf', name='Min Output Buffer', type='int',
-                      hide='part', value='0', tab=ADVANCED_PARAM_TAB)
-            add_param(key='maxoutbuf', name='Max Output Buffer', type='int',
-                      hide='part', value='0', tab=ADVANCED_PARAM_TAB)
-
-        base_params_n = {}
-        for param_n in params_n:
-            key = param_n['key']
-            if key in self.params:
-                raise Exception('Key "{}" already exists in params'.format(key))
-
-            base_key = param_n.get('base_key', None)
-            param_n_ext = base_params_n.get(base_key, {}).copy()
-            param_n_ext.update(param_n)
-            self.params[key] = param_factory(self, **param_n_ext)
-            base_params_n[key] = param_n_ext
-
-        add_param(key='comment', name='Comment', type='_multiline', hide='part',
-                  value='', tab=ADVANCED_PARAM_TAB)
-
-    def _init_ports(self, ports_n, direction):
-        port_factory = self.parent_platform.get_new_port
-        ports = []
-        port_keys = set()
-        stream_port_keys = itertools.count()
-        for i, port_n in enumerate(ports_n):
-            port_n.setdefault('key', str(next(stream_port_keys)))
-            port = port_factory(parent=self, direction=direction, **port_n)
-            key = port.key
-            if key in port_keys:
-                raise Exception('Key "{}" already exists in {}'.format(key, direction))
-            port_keys.add(key)
-            ports.append(port)
-        return ports
-
-    ##############################################
-    # validation and rewrite
-    ##############################################
-    def rewrite(self):
-        """
-        Add and remove ports to adjust for the nports.
-        """
-        Element.rewrite(self)
-
-        def rekey(ports):
-            """Renumber non-message/message ports"""
-            domain_specific_port_index = collections.defaultdict(int)
-            for port in [p for p in ports if p.key.isdigit()]:
-                domain = port.domain
-                port.key = str(domain_specific_port_index[domain])
-                domain_specific_port_index[domain] += 1
-
-        # Adjust nports
-        for ports in (self.sources, self.sinks):
-            self._rewrite_nports(ports)
-            self.back_ofthe_bus(ports)
-            rekey(ports)
-
-        self._rewrite_bus_ports()
-
-        # disconnect hidden ports
-        for port in itertools.chain(self.sources, self.sinks):
-            if port.get_hide():
-                for connection in port.get_connections():
-                    self.parent_flowgraph.remove_element(connection)
-
-
-        self.active_sources = [p for p in self.get_sources_gui() if not p.get_hide()]
-        self.active_sinks = [p for p in self.get_sinks_gui() if not p.get_hide()]
-
-    def _rewrite_nports(self, ports):
-        for port in ports:
-            if port.is_clone:  # Not a master port and no left-over clones
-                continue
-            nports = port.get_nports() or 1
-            for clone in port.clones[nports-1:]:
-                # Remove excess connections
-                for connection in clone.get_connections():
-                    self.parent_flowgraph.remove_element(connection)
-                port.remove_clone(clone)
-                ports.remove(clone)
-            # Add more cloned ports
-            for j in range(1 + len(port.clones), nports):
-                clone = port.add_clone()
-                ports.insert(ports.index(port) + j, clone)
-
-    def validate(self):
-        """
-        Validate this block.
-        Call the base class validate.
-        Evaluate the checks: each check must evaluate to True.
-        """
-        Element.validate(self)
-        self._run_checks()
-        self._validate_generate_mode_compat()
-        self._validate_var_value()
-
-    def _run_checks(self):
-        """Evaluate the checks"""
-        for check in self._checks:
-            check_res = self.resolve_dependencies(check)
-            try:
-                if not self.parent.evaluate(check_res):
-                    self.add_error_message('Check "{}" failed.'.format(check))
-            except:
-                self.add_error_message('Check "{}" did not evaluate.'.format(check))
-
-    def _validate_generate_mode_compat(self):
-        """check if this is a GUI block and matches the selected generate option"""
-        current_generate_option = self.parent.get_option('generate_options')
-
-        def check_generate_mode(label, flag, valid_options):
-            block_requires_mode = (
-                flag in self.flags or self.name.upper().startswith(label)
-            )
-            if block_requires_mode and current_generate_option not in valid_options:
-                self.add_error_message("Can't generate this block in mode: {} ".format(
-                                       repr(current_generate_option)))
-
-        check_generate_mode('QT GUI', BLOCK_FLAG_NEED_QT_GUI, ('qt_gui', 'hb_qt_gui'))
-
-    def _validate_var_value(self):
-        """or variables check the value (only if var_value is used)"""
-        if self.is_variable and self._var_value != '$value':
-            value = self._var_value
-            try:
-                value = self.get_var_value()
-                self.parent.evaluate(value)
-            except Exception as err:
-                self.add_error_message('Value "{}" cannot be evaluated:\n{}'.format(value, err))
-
-    ##############################################
-    # props
-    ##############################################
-
-    @lazy_property
-    def is_throtteling(self):
-        return BLOCK_FLAG_THROTTLE in self.flags
-
-    @lazy_property
-    def is_deprecated(self):
-        return BLOCK_FLAG_DEPRECATED in self.flags
-
-    @property
-    def documentation(self):
-        documentation = self.parent_platform.block_docstrings.get(self.key, {})
-        from_xml = self._doc.strip()
-        if from_xml:
-            documentation[''] = from_xml
-        return documentation
-
-    @property
-    def comment(self):
-        return self.params['comment'].get_value()
-
-    @property
-    def state(self):
-        """Gets the block's current state."""
-        try:
-            return self.STATE_LABELS[int(self.states['_enabled'])]
-        except ValueError:
-            return 'enabled'
-
-    @state.setter
-    def state(self, value):
-        """Sets the state for the block."""
-        try:
-            encoded = self.STATE_LABELS.index(value)
-        except ValueError:
-            encoded = 1
-        self.states['_enabled'] = encoded
-
-    # Enable/Disable Aliases
-    @property
-    def enabled(self):
-        """Get the enabled state of the block"""
-        return self.state != 'disabled'
-
-    ##############################################
-    # Getters (old)
-    ##############################################
-
-    def get_imports(self, raw=False):
-        """
-        Resolve all import statements.
-        Split each import statement at newlines.
-        Combine all import statements into a list.
-        Filter empty imports.
-
-        Returns:
-            a list of import statements
-        """
-        if raw:
-            return self._imports
-        return [i for i in sum((self.resolve_dependencies(i).split('\n')
-                                for i in self._imports), []) if i]
-
-    def get_make(self, raw=False):
-        if raw:
-            return self._make
-        return self.resolve_dependencies(self._make)
-
-    def get_var_make(self):
-        return self.resolve_dependencies(self._var_make)
-
-    def get_var_value(self):
-        return self.resolve_dependencies(self._var_value)
-
-    def get_callbacks(self):
-        """
-        Get a list of function callbacks for this block.
-
-        Returns:
-            a list of strings
-        """
-        def make_callback(callback):
-            callback = self.resolve_dependencies(callback)
-            if 'self.' in callback:
-                return callback
-            return 'self.{}.{}'.format(self.get_id(), callback)
-        return [make_callback(c) for c in self._callbacks]
-
-    def is_virtual_sink(self):
-        return self.key == 'virtual_sink'
-
-    def is_virtual_source(self):
-        return self.key == 'virtual_source'
-
-    # Block bypassing
-    def get_bypassed(self):
-        """
-        Check if the block is bypassed
-        """
-        return self.state == 'bypassed'
-
-    def set_bypassed(self):
-        """
-        Bypass the block
-
-        Returns:
-            True if block chagnes state
-        """
-        if self.state != 'bypassed' and self.can_bypass():
-            self.state = 'bypassed'
-            return True
-        return False
-
-    def can_bypass(self):
-        """ Check the number of sinks and sources and see if this block can be bypassed """
-        # Check to make sure this is a single path block
-        # Could possibly support 1 to many blocks
-        if len(self.sources) != 1 or len(self.sinks) != 1:
-            return False
-        if not (self.sources[0].get_type() == self.sinks[0].get_type()):
-            return False
-        if BLOCK_FLAG_DISABLE_BYPASS in self.flags:
-            return False
-        return True
-
-    def __str__(self):
-        return 'Block - {} - {}({})'.format(self.get_id(), self.name, self.key)
-
-    def get_id(self):
-        return self.params['id'].get_value()
-
-    def get_ports(self):
-        return self.sources + self.sinks
-
-    def get_ports_gui(self):
-        return self.get_sources_gui() + self.get_sinks_gui()
-
-    def active_ports(self):
-        return itertools.chain(self.active_sources, self.active_sinks)
-
-    def get_children(self):
-        return self.get_ports() + list(self.params.values())
-
-    def get_children_gui(self):
-        return self.get_ports_gui() + self.params.values()
-
-    ##############################################
-    # Access
-    ##############################################
-
-    def get_param(self, key):
-        return self.params[key]
-
-    def get_sink(self, key):
-        return _get_elem(self.sinks, key)
-
-    def get_sinks_gui(self):
-        return self.filter_bus_port(self.sinks)
-
-    def get_source(self, key):
-        return _get_elem(self.sources, key)
-
-    def get_sources_gui(self):
-        return self.filter_bus_port(self.sources)
-
-    def get_connections(self):
-        return sum((port.get_connections() for port in self.get_ports()), [])
-
-    ##############################################
-    # Resolve
-    ##############################################
-    def resolve_dependencies(self, tmpl):
-        """
-        Resolve a paramater dependency with cheetah templates.
-
-        Args:
-            tmpl: the string with dependencies
-
-        Returns:
-            the resolved value
-        """
-        tmpl = str(tmpl)
-        if '$' not in tmpl:
-            return tmpl
-        # TODO: cache that
-        n = {key: param.template_arg for key, param in six.iteritems(self.params)}
-        try:
-            return str(Template(tmpl, n))
-        except Exception as err:
-            return "Template error: {}\n    {}".format(tmpl, err)
-
-    ##############################################
-    # Import/Export Methods
-    ##############################################
-    def export_data(self):
-        """
-        Export this block's params to nested data.
-
-        Returns:
-            a nested data odict
-        """
-        n = collections.OrderedDict()
-        n['key'] = self.key
-
-        params = (param.export_data() for param in six.itervalues(self.params))
-        states = (collections.OrderedDict([('key', key), ('value', repr(value))])
-                  for key, value in six.iteritems(self.states))
-        n['param'] = sorted(itertools.chain(states, params), key=lambda p: p['key'])
-
-        if any('bus' in a.get_type() for a in self.sinks):
-            n['bus_sink'] = '1'
-        if any('bus' in a.get_type() for a in self.sources):
-            n['bus_source'] = '1'
-        return n
-
-    def import_data(self, n):
-        """
-        Import this block's params from nested data.
-        Any param keys that do not exist will be ignored.
-        Since params can be dynamically created based another param,
-        call rewrite, and repeat the load until the params stick.
-        This call to rewrite will also create any dynamic ports
-        that are needed for the connections creation phase.
-
-        Args:
-            n: the nested data odict
-        """
-        param_data = {p['key']: p['value'] for p in n.get('param', [])}
-
-        for key in self.states:
-            try:
-                self.states[key] = ast.literal_eval(param_data.pop(key))
-            except (KeyError, SyntaxError, ValueError):
-                pass
-
-        def get_hash():
-            return hash(tuple(hash(v) for v in self.params.values()))
-
-        pre_rewrite_hash = -1
-        while pre_rewrite_hash != get_hash():
-            for key, value in six.iteritems(param_data):
-                try:
-                    self.params[key].set_value(value)
-                except KeyError:
-                    continue
-            # Store hash and call rewrite
-            pre_rewrite_hash = get_hash()
-            self.rewrite()
-
-        self._import_bus_stuff(n)
-
-    ##############################################
-    # Bus ports stuff
-    ##############################################
-
-    def get_bus_structure(self, direction):
-        bus_structure = self.resolve_dependencies(self._bus_structure[direction])
-        if not bus_structure:
-            return
-        try:
-            return self.parent_flowgraph.evaluate(bus_structure)
-        except:
-            return
-
-    @staticmethod
-    def back_ofthe_bus(portlist):
-        portlist.sort(key=lambda p: p._type == 'bus')
-
-    @staticmethod
-    def filter_bus_port(ports):
-        buslist = [p for p in ports if p._type == 'bus']
-        return buslist or ports
-
-    def _import_bus_stuff(self, n):
-        bus_sinks = n.get('bus_sink', [])
-        if len(bus_sinks) > 0 and not self._bussify_sink:
-            self.bussify('sink')
-        elif len(bus_sinks) > 0:
-            self.bussify('sink')
-            self.bussify('sink')
-        bus_sources = n.get('bus_source', [])
-        if len(bus_sources) > 0 and not self._bussify_source:
-            self.bussify('source')
-        elif len(bus_sources) > 0:
-            self.bussify('source')
-            self.bussify('source')
-
-    def form_bus_structure(self, direc):
-        ports = self.sources if direc == 'source' else self.sinks
-        struct = self.get_bus_structure(direc)
-
-        if not struct:
-            struct = [list(range(len(ports)))]
-
-        elif any(isinstance(p.get_nports(), int) for p in ports):
-            last = 0
-            structlet = []
-            for port in ports:
-                nports = port.get_nports()
-                if not isinstance(nports, int):
-                    continue
-                structlet.extend(a + last for a in range(nports))
-                last += nports
-            struct = [structlet]
-
-        self.current_bus_structure[direc] = struct
-        return struct
-
-    def bussify(self, direc):
-        ports = self.sources if direc == 'source' else self.sinks
-
-        for elt in ports:
-            for connect in elt.get_connections():
-                self.parent.remove_element(connect)
-
-        if ports and all('bus' != p.get_type() for p in ports):
-            struct = self.current_bus_structure[direc] = self.form_bus_structure(direc)
-            n = {'type': 'bus'}
-            if ports[0].get_nports():
-                n['nports'] = '1'
-
-            for i, structlet in enumerate(struct):
-                name = 'bus{}#{}'.format(i, len(structlet))
-                port = self.parent_platform.get_new_port(
-                    self, direction=direc, key=str(len(ports)), name=name, **n)
-                ports.append(port)
-        elif any('bus' == p.get_type() for p in ports):
-            get_p_gui = self.get_sources_gui if direc == 'source' else self.get_sinks_gui
-            for elt in get_p_gui():
-                ports.remove(elt)
-            self.current_bus_structure[direc] = ''
-
-    def _init_bus_ports(self, n):
-        self.current_bus_structure = {'source': '', 'sink': ''}
-        self._bus_structure = {'source': n.get('bus_structure_source', ''),
-                               'sink': n.get('bus_structure_sink', '')}
-        self._bussify_sink = n.get('bus_sink')
-        self._bussify_source = n.get('bus_source')
-        if self._bussify_sink:
-            self.bussify('sink')
-        if self._bussify_source:
-            self.bussify('source')
-
-    def _rewrite_bus_ports(self):
-        return  # fixme: probably broken
-
-        def doit(ports, ports_gui, direc):
-            if not self.current_bus_structure[direc]:
-                return
-
-            bus_structure = self.form_bus_structure(direc)
-            for port in ports_gui[len(bus_structure):]:
-                for connect in port.get_connections():
-                    self.parent_flowgraph.remove_element(connect)
-                ports.remove(port)
-
-            port_factory = self.parent_platform.get_new_port
-
-            if len(ports_gui) < len(bus_structure):
-                for i in range(len(ports_gui), len(bus_structure)):
-                    port = port_factory(self, direction=direc, key=str(1 + i),
-                                        name='bus', type='bus')
-                    ports.append(port)
-
-        doit(self.sources, self.get_sources_gui(), 'source')
-        doit(self.sinks, self.get_sinks_gui(), 'sink')
-
-        if 'bus' in [a.get_type() for a in self.get_sources_gui()]:
-            for i in range(len(self.get_sources_gui())):
-                if not self.get_sources_gui()[i].get_connections():
-                    continue
-                source = self.get_sources_gui()[i]
-                sink = []
-
-                for j in range(len(source.get_connections())):
-                    sink.append(source.get_connections()[j].sink_port)
-                for elt in source.get_connections():
-                    self.parent_flowgraph.remove_element(elt)
-                for j in sink:
-                    self.parent_flowgraph.connect(source, j)
-
-
-class EPyBlock(Block):
-
-    def __init__(self, flow_graph, **n):
-        super(EPyBlock, self).__init__(flow_graph, **n)
-        self._epy_source_hash = -1  # for epy blocks
-        self._epy_reload_error = None
-
-    def rewrite(self):
-        Element.rewrite(self)
-
-        param_blk = self.params['_io_cache']
-        param_src = self.params['_source_code']
-
-        src = param_src.get_value()
-        src_hash = hash((self.get_id(), src))
-        if src_hash == self._epy_source_hash:
-            return
-
-        try:
-            blk_io = utils.epy_block_io.extract(src)
-
-        except Exception as e:
-            self._epy_reload_error = ValueError(str(e))
-            try:  # Load last working block io
-                blk_io_args = eval(param_blk.get_value())
-                if len(blk_io_args) == 6:
-                    blk_io_args += ([],)  # add empty callbacks
-                blk_io = utils.epy_block_io.BlockIO(*blk_io_args)
-            except Exception:
-                return
-        else:
-            self._epy_reload_error = None  # Clear previous errors
-            param_blk.set_value(repr(tuple(blk_io)))
-
-        # print "Rewriting embedded python block {!r}".format(self.get_id())
-
-        self._epy_source_hash = src_hash
-        self.name = blk_io.name or blk_io.cls
-        self._doc = blk_io.doc
-        self._imports[0] = 'import ' + self.get_id()
-        self._make = '{0}.{1}({2})'.format(self.get_id(), blk_io.cls, ', '.join(
-            '{0}=${{ {0} }}'.format(key) for key, _ in blk_io.params))
-        self._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')
-        self._update_ports('out', self.sources, blk_io.sources, 'source')
-
-        super(EPyBlock, self).rewrite()
-
-    def _update_params(self, params_in_src):
-        param_factory = self.parent_platform.get_new_param
-        params = {}
-        for param in list(self.params):
-            if hasattr(param, '__epy_param__'):
-                params[param.key] = param
-                del self.params[param.key]
-
-        for key, value in params_in_src:
-            try:
-                param = params[key]
-                if param.default == param.value:
-                    param.set_value(value)
-                param.default = str(value)
-            except KeyError:  # need to make a new param
-                param = param_factory(
-                    parent=self,  key=key, type='raw', value=value,
-                    name=key.replace('_', ' ').title(),
-                )
-                setattr(param, '__epy_param__', True)
-            self.params[key] = param
-
-    def _update_ports(self, label, ports, port_specs, direction):
-        port_factory = self.parent_platform.get_new_port
-        ports_to_remove = list(ports)
-        iter_ports = iter(ports)
-        ports_new = []
-        port_current = next(iter_ports, None)
-        for key, port_type, vlen in port_specs:
-            reuse_port = (
-                port_current is not None and
-                port_current.get_type() == port_type and
-                port_current.get_vlen() == vlen and
-                (key.isdigit() or port_current.key == key)
-            )
-            if reuse_port:
-                ports_to_remove.remove(port_current)
-                port, port_current = port_current, next(iter_ports, None)
-            else:
-                n = dict(name=label + str(key), type=port_type, key=key)
-                if port_type == 'message':
-                    n['name'] = key
-                    n['optional'] = '1'
-                if vlen > 1:
-                    n['vlen'] = str(vlen)
-                port = port_factory(self, direction=direction, **n)
-            ports_new.append(port)
-        # replace old port list with new one
-        del ports[:]
-        ports.extend(ports_new)
-        # remove excess port connections
-        for port in ports_to_remove:
-            for connection in port.get_connections():
-                self.parent_flowgraph.remove_element(connection)
-
-    def validate(self):
-        super(EPyBlock, self).validate()
-        if self._epy_reload_error:
-            self.params['_source_code'].add_error_message(str(self._epy_reload_error))
-
-
-class DummyBlock(Block):
-
-    is_dummy_block = True
-    build_in_param_keys = 'id alias affinity minoutbuf maxoutbuf comment'
-
-    def __init__(self, parent, key, missing_key, params_n):
-        super(DummyBlock, self).__init__(parent=parent, key=missing_key, name='Missing Block')
-        param_factory = self.parent_platform.get_new_param
-        for param_n in params_n:
-            key = param_n['key']
-            self.params.setdefault(key, param_factory(self, key=key, name=key, type='string'))
-
-    def is_valid(self):
-        return False
-
-    @property
-    def enabled(self):
-        return False
-
-    def add_missing_port(self, key, dir):
-        port = self.parent_platform.get_new_port(
-            parent=self, direction=dir, key=key, name='?', type='',
-        )
-        if port.is_source:
-            self.sources.append(port)
-        else:
-            self.sinks.append(port)
-        return port
-- 
cgit v1.2.3