diff options
author | Johnathan Corgan <johnathan@corganlabs.com> | 2016-02-03 11:59:50 -0800 |
---|---|---|
committer | Johnathan Corgan <johnathan@corganlabs.com> | 2016-02-03 11:59:50 -0800 |
commit | 1049fa0bbde029f5435ee6e5cd8e28d1d275ce7c (patch) | |
tree | 4451e884bcf40b050d1e05f74ca26e767b8d9c9c /grc | |
parent | 5632236167e81694947d992918a8035fa1bc2972 (diff) | |
parent | 13b69807d0881c233f0cd5b73e5a07425852777c (diff) |
Merge branch 'master' into next
Diffstat (limited to 'grc')
-rw-r--r-- | grc/gui/Messages.py | 2 | ||||
-rw-r--r-- | grc/python/Block.py | 7 | ||||
-rw-r--r-- | grc/python/Generator.py | 49 | ||||
-rw-r--r-- | grc/python/epy_block_io.py | 12 |
4 files changed, 48 insertions, 22 deletions
diff --git a/grc/gui/Messages.py b/grc/gui/Messages.py index 32c6cf108e..551a8ce753 100644 --- a/grc/gui/Messages.py +++ b/grc/gui/Messages.py @@ -122,7 +122,7 @@ def send_fail_gen(error): def send_start_exec(file_path): - send('\nExecuting: %r\n' % file_path) + send('\nExecuting: %s\n' % file_path) def send_verbose_exec(verbose): diff --git a/grc/python/Block.py b/grc/python/Block.py index 239352de1f..f5c994dc05 100644 --- a/grc/python/Block.py +++ b/grc/python/Block.py @@ -272,7 +272,7 @@ class Block(_Block, _GUIBlock): self._make = '{}({})'.format(blk_io.cls, ', '.join( '{0}=${0}'.format(key) for key, _ in blk_io.params)) - params = dict() + params = {} for param in list(self._params): if hasattr(param, '__epy_param__'): params[param.get_key()] = param @@ -293,7 +293,7 @@ class Block(_Block, _GUIBlock): def update_ports(label, ports, port_specs, direction): ports_to_remove = list(ports) iter_ports = iter(ports) - ports_new = list() + ports_new = [] port_current = next(iter_ports, None) for key, port_type in port_specs: reuse_port = ( @@ -306,6 +306,9 @@ class Block(_Block, _GUIBlock): port, port_current = port_current, next(iter_ports, None) else: n = odict(dict(name=label + str(key), type=port_type, key=key)) + if port_type == 'message': + n['name'] = key + n['optional'] = '1' port = platform.Port(block=self, n=n, dir=direction) ports_new.append(port) # replace old port list with new one diff --git a/grc/python/Generator.py b/grc/python/Generator.py index d688beba15..56e3a6e78f 100644 --- a/grc/python/Generator.py +++ b/grc/python/Generator.py @@ -23,6 +23,7 @@ import subprocess import tempfile import shlex import codecs +import re # for shlex_quote from distutils.spawn import find_executable from Cheetah.Template import Template @@ -125,24 +126,30 @@ class TopBlockGenerator(object): Returns: a popen object """ - def args_to_string(args): - """Accounts for spaces in args""" - return ' '.join(repr(arg) if ' ' in arg else arg for arg in args) - run_command = self._flow_graph.get_option('run_command') - cmds = shlex.split(run_command.format(python=sys.executable, - filename=self.get_file_path())) + try: + run_command = run_command.format( + python=shlex_quote(sys.executable), + filename=shlex_quote(self.get_file_path())) + run_command_args = shlex.split(run_command) + except Exception as e: + raise ValueError("Can't parse run command {!r}: {}".format(run_command, e)) # when in no gui mode on linux, use a graphical terminal (looks nice) xterm_executable = find_executable(XTERM_EXECUTABLE) if self._generate_options == 'no_gui' and xterm_executable: - cmds = [xterm_executable, '-e', args_to_string(cmds)] + run_command_args = [xterm_executable, '-e', run_command] - Messages.send_start_exec(args_to_string(cmds)) - p = subprocess.Popen( - args=cmds, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, - shell=False, universal_newlines=True) - return p + # this does not reproduce a shell executable command string, if a graphical + # terminal is used. Passing run_command though shlex_quote would do it but + # it looks really ugly and confusing in the console panel. + Messages.send_start_exec(' '.join(run_command_args)) + + return subprocess.Popen( + args=run_command_args, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + shell=False, universal_newlines=True + ) def _build_python_code_from_template(self): """ @@ -420,3 +427,21 @@ class QtHierBlockGenerator(HierBlockGenerator): "\n${gui_hint()($win)}" ) return n + + +########################################################### +# back-port from python3 +########################################################### +_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search + + +def shlex_quote(s): + """Return a shell-escaped version of the string *s*.""" + if not s: + return "''" + if _find_unsafe(s) is None: + return s + + # use single quotes, and put single quotes into double quotes + # the string $'b is then quoted as '$'"'"'b' + return "'" + s.replace("'", "'\"'\"'") + "'" diff --git a/grc/python/epy_block_io.py b/grc/python/epy_block_io.py index 8d3ce1caa1..e089908a01 100644 --- a/grc/python/epy_block_io.py +++ b/grc/python/epy_block_io.py @@ -39,10 +39,8 @@ def _blk_class(source_code): raise ValueError("Can't interpret source code: " + str(e)) for var in ns.itervalues(): if inspect.isclass(var)and issubclass(var, gr.gateway.gateway_block): - break - else: - raise ValueError('No python block class found in code') - return var + return var + raise ValueError('No python block class found in code') def extract(cls): @@ -55,7 +53,7 @@ def extract(cls): cls_name = cls.__name__ if len(defaults) + 1 != len(spec.args): - raise ValueError("Need all default values") + raise ValueError("Need all __init__ arguments to have default values") try: instance = cls() @@ -66,9 +64,9 @@ def extract(cls): params = list(zip(spec.args[1:], defaults)) sinks = _ports(instance.in_sig(), - pmt.to_python(instance.message_ports_in())) + pmt.to_python(instance.message_ports_in())) sources = _ports(instance.out_sig(), - pmt.to_python(instance.message_ports_out())) + pmt.to_python(instance.message_ports_out())) return BlockIO(name, cls_name, params, sinks, sources, doc) |