diff options
Diffstat (limited to 'gnuradio-runtime/python/gnuradio/gr')
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/__init__.py | 2 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/exceptions.py | 1 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/gateway.py | 69 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/hier_block2.py | 9 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/packet_utils.py | 22 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/pubsub.py | 31 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/qa_flowgraph.py | 1 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/qa_hier_block2.py | 6 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/qa_random.py | 3 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/tag_utils.py | 10 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/top_block.py | 8 |
11 files changed, 95 insertions, 67 deletions
diff --git a/gnuradio-runtime/python/gnuradio/gr/__init__.py b/gnuradio-runtime/python/gnuradio/gr/__init__.py index 0715a641ea..49142c65fc 100644 --- a/gnuradio-runtime/python/gnuradio/gr/__init__.py +++ b/gnuradio-runtime/python/gnuradio/gr/__init__.py @@ -20,7 +20,7 @@ Core contents. # If gnuradio is installed then the pybind output will be in this directory. # Otherwise it will reside in bindings/. -import os, sys +import os try: from .gr_python import * diff --git a/gnuradio-runtime/python/gnuradio/gr/exceptions.py b/gnuradio-runtime/python/gnuradio/gr/exceptions.py index 5dec4a6301..eda63b7954 100644 --- a/gnuradio-runtime/python/gnuradio/gr/exceptions.py +++ b/gnuradio-runtime/python/gnuradio/gr/exceptions.py @@ -10,6 +10,7 @@ class NotDAG (Exception): """Not a directed acyclic graph""" pass + class CantHappen (Exception): """Can't happen""" pass diff --git a/gnuradio-runtime/python/gnuradio/gr/gateway.py b/gnuradio-runtime/python/gnuradio/gr/gateway.py index 3be5e64eeb..7091a0586c 100644 --- a/gnuradio-runtime/python/gnuradio/gr/gateway.py +++ b/gnuradio-runtime/python/gnuradio/gr/gateway.py @@ -8,7 +8,6 @@ # - import numpy import ctypes @@ -80,7 +79,7 @@ class py_io_signature(object): return () if nports <= ntypes: return self.__types[:nports] - return self.__types + [self.__types[-1]]*(nports-ntypes) + return self.__types + [self.__types[-1]] * (nports - ntypes) def __iter__(self): """ @@ -106,7 +105,7 @@ class gateway_block(object): # Normalize the many Python ways of saying 'nothing' to '()' in_sig = in_sig or () out_sig = out_sig or () - + # Backward compatibility: array of type strings -> py_io_signature if type(in_sig) is py_io_signature: self.__in_sig = in_sig @@ -138,17 +137,17 @@ class gateway_block(object): Makes this block connectable by hier/top block python """ return self.gateway.to_basic_block() - + def fixed_rate_noutput_to_ninput(self, noutput_items): return int((noutput_items * self._decim / self._interp) + self.gateway.history() - 1) def handle_forecast(self, noutput_items, ninputs): """ - This is the handler function for forecast calls from + This is the handler function for forecast calls from block_gateway in c++ across pybind11 wrappers """ return self.forecast(noutput_items, ninputs) - + # return ninput_items_required def forecast(self, noutput_items, ninputs): @@ -156,50 +155,51 @@ class gateway_block(object): forecast is only called from a general block this is the default implementation """ - ninput_items_required = [0]*ninputs + ninput_items_required = [0] * ninputs for i in range(ninputs): - ninput_items_required[i] = noutput_items + self.gateway.history() - 1 + ninput_items_required[i] = noutput_items + \ + self.gateway.history() - 1 return ninput_items_required - def handle_general_work(self, noutput_items, - ninput_items, - input_items, - output_items): + def handle_general_work(self, noutput_items, + ninput_items, + input_items, + output_items): ninputs = len(input_items) noutputs = len(output_items) in_types = self.in_sig().port_types(ninputs) out_types = self.out_sig().port_types(noutputs) - ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p - ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object, ctypes.c_char_p] + ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ + ctypes.py_object, ctypes.c_char_p] if self._block_type != gr.GW_BLOCK_GENERAL: - ii=[pointer_to_ndarray( - ctypes.pythonapi.PyCapsule_GetPointer(input_items[i],None), + ii = [pointer_to_ndarray( + ctypes.pythonapi.PyCapsule_GetPointer(input_items[i], None), in_types[i], self.fixed_rate_noutput_to_ninput(noutput_items) ) for i in range(ninputs)] else: - ii=[pointer_to_ndarray( - ctypes.pythonapi.PyCapsule_GetPointer(input_items[i],None), + ii = [pointer_to_ndarray( + ctypes.pythonapi.PyCapsule_GetPointer(input_items[i], None), in_types[i], ninput_items[i] ) for i in range(ninputs)] - oo=[pointer_to_ndarray( - ctypes.pythonapi.PyCapsule_GetPointer(output_items[i],None), + oo = [pointer_to_ndarray( + ctypes.pythonapi.PyCapsule_GetPointer(output_items[i], None), out_types[i], noutput_items - ) for i in range(noutputs)] + ) for i in range(noutputs)] if self._block_type != gr.GW_BLOCK_GENERAL: - r = self.work(ii,oo) + r = self.work(ii, oo) self.consume_items(r) else: - r = self.general_work(ii,oo) + r = self.general_work(ii, oo) return r @@ -224,7 +224,8 @@ class gateway_block(object): return self.__out_sig def set_msg_handler(self, which_port, handler_function): - self.gateway.set_msg_handler_pybind(which_port, handler_function.__name__) + self.gateway.set_msg_handler_pybind( + which_port, handler_function.__name__) # Save handler object in class so it's not garbage collected self.msg_handlers[which_port] = handler_function @@ -247,11 +248,10 @@ class gateway_block(object): # return self.gateway.produce(which_output, how_many_items) - ######################################################################## # Wrappers for the user to inherit from ######################################################################## -class basic_block(gateway_block): +class basic_block(gateway_block): """ Args: name (str): block name @@ -263,6 +263,7 @@ class basic_block(gateway_block): For backward compatibility, a sequence of numpy type names is also accepted as an io signature. """ + def __init__(self, name, in_sig, out_sig): gateway_block.__init__(self, name=name, @@ -271,10 +272,11 @@ class basic_block(gateway_block): block_type=gr.GW_BLOCK_GENERAL ) - def consume_items(self, nitems ): + def consume_items(self, nitems): pass -class sync_block(gateway_block): + +class sync_block(gateway_block): """ Args: name (str): block name @@ -286,6 +288,7 @@ class sync_block(gateway_block): For backward compatibility, a sequence of numpy type names is also accepted as an io signature. """ + def __init__(self, name, in_sig, out_sig): gateway_block.__init__(self, name=name, @@ -296,7 +299,7 @@ class sync_block(gateway_block): self._decim = 1 self._interp = 1 - def consume_items(self, nitems ): + def consume_items(self, nitems): if (nitems > 0): self.gateway.consume_each(nitems) @@ -313,6 +316,7 @@ class decim_block(gateway_block): For backward compatibility, a sequence of numpy type names is also accepted as an io signature. """ + def __init__(self, name, in_sig, out_sig, decim): gateway_block.__init__(self, name=name, @@ -325,7 +329,7 @@ class decim_block(gateway_block): self.gateway.set_relative_rate(self._interp, self._decim) self.gateway.set_output_multiple(self._interp) - def consume_items(self, nitems ): + def consume_items(self, nitems): if (nitems > 0): self.gateway.consume_each(int(nitems * self._decim)) @@ -333,7 +337,6 @@ class decim_block(gateway_block): return [self.fixed_rate_noutput_to_ninput(noutput_items) for ii in range(ninputs)] - class interp_block(gateway_block): """ Args: @@ -346,6 +349,7 @@ class interp_block(gateway_block): For backward compatibility, a sequence of numpy type names is also accepted as an io signature. """ + def __init__(self, name, in_sig, out_sig, interp): gateway_block.__init__(self, name=name, @@ -358,8 +362,7 @@ class interp_block(gateway_block): self.gateway.set_relative_rate(self._interp, self._decim) self.gateway.set_output_multiple(self._interp) - - def consume_items(self, nitems ): + def consume_items(self, nitems): if (nitems > 0): self.gateway.consume_each(int(nitems / self._interp)) diff --git a/gnuradio-runtime/python/gnuradio/gr/hier_block2.py b/gnuradio-runtime/python/gnuradio/gr/hier_block2.py index cbb6e77392..4d0f428174 100644 --- a/gnuradio-runtime/python/gnuradio/gr/hier_block2.py +++ b/gnuradio-runtime/python/gnuradio/gr/hier_block2.py @@ -19,12 +19,14 @@ def _multiple_endpoints(func): @functools.wraps(func) def wrapped(self, *points): if not points: - raise ValueError("At least one block required for " + func.__name__) + raise ValueError( + "At least one block required for " + func.__name__) elif len(points) == 1: try: block = points[0].to_basic_block() except AttributeError: - raise ValueError("At least two endpoints required for " + func.__name__) + raise ValueError( + "At least two endpoints required for " + func.__name__) func(self, block) else: try: @@ -75,7 +77,7 @@ class hier_block2(object): """ Pass-through member requests to the C++ object. """ - + try: object.__getattribute__(self, "_impl") except AttributeError as exception: @@ -84,7 +86,6 @@ class hier_block2(object): "a derived class?".format(object.__getattribute__(self.__class__, "__name__"))) from exception return getattr(self._impl, name) - # FIXME: these should really be implemented # in the original C++ class (gr_hier_block2), then they would all be inherited here diff --git a/gnuradio-runtime/python/gnuradio/gr/packet_utils.py b/gnuradio-runtime/python/gnuradio/gr/packet_utils.py index fd7d424480..53e053317d 100644 --- a/gnuradio-runtime/python/gnuradio/gr/packet_utils.py +++ b/gnuradio-runtime/python/gnuradio/gr/packet_utils.py @@ -11,6 +11,7 @@ from gnuradio import gr import pmt + def make_lengthtags(lengths, offsets, tagname='length', vlen=1): tags = [] assert(len(offsets) == len(lengths)) @@ -22,26 +23,31 @@ def make_lengthtags(lengths, offsets, tagname='length', vlen=1): tags.append(tag) return tags + def string_to_vector(string): v = [] for s in string: v.append(ord(s)) return v + def strings_to_vectors(strings, tsb_tag_key): vs = [string_to_vector(string) for string in strings] return packets_to_vectors(vs, tsb_tag_key) + def vector_to_string(v): s = [] for d in v: s.append(chr(d)) return ''.join(s) + def vectors_to_strings(data, tags, tsb_tag_key): packets = vectors_to_packets(data, tags, tsb_tag_key) return [vector_to_string(packet) for packet in packets] + def count_bursts(data, tags, tsb_tag_key, vlen=1): lengthtags = [t for t in tags if pmt.symbol_to_string(t.key) == tsb_tag_key] @@ -51,7 +57,7 @@ def count_bursts(data, tags, tsb_tag_key, vlen=1): raise ValueError( "More than one tags with key {0} with the same offset={1}." .format(tsb_tag_key, tag.offset)) - lengths[tag.offset] = pmt.to_long(tag.value)*vlen + lengths[tag.offset] = pmt.to_long(tag.value) * vlen in_burst = False in_packet = False packet_length = None @@ -60,7 +66,8 @@ def count_bursts(data, tags, tsb_tag_key, vlen=1): for pos in range(len(data)): if pos in lengths: if in_packet: - print("Got tag at pos {0} current packet_pos is {1}".format(pos, packet_pos)) + print("Got tag at pos {0} current packet_pos is {1}".format( + pos, packet_pos)) raise Exception("Received packet tag while in packet.") packet_pos = -1 packet_length = lengths[pos] @@ -72,11 +79,12 @@ def count_bursts(data, tags, tsb_tag_key, vlen=1): in_burst = False if in_packet: packet_pos += 1 - if packet_pos == packet_length-1: + if packet_pos == packet_length - 1: in_packet = False packet_pos = None return burst_count + def vectors_to_packets(data, tags, tsb_tag_key, vlen=1): lengthtags = [t for t in tags if pmt.symbol_to_string(t.key) == tsb_tag_key] @@ -86,7 +94,7 @@ def vectors_to_packets(data, tags, tsb_tag_key, vlen=1): raise ValueError( "More than one tags with key {0} with the same offset={1}." .format(tsb_tag_key, tag.offset)) - lengths[tag.offset] = pmt.to_long(tag.value)*vlen + lengths[tag.offset] = pmt.to_long(tag.value) * vlen if 0 not in lengths: raise ValueError("There is no tag with key {0} and an offset of 0" .format(tsb_tag_key)) @@ -100,12 +108,13 @@ def vectors_to_packets(data, tags, tsb_tag_key, vlen=1): length = lengths[pos] if length == 0: raise ValueError("Packets cannot have zero length.") - if pos+length > len(data): + if pos + length > len(data): raise ValueError("The final packet is incomplete.") - packets.append(data[pos: pos+length]) + packets.append(data[pos: pos + length]) pos += length return packets + def packets_to_vectors(packets, tsb_tag_key, vlen=1): """ Returns a single data vector and a set of tags. If used with blocks.vector_source_X, this set of data @@ -122,4 +131,3 @@ def packets_to_vectors(packets, tsb_tag_key, vlen=1): tags.append(tag) offset = offset + len(packet) return data, tags - diff --git a/gnuradio-runtime/python/gnuradio/gr/pubsub.py b/gnuradio-runtime/python/gnuradio/gr/pubsub.py index 11f53d5597..87e99785a6 100644 --- a/gnuradio-runtime/python/gnuradio/gr/pubsub.py +++ b/gnuradio-runtime/python/gnuradio/gr/pubsub.py @@ -17,9 +17,9 @@ This is a proof of concept implementation, will likely change significantly. class pubsub(dict): def __init__(self): - self._publishers = { } - self._subscribers = { } - self._proxies = { } + self._publishers = {} + self._subscribers = {} + self._proxies = {} def __missing__(self, key, value=None): dict.__setitem__(self, key, value) @@ -41,7 +41,8 @@ class pubsub(dict): sub(val) def __getitem__(self, key): - if key not in self: self.__missing__(key) + if key not in self: + self.__missing__(key) if self._proxies[key] is not None: (p, newkey) = self._proxies[key] return p[newkey] @@ -51,7 +52,8 @@ class pubsub(dict): return dict.__getitem__(self, key) def publish(self, key, publisher): - if key not in self: self.__missing__(key) + if key not in self: + self.__missing__(key) if self._proxies[key] is not None: (p, newkey) = self._proxies[key] p.publish(newkey, publisher) @@ -59,7 +61,8 @@ class pubsub(dict): self._publishers[key] = publisher def subscribe(self, key, subscriber): - if key not in self: self.__missing__(key) + if key not in self: + self.__missing__(key) if self._proxies[key] is not None: (p, newkey) = self._proxies[key] p.subscribe(newkey, subscriber) @@ -81,13 +84,16 @@ class pubsub(dict): self._subscribers[key].remove(subscriber) def proxy(self, key, p, newkey=None): - if key not in self: self.__missing__(key) - if newkey is None: newkey = key + if key not in self: + self.__missing__(key) + if newkey is None: + newkey = key self._proxies[key] = (p, newkey) def unproxy(self, key): self._proxies[key] = None + # Test code if __name__ == "__main__": import sys @@ -106,27 +112,28 @@ if __name__ == "__main__": class subber(object): def __init__(self, param): self._param = param + def printer(self, x): print(self._param, repr(x)) s = subber('param') o.subscribe('foo', s.printer) # The third is a lambda function - o.subscribe('foo', lambda x: sys.stdout.write('val='+repr(x)+'\n')) + o.subscribe('foo', lambda x: sys.stdout.write('val=' + repr(x) + '\n')) # Update key 'foo', will notify subscribers print("Updating 'foo' with three subscribers:") - o['foo'] = 'bar'; + o['foo'] = 'bar' # Remove first subscriber o.unsubscribe('foo', print_len) # Update now will only trigger second and third subscriber print("Updating 'foo' after removing a subscriber:") - o['foo'] = 'bar2'; + o['foo'] = 'bar2' # Publish a key as a function, in this case, a lambda function - o.publish('baz', lambda : 42) + o.publish('baz', lambda: 42) print("Published value of 'baz':", o['baz']) # Unpublish the key diff --git a/gnuradio-runtime/python/gnuradio/gr/qa_flowgraph.py b/gnuradio-runtime/python/gnuradio/gr/qa_flowgraph.py index bbf979d0eb..78eb72222c 100644 --- a/gnuradio-runtime/python/gnuradio/gr/qa_flowgraph.py +++ b/gnuradio-runtime/python/gnuradio/gr/qa_flowgraph.py @@ -25,5 +25,6 @@ class test_flowgraph (gr_unittest.TestCase): self.tb.start() self.tb.stop() + if __name__ == '__main__': gr_unittest.run(test_flowgraph) diff --git a/gnuradio-runtime/python/gnuradio/gr/qa_hier_block2.py b/gnuradio-runtime/python/gnuradio/gr/qa_hier_block2.py index 33a758902b..70075013fb 100644 --- a/gnuradio-runtime/python/gnuradio/gr/qa_hier_block2.py +++ b/gnuradio-runtime/python/gnuradio/gr/qa_hier_block2.py @@ -106,7 +106,7 @@ class test_hier_block2(gr_unittest.TestCase): def test_010_end_with_head(self): import math exp = 1j * 440 / 44100 - src = blocks.vector_source_c([math.e**(exp*n) for n in range(10**6)]) + src = blocks.vector_source_c([math.e**(exp * n) for n in range(10**6)]) head = blocks.head(gr.sizeof_gr_complex, 1000) test = test_hblk([gr.sizeof_gr_complex], 0) tb = gr.top_block() @@ -116,7 +116,7 @@ class test_hier_block2(gr_unittest.TestCase): def test_011_test_message_connect(self): import math exp = 1j * 440 / 44100 - src = blocks.vector_source_c([math.e**(exp*n) for n in range(10**6)]) + src = blocks.vector_source_c([math.e**(exp * n) for n in range(10**6)]) strobe = blocks.message_strobe(pmt.PMT_NIL, 100) head = blocks.head(gr.sizeof_gr_complex, 1000) test = test_hblk([gr.sizeof_gr_complex], 1) @@ -131,7 +131,7 @@ class test_hier_block2(gr_unittest.TestCase): def test_012(self): import math exp = 1j * 440 / 44100 - src = blocks.vector_source_c([math.e**(exp*n) for n in range(10**6)]) + src = blocks.vector_source_c([math.e**(exp * n) for n in range(10**6)]) strobe = blocks.message_strobe(pmt.PMT_NIL, 100) head = blocks.head(gr.sizeof_gr_complex, 1000) test = test_hblk([gr.sizeof_gr_complex], 16) diff --git a/gnuradio-runtime/python/gnuradio/gr/qa_random.py b/gnuradio-runtime/python/gnuradio/gr/qa_random.py index d7f4bb65a5..1f4b8aee15 100644 --- a/gnuradio-runtime/python/gnuradio/gr/qa_random.py +++ b/gnuradio-runtime/python/gnuradio/gr/qa_random.py @@ -95,10 +95,11 @@ class test_random(gr_unittest.TestCase): N = 10**6 self.assertEqual(gr.xoroshiro128p_prng.min(), 0) - self.assertEqual(gr.xoroshiro128p_prng.max(), 2**64-1) + self.assertEqual(gr.xoroshiro128p_prng.max(), 2**64 - 1) rng = gr.xoroshiro128p_prng(42) arr = all((0 <= rng() <= 2**64 - 1 for _ in range(N))) self.assertTrue(arr) + if __name__ == '__main__': gr_unittest.run(test_random) diff --git a/gnuradio-runtime/python/gnuradio/gr/tag_utils.py b/gnuradio-runtime/python/gnuradio/gr/tag_utils.py index d48bf8eb78..7d415c28c9 100644 --- a/gnuradio-runtime/python/gnuradio/gr/tag_utils.py +++ b/gnuradio-runtime/python/gnuradio/gr/tag_utils.py @@ -2,13 +2,16 @@ import pmt from . import gr_python as gr + class PythonTag(object): " Python container for tags " + def __init__(self): self.offset = None - self.key = None - self.value = None - self.srcid = False + self.key = None + self.value = None + self.srcid = False + def tag_to_python(tag): """ Convert a stream tag to a Python-readable object """ @@ -19,6 +22,7 @@ def tag_to_python(tag): newtag.srcid = pmt.to_python(tag.srcid) return newtag + def python_to_tag(tag_struct): """ Convert a Python list/tuple/dictionary to a stream tag. diff --git a/gnuradio-runtime/python/gnuradio/gr/top_block.py b/gnuradio-runtime/python/gnuradio/gr/top_block.py index d44c6c46d4..b3cb06d41c 100644 --- a/gnuradio-runtime/python/gnuradio/gr/top_block.py +++ b/gnuradio-runtime/python/gnuradio/gr/top_block.py @@ -9,15 +9,16 @@ from .gr_python import (top_block_pb, - top_block_wait_unlocked, top_block_run_unlocked, - top_block_start_unlocked, top_block_stop_unlocked, - top_block_unlock_unlocked) #, dot_graph_tb) + top_block_wait_unlocked, top_block_run_unlocked, + top_block_start_unlocked, top_block_stop_unlocked, + top_block_unlock_unlocked) # , dot_graph_tb) from .hier_block2 import hier_block2 import threading from .hier_block2 import hier_block2 + class _top_block_waiter(threading.Thread): """ This kludge allows ^C to interrupt top_block.run and top_block.wait @@ -41,6 +42,7 @@ class _top_block_waiter(threading.Thread): See also top_block.wait (below), which uses this class to implement the interruptible wait. """ + def __init__(self, tb): threading.Thread.__init__(self) self.setDaemon(1) |