commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 12/101: grc-refactor: remove odict


From: git
Subject: [Commit-gnuradio] [gnuradio] 12/101: grc-refactor: remove odict
Date: Thu, 16 Mar 2017 14:57:58 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

jcorgan pushed a commit to branch python3
in repository gnuradio.

commit 963773b800655f2902998aedce8d46605d54e60f
Author: Sebastian Koslowski <address@hidden>
Date:   Fri Jun 3 16:17:57 2016 +0200

    grc-refactor: remove odict
---
 grc/core/Block.py               |  69 ++++++++++++------------
 grc/core/Connection.py          |   5 +-
 grc/core/FlowGraph.py           |  52 +++++++++---------
 grc/core/Param.py               |  26 ++++-----
 grc/core/ParseXML.py            |  50 ++++++++++++------
 grc/core/Platform.py            |  55 ++++++++++---------
 grc/core/Port.py                |  17 +++---
 grc/core/generator/Generator.py |  26 +++++----
 grc/core/utils/__init__.py      |   1 -
 grc/core/utils/odict.py         | 113 ----------------------------------------
 grc/gui/FlowGraph.py            |  12 ++---
 11 files changed, 172 insertions(+), 254 deletions(-)

diff --git a/grc/core/Block.py b/grc/core/Block.py
index 062598e..b607f90 100644
--- a/grc/core/Block.py
+++ b/grc/core/Block.py
@@ -26,7 +26,7 @@ from six.moves import map, range
 
 from Cheetah.Template import Template
 
-from .utils import epy_block_io, odict
+from .utils import epy_block_io
 from . Constants import (
     BLOCK_FLAG_NEED_QT_GUI, BLOCK_FLAG_NEED_WX_GUI,
     ADVANCED_PARAM_TAB, DEFAULT_PARAM_TAB,
@@ -64,33 +64,34 @@ class Block(Element):
             block a new block
         """
         Element.__init__(self, flow_graph)
-        self._name = n.find('name')
-        self._key = n.find('key')
-        self._category = n.find('category') or ''
-        self._flags = n.find('flags') or ''
+
+        self._name = n['name']
+        self._key = n['key']
+        self._category = n.get('category', '')
+        self._flags = n.get('flags', '')
 
         # Backwards compatibility
-        if n.find('throttle') and BLOCK_FLAG_THROTTLE not in self._flags:
+        if n.get('throttle') and BLOCK_FLAG_THROTTLE not in self._flags:
             self._flags += BLOCK_FLAG_THROTTLE
 
-        self._doc = (n.find('doc') or '').strip('\n').replace('\\\n', '')
-        self._imports = [i.strip() for i in n.findall('import')]
-        self._make = n.find('make')
-        self._var_make = n.find('var_make')
-        self._var_value = n.find('var_value') or '$value'
-        self._checks = n.findall('check')
-        self._callbacks = n.findall('callback')
+        self._doc = n.get('doc', '').strip('\n').replace('\\\n', '')
+        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.find('grc_source') or ''
-        self._block_wrapper_path = n.find('block_wrapper_path')
+        self._grc_source = n.get('grc_source', '')
+        self._block_wrapper_path = n.get('block_wrapper_path')
 
-        params_n = n.findall('param')
-        sources_n = n.findall('source')
-        sinks_n = n.findall('sink')
+        params_n = n.get('param', [])
+        sources_n = n.get('source', [])
+        sinks_n = n.get('sink', [])
 
         # Get list of param tabs
-        n_tabs = n.find('param_tab_order') or None
-        self._param_tab_labels = n_tabs.findall('tab') if n_tabs is not None 
else [DEFAULT_PARAM_TAB]
+        n_tabs = n.get('param_tab_order', {})
+        self._param_tab_labels = n.get('param_tab_order', {}).get('tab') or 
[DEFAULT_PARAM_TAB]
         self._params = []
         self._init_params(
             params_n=params_n,
@@ -108,17 +109,17 @@ class Block(Element):
         self.back_ofthe_bus(self._sources)
         self.back_ofthe_bus(self._sinks)
         self.current_bus_structure = {'source': '', 'sink': ''}
-        self._bus_structure_source = n.find('bus_structure_source') or ''
-        self._bus_structure_sink = n.find('bus_structure_sink') or ''
-        self._bussify_sink = n.find('bus_sink')
-        self._bussify_source = n.find('bus_source')
+        self._bus_structure_source = n.get('bus_structure_source', '')
+        self._bus_structure_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({'name': 'bus', 'type': 'bus'}, 'sink')
         if self._bussify_source:
             self.bussify({'name': 'bus', 'type': 'bus'}, 'source')
 
     def _add_param(self, key, name, value='', type='raw', **kwargs):
-        n = odict({'key': key, 'name': name, 'value': value, 'type': type})
+        n = {'key': key, 'name': name, 'value': value, 'type': type}
         n.update(kwargs)
         param = self.get_parent().get_parent().Param(block=self, n=n)
         self._params.append(param)
@@ -366,7 +367,7 @@ class Block(Element):
                 param.set_default(value)
             except KeyError:  # need to make a new param
                 name = key.replace('_', ' ').title()
-                n = odict(dict(name=name, key=key, type='raw', value=value))
+                n = dict(name=name, key=key, type='raw', value=value)
                 param = platform.Param(block=self, n=n)
                 setattr(param, '__epy_param__', True)
             self._params.append(param)
@@ -386,7 +387,7 @@ class Block(Element):
                     ports_to_remove.remove(port_current)
                     port, port_current = port_current, next(iter_ports, None)
                 else:
-                    n = odict(dict(name=label + str(key), type=port_type, 
key=key))
+                    n = dict(name=label + str(key), type=port_type, key=key)
                     if port_type == 'message':
                         n['name'] = key
                         n['optional'] = '1'
@@ -684,7 +685,7 @@ class Block(Element):
         Returns:
             a nested data odict
         """
-        n = odict()
+        n = collections.OrderedDict()
         n['key'] = self.get_key()
         n['param'] = [p.export_data() for p in sorted(self.get_params(), 
key=str)]
         if 'bus' in [a.get_type() for a in self.get_sinks()]:
@@ -705,7 +706,7 @@ class Block(Element):
         Args:
             n: the nested data odict
         """
-        params_n = n.findall('param')
+        params_n = n.get('param', [])
         params = dict((param.get_key(), param) for param in self._params)
 
         def get_hash():
@@ -714,8 +715,8 @@ class Block(Element):
         my_hash = 0
         while get_hash() != my_hash:
             for param_n in params_n:
-                key = param_n.find('key')
-                value = param_n.find('value')
+                key = param_n['key']
+                value = param_n['value']
                 try:
                     params[key].set_value(value)
                 except KeyError:
@@ -755,13 +756,13 @@ class Block(Element):
         return buslist or ports
 
     def _import_bus_stuff(self, n):
-        bussinks = n.findall('bus_sink')
+        bussinks = n.get('bus_sink', [])
         if len(bussinks) > 0 and not self._bussify_sink:
             self.bussify({'name': 'bus', 'type': 'bus'}, 'sink')
         elif len(bussinks) > 0:
             self.bussify({'name': 'bus', 'type': 'bus'}, 'sink')
             self.bussify({'name': 'bus', 'type': 'bus'}, 'sink')
-        bussrcs = n.findall('bus_source')
+        bussrcs = n.get('bus_source', [])
         if len(bussrcs) > 0 and not self._bussify_source:
             self.bussify({'name': 'bus', 'type': 'bus'}, 'source')
         elif len(bussrcs) > 0:
@@ -815,7 +816,7 @@ class Block(Element):
 
             for i in range(len(struct)):
                 n['key'] = str(len(get_p()))
-                n = odict(n)
+                n = dict(n)
                 port = self.get_parent().get_parent().Port(block=self, n=n, 
dir=direc)
                 get_p().append(port)
         elif 'bus' in [a.get_type() for a in get_p()]:
diff --git a/grc/core/Connection.py b/grc/core/Connection.py
index ddc6c02..9ae99de 100644
--- a/grc/core/Connection.py
+++ b/grc/core/Connection.py
@@ -19,11 +19,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
MA  02110-1301, USA
 
 from __future__ import absolute_import
 
+import collections
+
 from six.moves import range
 
 from . import Constants
 from .Element import Element
-from .utils import odict
 
 
 class Connection(Element):
@@ -157,7 +158,7 @@ class Connection(Element):
         Returns:
             a nested data odict
         """
-        n = odict()
+        n = collections.OrderedDict()
         n['source_block_id'] = self.get_source().get_parent().get_id()
         n['sink_block_id'] = self.get_sink().get_parent().get_id()
         n['source_key'] = self.get_source().get_key()
diff --git a/grc/core/FlowGraph.py b/grc/core/FlowGraph.py
index 9edd4f2..b0f52db 100644
--- a/grc/core/FlowGraph.py
+++ b/grc/core/FlowGraph.py
@@ -22,13 +22,14 @@ import time
 import re
 from itertools import chain
 from operator import methodcaller, attrgetter
+import collections
 
 from six.moves import filter
 
 from . import Messages
 from .Constants import FLOW_GRAPH_FILE_FORMAT_VERSION
 from .Element import Element
-from .utils import odict, expr_utils
+from .utils import expr_utils
 
 _parameter_matcher = re.compile('^(parameter)$')
 _monitors_searcher = re.compile('(ctrlport_monitor)')
@@ -364,20 +365,19 @@ class FlowGraph(Element):
             str(b)
         ))
         connections = sorted(self.connections, key=str)
-        n = odict()
+        n = collections.OrderedDict()
         n['timestamp'] = self._timestamp
         n['block'] = [b.export_data() for b in blocks]
         n['connection'] = [c.export_data() for c in connections]
-        instructions = odict({
-            'created': '.'.join(self.get_parent().config.version_parts),
-            'format': FLOW_GRAPH_FILE_FORMAT_VERSION,
-        })
-        return odict({'flow_graph': n, '_instructions': instructions})
+        instructions = collections.OrderedDict()
+        instructions['created'] = 
'.'.join(self.get_parent().config.version_parts)
+        instructions['format'] = FLOW_GRAPH_FILE_FORMAT_VERSION
+        return {'flow_graph': n, '_instructions': instructions}
 
     def import_data(self, n):
         """
         Import blocks and connections into this flow graph.
-        Clear this flowgraph of all previous blocks and connections.
+        Clear this flow graph of all previous blocks and connections.
         Any blocks or connections in error will be ignored.
 
         Args:
@@ -388,18 +388,18 @@ class FlowGraph(Element):
         del self.connections[:]
         # set file format
         try:
-            instructions = n.find('_instructions') or {}
+            instructions = n.get('_instructions', {})
             file_format = int(instructions.get('format', '0')) or 
_guess_file_format_1(n)
         except:
             file_format = 0
 
-        fg_n = n and n.find('flow_graph') or odict()  # use blank data if none 
provided
-        self._timestamp = fg_n.find('timestamp') or time.ctime()
+        fg_n = n and n.get('flow_graph', {})  # use blank data if none provided
+        self._timestamp = fg_n.get('timestamp', time.ctime())
 
         # build the blocks
         self._options_block = self.new_block('options')
-        for block_n in fg_n.findall('block'):
-            key = block_n.find('key')
+        for block_n in fg_n.get('block', []):
+            key = block_n['key']
             block = self._options_block if key == 'options' else 
self.new_block(key)
 
             if not block:
@@ -442,12 +442,12 @@ class FlowGraph(Element):
             return port
 
         errors = False
-        for connection_n in fg_n.findall('connection'):
+        for connection_n in fg_n.get('connection', []):
             # get the block ids and port keys
-            source_block_id = connection_n.find('source_block_id')
-            sink_block_id = connection_n.find('sink_block_id')
-            source_key = connection_n.find('source_key')
-            sink_key = connection_n.find('sink_key')
+            source_block_id = connection_n.get('source_block_id')
+            sink_block_id = connection_n.get('sink_block_id')
+            source_key = connection_n.get('source_key')
+            sink_key = connection_n.get('sink_key')
             try:
                 source_block = self.get_block(source_block_id)
                 sink_block = self.get_block(sink_block_id)
@@ -502,7 +502,7 @@ class FlowGraph(Element):
 
                         for i in times:
                             n['key'] = str(len(get_p()))
-                            n = odict(n)
+                            n = dict(n)
                             port = block.get_parent().get_parent().Port(
                                 block=block, n=n, dir=direc)
                             get_p().append(port)
@@ -553,9 +553,9 @@ def _guess_file_format_1(n):
     """
     try:
         has_non_numeric_message_keys = any(not (
-            connection_n.find('source_key').isdigit() and
-            connection_n.find('sink_key').isdigit()
-        ) for connection_n in n.find('flow_graph').findall('connection'))
+            connection_n.get('source_key', '').isdigit() and
+            connection_n.get('sink_key', '').isdigit()
+        ) for connection_n in n.get('flow_graph', []).get('connection', []))
         if has_non_numeric_message_keys:
             return 1
     except:
@@ -569,20 +569,20 @@ def _initialize_dummy_block(block, block_n):
     Modify block object to get the behaviour for a missing block
     """
 
-    block._key = block_n.find('key')
+    block._key = block_n.get('key')
     block.is_dummy_block = lambda: True
     block.is_valid = lambda: False
     block.get_enabled = lambda: False
-    for param_n in block_n.findall('param'):
+    for param_n in block_n.get('param', []):
         if param_n['key'] not in block.get_param_keys():
-            new_param_n = odict({'key': param_n['key'], 'name': 
param_n['key'], 'type': 'string'})
+            new_param_n = {'key': param_n['key'], 'name': param_n['key'], 
'type': 'string'}
             params = block.get_parent().get_parent().Param(block=block, 
n=new_param_n)
             block.get_params().append(params)
 
 
 def _dummy_block_add_port(block, key, dir):
     """ This is so ugly... Add a port to a dummy-field block """
-    port_n = odict({'name': '?', 'key': key, 'type': ''})
+    port_n = {'name': '?', 'key': key, 'type': ''}
     port = block.get_parent().get_parent().Port(block=block, n=port_n, dir=dir)
     if port.is_source:
         block.get_sources().append(port)
diff --git a/grc/core/Param.py b/grc/core/Param.py
index 45f0187..a9d495d 100644
--- a/grc/core/Param.py
+++ b/grc/core/Param.py
@@ -22,12 +22,12 @@ from __future__ import absolute_import
 import ast
 import weakref
 import re
+import collections
 
 from six.moves import builtins, filter, map, range, zip
 
 from . import Constants
 from .Element import Element
-from .utils import odict
 
 # Blacklist certain ids, its not complete, but should help
 ID_BLACKLIST = ['self', 'options', 'gr', 'blks2', 'wxgui', 'wx', 'math', 
'forms', 'firdes'] + dir(builtins)
@@ -79,10 +79,10 @@ class Option(Element):
 
     def __init__(self, param, n):
         Element.__init__(self, param)
-        self._name = n.find('name')
-        self._key = n.find('key')
+        self._name = n.get('name')
+        self._key = n.get('key')
         self._opts = dict()
-        opts = n.findall('opt')
+        opts = n.get('opt', [])
         # Test against opts when non enum
         if not self.get_parent().is_enum() and opts:
             raise Exception('Options for non-enum types cannot have 
sub-options')
@@ -155,7 +155,7 @@ class Param(Element):
             n: the nested odict
         """
         # If the base key is a valid param key, copy its data and overlay this 
params data
-        base_key = n.find('base_key')
+        base_key = n.get('base_key')
         if base_key and base_key in block.get_param_keys():
             n_expanded = block.get_param(base_key)._n.copy()
             n_expanded.update(n)
@@ -163,12 +163,12 @@ class Param(Element):
         # Save odict in case this param will be base for another
         self._n = n
         # Parse the data
-        self._name = n.find('name')
-        self._key = n.find('key')
-        value = n.find('value') or ''
-        self._type = n.find('type') or 'raw'
-        self._hide = n.find('hide') or ''
-        self._tab_label = n.find('tab') or block.get_param_tab_labels()[0]
+        self._name = n['name']
+        self._key = n['key']
+        value = n.get('value', '')
+        self._type = n.get('type', 'raw')
+        self._hide = n.get('hide', '')
+        self._tab_label = n.get('tab', block.get_param_tab_labels()[0])
         if self._tab_label not in block.get_param_tab_labels():
             block.get_param_tab_labels().append(self._tab_label)
         # Build the param
@@ -176,7 +176,7 @@ class Param(Element):
         # Create the Option objects from the n data
         self._options = list()
         self._evaluated = None
-        for o_n in n.findall('option'):
+        for o_n in n.get('option', []):
             option = Option(param=self, n=o_n)
             key = option.get_key()
             # Test against repeated keys
@@ -703,7 +703,7 @@ class Param(Element):
         Returns:
             a nested data odict
         """
-        n = odict()
+        n = collections.OrderedDict()
         n['key'] = self.get_key()
         n['value'] = self.get_value()
         return n
diff --git a/grc/core/ParseXML.py b/grc/core/ParseXML.py
index d1306fc..163289b 100644
--- a/grc/core/ParseXML.py
+++ b/grc/core/ParseXML.py
@@ -24,7 +24,6 @@ from lxml import etree
 import six
 from six.moves import map
 
-from .utils import odict
 
 xml_failures = {}
 etree.set_default_parser(etree.XMLParser(remove_comments=True))
@@ -80,19 +79,35 @@ def from_file(xml_file):
         the nested data with grc version information
     """
     xml = etree.parse(xml_file)
-    nested_data = _from_file(xml.getroot())
+
+    tag, nested_data = _from_file(xml.getroot())
+    nested_data = {tag: nested_data, '_instructions': {}}
 
     # Get the embedded instructions and build a dictionary item
-    nested_data['_instructions'] = {}
     xml_instructions = xml.xpath('/processing-instruction()')
     for inst in xml_instructions:
         if inst.target != 'grc':
             continue
-        nested_data['_instructions'] = odict(inst.attrib)
+        nested_data['_instructions'] = dict(inst.attrib)
     return nested_data
 
 
-def _from_file(xml):
+WANT_A_LIST = {
+    '/block': 'import callback param check sink source'.split(),
+    '/block/param_tab_order': 'tab'.split(),
+    '/block/param': 'option'.split(),
+    '/block/param/option': 'opt'.split(),
+    '/flow_graph': 'block connection'.split(),
+    '/flow_graph/block': 'param'.split(),
+    '/cat': 'cat block'.split(),
+    '/cat/cat': 'cat block'.split(),
+    '/cat/cat/cat': 'cat block'.split(),
+    '/cat/cat/cat/cat': 'cat block'.split(),
+    '/domain': 'connection'.split(),
+}
+
+
+def _from_file(xml, parent_tag=''):
     """
     Recursively parse the xml tree into nested data format.
 
@@ -103,21 +118,24 @@ def _from_file(xml):
         the nested data
     """
     tag = xml.tag
+    tag_path = parent_tag + '/' + tag
+
     if not len(xml):
-        return odict({tag: xml.text or ''})  # store empty tags (text is None) 
as empty string
-    nested_data = odict()
+        return tag, xml.text or ''  # store empty tags (text is None) as empty 
string
+
+    nested_data = {}
     for elem in xml:
-        key, value = list(_from_file(elem).items())[0]
-        if key in nested_data:
-            nested_data[key].append(value)
+        key, value = _from_file(elem, tag_path)
+
+        if key in WANT_A_LIST.get(tag_path, []):
+            try:
+                nested_data[key].append(value)
+            except KeyError:
+                nested_data[key] = [value]
         else:
-            nested_data[key] = [value]
-    # Delistify if the length of values is 1
-    for key, values in six.iteritems(nested_data):
-        if len(values) == 1:
-            nested_data[key] = values[0]
+            nested_data[key] = value
 
-    return odict({tag: nested_data})
+    return tag, nested_data
 
 
 def to_file(nested_data, xml_file):
diff --git a/grc/core/Platform.py b/grc/core/Platform.py
index 25f4156..403c6c8 100644
--- a/grc/core/Platform.py
+++ b/grc/core/Platform.py
@@ -17,11 +17,14 @@ 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
-from __future__ import print_function
+from __future__ import absolute_import, print_function
+
 import os
 import sys
 
+import six
+from six.moves import range
+
 from . import ParseXML, Messages, Constants
 
 from .Config import Config
@@ -33,10 +36,7 @@ from .Block import Block
 from .Port import Port
 from .Param import Param
 
-from .utils import odict, extract_docs
-import six
-from six.moves import map
-from six.moves import range
+from .utils import extract_docs
 
 
 class Platform(Element):
@@ -72,9 +72,9 @@ class Platform(Element):
         self._flow_graph = Element(self)
         self._flow_graph.connections = []
 
-        self.blocks = None
-        self._blocks_n = None
-        self._category_trees_n = None
+        self.blocks = {}
+        self._blocks_n = {}
+        self._category_trees_n = []
         self.domains = {}
         self.connection_templates = {}
 
@@ -141,13 +141,15 @@ class Platform(Element):
     def load_blocks(self):
         """load the blocks and block tree from the search paths"""
         self._docstring_extractor.start()
+
         # Reset
-        self.blocks = odict()
-        self._blocks_n = odict()
-        self._category_trees_n = list()
+        self.blocks.clear()
+        self._blocks_n.clear()
+        del self._category_trees_n[:]
         self.domains.clear()
         self.connection_templates.clear()
         ParseXML.xml_failures.clear()
+
         # Try to parse and load blocks
         for xml_file in self.iter_xml_files():
             try:
@@ -161,6 +163,7 @@ class Platform(Element):
                 # print >> sys.stderr, 'Warning: Block validation 
failed:\n\t%s\n\tIgnoring: %s' % (e, xml_file)
                 pass
             except Exception as e:
+                raise
                 print('Warning: XML parsing failed:\n\t%r\n\tIgnoring: %s' % 
(e, xml_file), file=sys.stderr)
 
         self._docstring_extractor.finish()
@@ -180,7 +183,7 @@ class Platform(Element):
         """Load block description from xml file"""
         # Validate and import
         ParseXML.validate_dtd(xml_file, self._block_dtd)
-        n = ParseXML.from_file(xml_file).find('block')
+        n = ParseXML.from_file(xml_file).get('block', {})
         n['block_wrapper_path'] = xml_file  # inject block wrapper path
         # Get block instance and add it to the list of blocks
         block = self.Block(self._flow_graph, n)
@@ -200,15 +203,15 @@ class Platform(Element):
     def load_category_tree_xml(self, xml_file):
         """Validate and parse category tree file and add it to list"""
         ParseXML.validate_dtd(xml_file, Constants.BLOCK_TREE_DTD)
-        n = ParseXML.from_file(xml_file).find('cat')
+        n = ParseXML.from_file(xml_file).get('cat', {})
         self._category_trees_n.append(n)
 
     def load_domain_xml(self, xml_file):
         """Load a domain properties and connection templates from XML"""
         ParseXML.validate_dtd(xml_file, Constants.DOMAIN_DTD)
-        n = ParseXML.from_file(xml_file).find('domain')
+        n = ParseXML.from_file(xml_file).get('domain')
 
-        key = n.find('key')
+        key = n.get('key')
         if not key:
             print('Warning: Domain with emtpy key.\n\tIgnoring: 
{}'.format(xml_file), file=sys.stderr)
             return
@@ -222,7 +225,7 @@ class Platform(Element):
                 return s.lower() not in ('false', 'off', '0', '')
             return d
 
-        color = n.find('color') or ''
+        color = n.get('color') or ''
         try:
             chars_per_color = 2 if len(color) > 4 else 1
             tuple(int(color[o:o + 2], 16) / 255.0 for o in range(1, 3 * 
chars_per_color, chars_per_color))
@@ -232,19 +235,19 @@ class Platform(Element):
                 color = None
 
         self.domains[key] = dict(
-            name=n.find('name') or key,
-            multiple_sinks=to_bool(n.find('multiple_sinks'), True),
-            multiple_sources=to_bool(n.find('multiple_sources'), False),
+            name=n.get('name') or key,
+            multiple_sinks=to_bool(n.get('multiple_sinks'), True),
+            multiple_sources=to_bool(n.get('multiple_sources'), False),
             color=color
         )
-        for connection_n in n.findall('connection'):
-            key = (connection_n.find('source_domain'), 
connection_n.find('sink_domain'))
+        for connection_n in n.get('connection', []):
+            key = (connection_n.get('source_domain'), 
connection_n.get('sink_domain'))
             if not all(key):
                 print('Warning: Empty domain key(s) in connection 
template.\n\t{}'.format(xml_file), file=sys.stderr)
             elif key in self.connection_templates:
                 print('Warning: Connection template "{}" already 
exists.\n\t{}'.format(key, xml_file), file=sys.stderr)
             else:
-                self.connection_templates[key] = connection_n.find('make') or 
''
+                self.connection_templates[key] = connection_n.get('make') or ''
 
     def load_block_tree(self, block_tree):
         """
@@ -258,13 +261,13 @@ class Platform(Element):
         # Recursive function to load categories and blocks
         def load_category(cat_n, parent=None):
             # Add this category
-            parent = (parent or []) + [cat_n.find('name')]
+            parent = (parent or []) + [cat_n.get('name')]
             block_tree.add_block(parent)
             # Recursive call to load sub categories
-            for cat in cat_n.findall('cat'):
+            for cat in cat_n.get('cat', []):
                 load_category(cat, parent)
             # Add blocks in this category
-            for block_key in cat_n.findall('block'):
+            for block_key in cat_n.get('block', []):
                 if block_key not in self.blocks:
                     print('Warning: Block key "{}" not found when loading 
category tree.'.format(block_key), file=sys.stderr)
                     continue
diff --git a/grc/core/Port.py b/grc/core/Port.py
index a24262d..34edb8d 100644
--- a/grc/core/Port.py
+++ b/grc/core/Port.py
@@ -124,23 +124,24 @@ class Port(Element):
             n['type'] = 'message'  # For port color
         if n['type'] == 'msg':
             n['key'] = 'msg'
-        if not n.find('key'):
-            n['key'] = str(next(block.port_counters[dir == 'source']))
+
+        n.setdefault('key', str(next(block.port_counters[dir == 'source'])))
 
         # Build the port
         Element.__init__(self, block)
         # Grab the data
         self._name = n['name']
         self._key = n['key']
-        self._type = n['type'] or ''
-        self._domain = n['domain']
-        self._hide = n.find('hide') or ''
+        self._type = n.get('type', '')
+        self._domain = n.get('domain')
+        self._hide = n.get('hide', '')
         self._dir = dir
         self._hide_evaluated = False  # Updated on rewrite()
 
-        self._nports = n.find('nports') or ''
-        self._vlen = n.find('vlen') or ''
-        self._optional = bool(n.find('optional'))
+        self._nports = n.get('nports', '')
+        self._vlen = n.get('vlen', '')
+        self._optional = bool(n.get('optional'))
+        self.di_optional = bool(n.get('optional'))
         self._clones = []  # References to cloned ports (for nports > 1)
 
     def __str__(self):
diff --git a/grc/core/generator/Generator.py b/grc/core/generator/Generator.py
index c9b0653..c27e926 100644
--- a/grc/core/generator/Generator.py
+++ b/grc/core/generator/Generator.py
@@ -17,12 +17,15 @@
 
 
 from __future__ import absolute_import
+
 import codecs
 import os
 import tempfile
 import operator
+import collections
 
 from Cheetah.Template import Template
+import six
 
 from .FlowGraphProxy import FlowGraphProxy
 from .. import ParseXML, Messages
@@ -30,7 +33,7 @@ from ..Constants import (
     TOP_BLOCK_FILE_MODE, BLOCK_FLAG_NEED_QT_GUI,
     HIER_BLOCK_FILE_MODE, BLOCK_DTD
 )
-from ..utils import expr_utils, odict
+from ..utils import expr_utils
 
 DATA_DIR = os.path.dirname(__file__)
 FLOW_GRAPH_TEMPLATE = os.path.join(DATA_DIR, 'flow_graph.tmpl')
@@ -299,7 +302,7 @@ class HierBlockGenerator(TopBlockGenerator):
             return name
 
         # Build the nested data
-        block_n = odict()
+        block_n = collections.OrderedDict()
         block_n['name'] = self._flow_graph.get_option('title') or \
             self._flow_graph.get_option('id').replace('_', ' ').title()
         block_n['key'] = block_key
@@ -324,7 +327,7 @@ class HierBlockGenerator(TopBlockGenerator):
         # Parameters
         block_n['param'] = list()
         for param in parameters:
-            param_n = odict()
+            param_n = collections.OrderedDict()
             param_n['name'] = param.get_param('label').get_value() or 
param.get_id()
             param_n['key'] = param.get_id()
             param_n['value'] = param.get_param('value').get_value()
@@ -341,7 +344,7 @@ class HierBlockGenerator(TopBlockGenerator):
         for direction in ('sink', 'source'):
             block_n[direction] = list()
             for port in self._flow_graph.get_hier_block_io(direction):
-                port_n = odict()
+                port_n = collections.OrderedDict()
                 port_n['name'] = port['label']
                 port_n['type'] = port['type']
                 if port['type'] != "message":
@@ -374,14 +377,18 @@ class QtHierBlockGenerator(HierBlockGenerator):
 
     def _build_block_n_from_flow_graph_io(self):
         n = HierBlockGenerator._build_block_n_from_flow_graph_io(self)
-        block_n = n['block']
+        block_n = collections.OrderedDict()
+
+        # insert flags after category
+        for key, value in six.iteritems(n['block']):
+            block_n[key] = value
+            if key == 'category':
+                block_n['flags'] = BLOCK_FLAG_NEED_QT_GUI
 
         if not block_n['name'].upper().startswith('QT GUI'):
             block_n['name'] = 'QT GUI ' + block_n['name']
 
-        block_n.insert_after('category', 'flags', BLOCK_FLAG_NEED_QT_GUI)
-
-        gui_hint_param = odict()
+        gui_hint_param = collections.OrderedDict()
         gui_hint_param['name'] = 'GUI Hint'
         gui_hint_param['key'] = 'gui_hint'
         gui_hint_param['value'] = ''
@@ -393,4 +400,5 @@ class QtHierBlockGenerator(HierBlockGenerator):
             "\n#set $win = 'self.%s' % $id"
             "\n${gui_hint()($win)}"
         )
-        return n
+
+        return {'block': block_n}
diff --git a/grc/core/utils/__init__.py b/grc/core/utils/__init__.py
index 0d84f71..66393fd 100644
--- a/grc/core/utils/__init__.py
+++ b/grc/core/utils/__init__.py
@@ -21,4 +21,3 @@ from . import expr_utils
 from . import epy_block_io
 from . import extract_docs
 
-from .odict import odict
diff --git a/grc/core/utils/odict.py b/grc/core/utils/odict.py
deleted file mode 100644
index 38f898a..0000000
--- a/grc/core/utils/odict.py
+++ /dev/null
@@ -1,113 +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
-
-from UserDict import DictMixin
-
-
-class odict(DictMixin):
-
-    def __init__(self, d={}):
-        self._keys = list(d.keys())
-        self._data = dict(d.copy())
-
-    def __setitem__(self, key, value):
-        if key not in self._data:
-            self._keys.append(key)
-        self._data[key] = value
-
-    def __getitem__(self, key):
-        return self._data[key]
-
-    def __delitem__(self, key):
-        del self._data[key]
-        self._keys.remove(key)
-
-    def keys(self):
-        return list(self._keys)
-
-    def copy(self):
-        copy_dict = odict()
-        copy_dict._data = self._data.copy()
-        copy_dict._keys = list(self._keys)
-        return copy_dict
-
-    def insert_after(self, pos_key, key, val):
-        """
-        Insert the new key, value entry after the entry given by the position 
key.
-        If the positional key is None, insert at the end.
-
-        Args:
-            pos_key: the positional key
-            key: the key for the new entry
-            val: the value for the new entry
-        """
-        index = (pos_key is None) and len(self._keys) or 
self._keys.index(pos_key)
-        if key in self._keys:
-            raise KeyError('Cannot insert, key "{}" already 
exists'.format(str(key)))
-        self._keys.insert(index+1, key)
-        self._data[key] = val
-
-    def insert_before(self, pos_key, key, val):
-        """
-        Insert the new key, value entry before the entry given by the position 
key.
-        If the positional key is None, insert at the begining.
-
-        Args:
-            pos_key: the positional key
-            key: the key for the new entry
-            val: the value for the new entry
-        """
-        index = (pos_key is not None) and self._keys.index(pos_key) or 0
-        if key in self._keys:
-            raise KeyError('Cannot insert, key "{}" already 
exists'.format(str(key)))
-        self._keys.insert(index, key)
-        self._data[key] = val
-
-    def find(self, key):
-        """
-        Get the value for this key if exists.
-
-        Args:
-            key: the key to search for
-
-        Returns:
-            the value or None
-        """
-        if key in self:
-            return self[key]
-        return None
-
-    def findall(self, key):
-        """
-        Get a list of values for this key.
-
-        Args:
-            key: the key to search for
-
-        Returns:
-            a list of values or empty list
-        """
-        obj = self.find(key)
-        if obj is None:
-            obj = list()
-        if isinstance(obj, list):
-            return obj
-        return [obj]
diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py
index 50e146b..8f35222 100644
--- a/grc/gui/FlowGraph.py
+++ b/grc/gui/FlowGraph.py
@@ -213,15 +213,15 @@ class FlowGraph(Element, _Flowgraph):
             x_off, y_off = 0, 0
         #create blocks
         for block_n in blocks_n:
-            block_key = block_n.find('key')
-            if block_key == 'options': continue
+            block_key = block_n.get('key')
+            if block_key == 'options':
+                continue
             block = self.new_block(block_key)
             if not block:
                 continue  # unknown block was pasted (e.g. dummy block)
             selected.add(block)
             #set params
-            params = dict((n.find('key'), n.find('value'))
-                          for n in block_n.findall('param'))
+            params = {n['key']: n['value'] for n in block_n.get('param', [])}
             if block_key == 'epy_block':
                 block.get_param('_io_cache').set_value(params.pop('_io_cache'))
                 
block.get_param('_source_code').set_value(params.pop('_source_code'))
@@ -241,8 +241,8 @@ class FlowGraph(Element, _Flowgraph):
         self.update()
         #create connections
         for connection_n in connections_n:
-            source = 
old_id2block[connection_n.find('source_block_id')].get_source(connection_n.find('source_key'))
-            sink = 
old_id2block[connection_n.find('sink_block_id')].get_sink(connection_n.find('sink_key'))
+            source = 
old_id2block[connection_n.get('source_block_id')].get_source(connection_n.get('source_key'))
+            sink = 
old_id2block[connection_n.get('sink_block_id')].get_sink(connection_n.get('sink_key'))
             self.connect(source, sink)
         #set all pasted elements selected
         for block in selected: selected = 
selected.union(set(block.get_connections()))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]