diff options
Diffstat (limited to 'gnuradio-runtime')
-rw-r--r-- | gnuradio-runtime/include/gnuradio/basic_block.h | 31 | ||||
-rw-r--r-- | gnuradio-runtime/include/gnuradio/block_registry.h | 3 | ||||
-rw-r--r-- | gnuradio-runtime/include/gnuradio/logger.h.in | 30 | ||||
-rw-r--r-- | gnuradio-runtime/include/pmt/pmt_sugar.h | 10 | ||||
-rw-r--r-- | gnuradio-runtime/lib/basic_block.cc | 27 | ||||
-rw-r--r-- | gnuradio-runtime/lib/block.cc | 2 | ||||
-rw-r--r-- | gnuradio-runtime/lib/block_registry.cc | 20 | ||||
-rw-r--r-- | gnuradio-runtime/lib/flowgraph.cc | 8 | ||||
-rwxr-xr-x | gnuradio-runtime/lib/pmt/generate_unv.py | 1 | ||||
-rw-r--r-- | gnuradio-runtime/lib/pmt/pmt_int.h | 1 | ||||
-rw-r--r-- | gnuradio-runtime/lib/pmt/pmt_io.cc | 13 | ||||
-rw-r--r-- | gnuradio-runtime/lib/pmt/unv_template.cc.t | 6 | ||||
-rw-r--r-- | gnuradio-runtime/lib/pmt/unv_template.h.t | 1 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/__init__.py | 8 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/packet_utils.py | 137 | ||||
-rw-r--r-- | gnuradio-runtime/python/pmt/pmt_to_python.py | 7 |
17 files changed, 273 insertions, 33 deletions
diff --git a/gnuradio-runtime/include/gnuradio/basic_block.h b/gnuradio-runtime/include/gnuradio/basic_block.h index 69775865ee..b413274ded 100644 --- a/gnuradio-runtime/include/gnuradio/basic_block.h +++ b/gnuradio-runtime/include/gnuradio/basic_block.h @@ -144,14 +144,41 @@ namespace gr { virtual ~basic_block(); long unique_id() const { return d_unique_id; } long symbolic_id() const { return d_symbolic_id; } + + /*! The name of the block */ std::string name() const { return d_name; } + + /*! + * The sybolic name of the block, which is used in the + * block_registry. The name is assigned by the block's constructor + * and never changes during the life of the block. + */ std::string symbol_name() const { return d_symbol_name; } + gr::io_signature::sptr input_signature() const { return d_input_signature; } gr::io_signature::sptr output_signature() const { return d_output_signature; } basic_block_sptr to_basic_block(); // Needed for Python type coercion + + /*! + * True if the block has an alias (see set_block_alias). + */ bool alias_set() { return !d_symbol_alias.empty(); } + + /*! + * Returns the block's alias as a string. + */ std::string alias(){ return alias_set()?d_symbol_alias:symbol_name(); } + + /*! + * Returns the block's alias as PMT. + */ pmt::pmt_t alias_pmt(){ return pmt::intern(alias()); } + + /*! + * Set's a new alias for the block; also adds an entry into the + * block_registry to get the block using either the alias or the + * original symbol name. + */ void set_block_alias(std::string name); // ** Message passing interface ** @@ -248,6 +275,10 @@ namespace gr { } return false; } + + const msg_queue_map_t& get_msg_map(void) const { + return msg_queue; + } #ifdef GR_CTRLPORT /*! diff --git a/gnuradio-runtime/include/gnuradio/block_registry.h b/gnuradio-runtime/include/gnuradio/block_registry.h index 49f0b7222d..86e5528dd1 100644 --- a/gnuradio-runtime/include/gnuradio/block_registry.h +++ b/gnuradio-runtime/include/gnuradio/block_registry.h @@ -44,9 +44,10 @@ namespace gr { std::string register_symbolic_name(basic_block* block); void register_symbolic_name(basic_block* block, std::string name); + void update_symbolic_name(basic_block* block, std::string name); basic_block_sptr block_lookup(pmt::pmt_t symbol); - + void register_primitive(std::string blk, gr::block* ref); void unregister_primitive(std::string blk); void notify_blk(std::string blk); diff --git a/gnuradio-runtime/include/gnuradio/logger.h.in b/gnuradio-runtime/include/gnuradio/logger.h.in index 17afa7effd..8e8cd2fb1e 100644 --- a/gnuradio-runtime/include/gnuradio/logger.h.in +++ b/gnuradio-runtime/include/gnuradio/logger.h.in @@ -1,19 +1,19 @@ /* -*- c++ -*- */ /* * Copyright 2012-2013 Free Software Foundation, Inc. - * + * * This file is part of GNU Radio - * + * * GNU Radio 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 3, or (at your option) * any later version. - * + * * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, @@ -69,9 +69,9 @@ namespace gr { #define GR_LOG_ASSIGN_LOGPTR(logger,name) #define GR_CONFIG_LOGGER(config) #define GR_CONFIG_AND_WATCH_LOGGER(config,period) -#define GR_LOG_GETLOGGER(logger, name) +#define GR_LOG_GETLOGGER(logger, name) #define GR_SET_LEVEL(name, level) -#define GR_LOG_SET_LEVEL(logger, level) +#define GR_LOG_SET_LEVEL(logger, level) #define GR_GET_LEVEL(name, level) #define GR_LOG_GET_LEVEL(logger, level) #define GR_ADD_APPENDER(name,appender) @@ -326,11 +326,11 @@ namespace gr { namespace gr { /*! - * \brief Class to control configuration of logger. + * \brief Class to control configuration of logger. * This is a singleton that cna launch a thread to wathc a config file for changes * \ingroup logging */ - class logger_config + class GR_RUNTIME_API logger_config { private: /*! \brief filename of logger config file */ @@ -340,7 +340,7 @@ namespace gr { /*! \brief Pointer to watch thread for config file changes */ boost::thread *watch_thread; - /*! \brief Watcher thread method + /*! \brief Watcher thread method * /param filename Name of configuration file * /param watch_period Seconds between checks for changes in config file */ @@ -632,7 +632,7 @@ namespace gr { * * Add rolling file appender to a given logger * - * \return vector of string names of loggers + * \return vector of string names of loggers */ GR_RUNTIME_API std::vector<std::string> logger_get_logger_names(void); @@ -651,9 +651,9 @@ namespace gr { #define GR_LOG_ASSIGN_LOGPTR(logger,name) #define GR_CONFIG_LOGGER(config) #define GR_CONFIG_AND_WATCH_LOGGER(config,period) -#define GR_LOG_GETLOGGER(logger, name) +#define GR_LOG_GETLOGGER(logger, name) #define GR_SET_LEVEL(name, level) -#define GR_LOG_SET_LEVEL(logger, level) +#define GR_LOG_SET_LEVEL(logger, level) #define GR_GET_LEVEL(name, level) #define GR_LOG_GET_LEVEL(logger, level) #define GR_ADD_APPENDER(name,appender) @@ -710,7 +710,7 @@ namespace gr { * \ingroup logging * */ - class logger + class GR_RUNTIME_API logger { private: /*! \brief logger pointer to logger associated wiith this wrapper class */ @@ -812,7 +812,7 @@ namespace gr { /**************** Start Configuration Class and Methods for Python ************/ /*! - * \brief Function to call configuration macro from python. + * \brief Function to call configuration macro from python. * Note: Configuration is only updated if filename or watch_period has changed. * \param config_filename Name of configuration file * \param watch_period Seconds to wait between checking for changes in conf file. @@ -830,7 +830,7 @@ GR_RUNTIME_API std::vector<std::string> gr_logger_get_logger_names(void); /*! * \brief Function to reset logger configuration from python - * + * */ GR_RUNTIME_API void gr_logger_reset_config(void); diff --git a/gnuradio-runtime/include/pmt/pmt_sugar.h b/gnuradio-runtime/include/pmt/pmt_sugar.h index 870b81902e..424f85cb01 100644 --- a/gnuradio-runtime/include/pmt/pmt_sugar.h +++ b/gnuradio-runtime/include/pmt/pmt_sugar.h @@ -51,10 +51,16 @@ namespace pmt { return from_long(x); } - //! Make pmt long + //! Make pmt uint64 + static inline pmt_t + mp(long unsigned x){ + return from_uint64(x); + } + + //! Make pmt uint64 static inline pmt_t mp(long long unsigned x){ - return from_long(x); + return from_uint64(x); } //! Make pmt long diff --git a/gnuradio-runtime/lib/basic_block.cc b/gnuradio-runtime/lib/basic_block.cc index 40edf09b01..686c1d6e65 100644 --- a/gnuradio-runtime/lib/basic_block.cc +++ b/gnuradio-runtime/lib/basic_block.cc @@ -71,8 +71,17 @@ namespace gr { void basic_block::set_block_alias(std::string name) - { - global_block_registry.register_symbolic_name(this, name); + { + // Only keep one alias'd name around for each block. If we don't + // have an alias, add it; if we do, update the entry in the + // registry. + if(alias_set()) + global_block_registry.update_symbolic_name(this, name); + else + global_block_registry.register_symbolic_name(this, name); + + // set the block's alias + d_symbol_alias = name; } // ** Message passing interface ** @@ -131,7 +140,7 @@ namespace gr { if(!pmt::dict_has_key(d_message_subscribers, port_id)) { throw std::runtime_error("port does not exist"); } - + pmt::pmt_t currlist = pmt::dict_ref(d_message_subscribers, port_id, pmt::PMT_NIL); // iterate through subscribers on port while(pmt::is_pair(currlist)) { @@ -139,7 +148,7 @@ namespace gr { pmt::pmt_t block = pmt::car(target); pmt::pmt_t port = pmt::cdr(target); - + currlist = pmt::cdr(currlist); basic_block_sptr blk = global_block_registry.block_lookup(block); //blk->post(msg); @@ -150,14 +159,14 @@ namespace gr { // - subscribe to a message port void basic_block::message_port_sub(pmt::pmt_t port_id, pmt::pmt_t target){ - if(!pmt::dict_has_key(d_message_subscribers, port_id)){ + if(!pmt::dict_has_key(d_message_subscribers, port_id)){ std::stringstream ss; ss << "Port does not exist: \"" << pmt::write_string(port_id) << "\" on block: " << pmt::write_string(target) << std::endl; throw std::runtime_error(ss.str()); } pmt::pmt_t currlist = pmt::dict_ref(d_message_subscribers,port_id,pmt::PMT_NIL); - + // ignore re-adds of the same target if(!pmt::list_has(currlist, target)) d_message_subscribers = pmt::dict_add(d_message_subscribers,port_id,pmt::list_add(currlist,target)); @@ -166,13 +175,13 @@ namespace gr { void basic_block::message_port_unsub(pmt::pmt_t port_id, pmt::pmt_t target) { - if(!pmt::dict_has_key(d_message_subscribers, port_id)) { + if(!pmt::dict_has_key(d_message_subscribers, port_id)) { std::stringstream ss; ss << "Port does not exist: \"" << pmt::write_string(port_id) << "\" on block: " << pmt::write_string(target) << std::endl; throw std::runtime_error(ss.str()); } - + // ignore unsubs of unknown targets pmt::pmt_t currlist = pmt::dict_ref(d_message_subscribers,port_id,pmt::PMT_NIL); d_message_subscribers = pmt::dict_add(d_message_subscribers,port_id,pmt::list_rm(currlist,target)); @@ -230,7 +239,7 @@ namespace gr { return m; } - pmt::pmt_t + pmt::pmt_t basic_block::message_subscribers(pmt::pmt_t port) { return pmt::dict_ref(d_message_subscribers,port,pmt::PMT_NIL); diff --git a/gnuradio-runtime/lib/block.cc b/gnuradio-runtime/lib/block.cc index 9e4fcf5cca..6309bca9b1 100644 --- a/gnuradio-runtime/lib/block.cc +++ b/gnuradio-runtime/lib/block.cc @@ -111,7 +111,7 @@ namespace gr { block::~block() { - global_block_registry.unregister_primitive(alias()); + global_block_registry.unregister_primitive(symbol_name()); } unsigned diff --git a/gnuradio-runtime/lib/block_registry.cc b/gnuradio-runtime/lib/block_registry.cc index c4dc7647d6..5241ef9922 100644 --- a/gnuradio-runtime/lib/block_registry.cc +++ b/gnuradio-runtime/lib/block_registry.cc @@ -90,6 +90,26 @@ namespace gr { d_ref_map = pmt::dict_add(d_ref_map, pmt::intern(name), pmt::make_any(block)); } + void + block_registry::update_symbolic_name(basic_block* block, std::string name) + { + gr::thread::scoped_lock guard(d_mutex); + + if(pmt::dict_has_key(d_ref_map, pmt::intern(name))) { + throw std::runtime_error("symbol already exists, can not re-use!"); + } + + // If we don't already have an alias, don't try and delete it. + if(block->alias_set()) { + // And make sure that the registry has the alias key. + // We test both in case the block's and registry ever get out of sync. + if(pmt::dict_has_key(d_ref_map, block->alias_pmt())) { + d_ref_map = pmt::dict_delete(d_ref_map, block->alias_pmt()); + } + } + d_ref_map = pmt::dict_add(d_ref_map, pmt::intern(name), pmt::make_any(block)); + } + basic_block_sptr block_registry::block_lookup(pmt::pmt_t symbol) { diff --git a/gnuradio-runtime/lib/flowgraph.cc b/gnuradio-runtime/lib/flowgraph.cc index 3d8dfea65a..abe51f741d 100644 --- a/gnuradio-runtime/lib/flowgraph.cc +++ b/gnuradio-runtime/lib/flowgraph.cc @@ -155,8 +155,14 @@ namespace gr { if(FLOWGRAPH_DEBUG) std::cout << "check_valid_port( " << e.block() << ", " << e.port() << ")\n"; - if(!e.block()->has_msg_port(e.port())) + if(!e.block()->has_msg_port(e.port())) { + const gr::basic_block::msg_queue_map_t& msg_map = e.block()->get_msg_map(); + std::cout << "Could not find port: " << e.port() << " in:" << std::endl; + for (gr::basic_block::msg_queue_map_t::const_iterator it = msg_map.begin(); it != msg_map.end(); ++it) + std::cout << it->first << std::endl; + std::cout << std::endl; throw std::invalid_argument("invalid msg port in connect() or disconnect()"); + } } void diff --git a/gnuradio-runtime/lib/pmt/generate_unv.py b/gnuradio-runtime/lib/pmt/generate_unv.py index 7562df46f8..6218099fc1 100755 --- a/gnuradio-runtime/lib/pmt/generate_unv.py +++ b/gnuradio-runtime/lib/pmt/generate_unv.py @@ -76,6 +76,7 @@ includes = """ #endif #include <vector> #include <pmt/pmt.h> +#include <boost/lexical_cast.hpp> #include "pmt_int.h" """ diff --git a/gnuradio-runtime/lib/pmt/pmt_int.h b/gnuradio-runtime/lib/pmt/pmt_int.h index ca90c5a475..49bde52063 100644 --- a/gnuradio-runtime/lib/pmt/pmt_int.h +++ b/gnuradio-runtime/lib/pmt/pmt_int.h @@ -239,6 +239,7 @@ public: virtual void *uniform_writable_elements(size_t &len) = 0; virtual size_t length() const = 0; virtual size_t itemsize() const = 0; + virtual const std::string string_ref(size_t k) const { return std::string("not implemented"); } }; #include "pmt_unv_int.h" diff --git a/gnuradio-runtime/lib/pmt/pmt_io.cc b/gnuradio-runtime/lib/pmt/pmt_io.cc index 17bdee408f..e63bae4994 100644 --- a/gnuradio-runtime/lib/pmt/pmt_io.cc +++ b/gnuradio-runtime/lib/pmt/pmt_io.cc @@ -110,9 +110,16 @@ write(pmt_t obj, std::ostream &port) port << "#<dict>"; } else if (is_uniform_vector(obj)){ - // FIXME - // port << "#<uniform-vector " << obj << ">"; - port << "#<uniform-vector>"; + port << "#["; + size_t len = length(obj); + if (len) + { + pmt_uniform_vector *uv = static_cast<pmt_uniform_vector*>(obj.get()); + port << uv->string_ref(0); + for (size_t i = 1; i < len; i++) + port << " " << uv->string_ref(i); + } + port << "]"; } else { error: diff --git a/gnuradio-runtime/lib/pmt/unv_template.cc.t b/gnuradio-runtime/lib/pmt/unv_template.cc.t index 8678894973..c8020e7de2 100644 --- a/gnuradio-runtime/lib/pmt/unv_template.cc.t +++ b/gnuradio-runtime/lib/pmt/unv_template.cc.t @@ -138,4 +138,10 @@ const std::vector< @TYPE@ > return _@TAG@vector(vector)->writable_elements(len); } +const std::string +pmt_@TAG@vector::string_ref(size_t k) const +{ + return boost::lexical_cast< std::string, @TYPE@ > (ref(k)); +} + } /* namespace pmt */ diff --git a/gnuradio-runtime/lib/pmt/unv_template.h.t b/gnuradio-runtime/lib/pmt/unv_template.h.t index 93ca684463..ab5c163570 100644 --- a/gnuradio-runtime/lib/pmt/unv_template.h.t +++ b/gnuradio-runtime/lib/pmt/unv_template.h.t @@ -21,4 +21,5 @@ public: @TYPE@ *writable_elements(size_t &len); const void *uniform_elements(size_t &len); void *uniform_writable_elements(size_t &len); + virtual const std::string string_ref(size_t k) const; }; diff --git a/gnuradio-runtime/python/gnuradio/gr/CMakeLists.txt b/gnuradio-runtime/python/gnuradio/gr/CMakeLists.txt index 9d6f4dd718..ddad2c448a 100644 --- a/gnuradio-runtime/python/gnuradio/gr/CMakeLists.txt +++ b/gnuradio-runtime/python/gnuradio/gr/CMakeLists.txt @@ -23,6 +23,7 @@ include(GrPython) GR_PYTHON_INSTALL(FILES __init__.py tag_utils.py + packet_utils.py gateway.py gr_threading.py gr_threading_23.py diff --git a/gnuradio-runtime/python/gnuradio/gr/__init__.py b/gnuradio-runtime/python/gnuradio/gr/__init__.py index 94a5c9ec2b..4fc55c68b2 100644 --- a/gnuradio-runtime/python/gnuradio/gr/__init__.py +++ b/gnuradio-runtime/python/gnuradio/gr/__init__.py @@ -48,3 +48,11 @@ from gateway import basic_block, sync_block, decim_block, interp_block # Force the preference database to be initialized prefs = prefs.singleton + +log = gr.logger("log") +log.add_console_appender(prefs().get_string("LOG", "log_level", "off"), 'gr::log %d :%p: %m%n') +log.set_level(prefs().get_string("LOG", "log_level", "notset")) + +log_debug = gr.logger("log_debug") +log_debug.add_console_appender(prefs().get_string("LOG", "debug_level", "off"), 'gr::debug %d :%p: %m%n') +log_debug.set_level(prefs().get_string("LOG", "debug_level", "notset")) diff --git a/gnuradio-runtime/python/gnuradio/gr/packet_utils.py b/gnuradio-runtime/python/gnuradio/gr/packet_utils.py new file mode 100644 index 0000000000..7ae42e88e3 --- /dev/null +++ b/gnuradio-runtime/python/gnuradio/gr/packet_utils.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python +# +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr +import pmt + +def make_lengthtags(lengths, offsets, tagname='length', vlen=1): + tags = [] + assert(len(offsets) == len(lengths)) + for offset, length in zip(offsets, lengths): + tag = gr.tag_t() + tag.offset = offset/vlen + tag.key = pmt.string_to_symbol(tagname) + tag.value = pmt.from_long(length/vlen) + 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] + lengths = {} + for tag in lengthtags: + if tag.offset in lengths: + 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 + in_burst = False + in_packet = False + packet_length = None + packet_pos = None + burst_count = 0 + 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)) + raise StandardError("Received packet tag while in packet.") + packet_pos = -1 + packet_length = lengths[pos] + in_packet = True + if not in_burst: + burst_count += 1 + in_burst = True + elif not in_packet: + in_burst = False + if in_packet: + packet_pos += 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] + lengths = {} + for tag in lengthtags: + if tag.offset in lengths: + 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 + if 0 not in lengths: + raise ValueError("There is no tag with key {0} and an offset of 0" + .format(tsb_tag_key)) + pos = 0 + packets = [] + while pos < len(data): + if pos not in lengths: + raise ValueError("There is no tag with key {0} and an offset of {1}." + "We were expecting one." + .format(tsb_tag_key, pos)) + length = lengths[pos] + if length == 0: + raise ValueError("Packets cannot have zero length.") + if pos+length > len(data): + raise ValueError("The final packet is incomplete.") + 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 + and tags will produced a correct tagged stream. """ + tags = [] + data = [] + offset = 0 + for packet in packets: + data.extend(packet) + tag = gr.tag_t() + tag.offset = offset/vlen + tag.key = pmt.string_to_symbol(tsb_tag_key) + tag.value = pmt.from_long(len(packet)/vlen) + tags.append(tag) + offset = offset + len(packet) + return data, tags + diff --git a/gnuradio-runtime/python/pmt/pmt_to_python.py b/gnuradio-runtime/python/pmt/pmt_to_python.py index 3344eba163..8973b886e6 100644 --- a/gnuradio-runtime/python/pmt/pmt_to_python.py +++ b/gnuradio-runtime/python/pmt/pmt_to_python.py @@ -110,12 +110,17 @@ type_mappings = ( #python type, check pmt type, to python, from python (tuple, pmt.is_tuple, pmt_to_tuple, pmt_from_tuple), (list, pmt.is_vector, pmt_to_vector, pmt_from_vector), (dict, pmt.is_dict, pmt_to_dict, pmt_from_dict), + (tuple, pmt.is_pair, lambda x: (pmt_to_python(pmt.car(x)), pmt_to_python(pmt.cdr(x))), lambda x: pmt.cons(python_to_pmt(x[0]), python_to_pmt(x[1]))), (numpy.ndarray, pmt.is_uniform_vector, uvector_to_numpy, numpy_to_uvector), ) def pmt_to_python(p): for python_type, pmt_check, to_python, from_python in type_mappings: - if pmt_check(p): return to_python(p) + if pmt_check(p): + try: + return to_python(p) + except: + pass raise ValueError("can't convert %s type to pmt (%s)"%(type(p),p)) def python_to_pmt(p): |