summaryrefslogtreecommitdiff
path: root/grc/python
diff options
context:
space:
mode:
authorJohnathan Corgan <johnathan@corganlabs.com>2016-02-03 11:59:50 -0800
committerJohnathan Corgan <johnathan@corganlabs.com>2016-02-03 11:59:50 -0800
commit1049fa0bbde029f5435ee6e5cd8e28d1d275ce7c (patch)
tree4451e884bcf40b050d1e05f74ca26e767b8d9c9c /grc/python
parent5632236167e81694947d992918a8035fa1bc2972 (diff)
parent13b69807d0881c233f0cd5b73e5a07425852777c (diff)
Merge branch 'master' into next
Diffstat (limited to 'grc/python')
-rw-r--r--grc/python/Block.py7
-rw-r--r--grc/python/Generator.py49
-rw-r--r--grc/python/epy_block_io.py12
3 files changed, 47 insertions, 21 deletions
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)