From 3b359abc14837f715ae9d06361d5a991ed68d953 Mon Sep 17 00:00:00 2001 From: arvidn Date: Tue, 21 Feb 2017 19:04:36 -0500 Subject: [PATCH] add pickle support to error_code python binding --- bindings/python/src/error_code.cpp | 70 ++++++++++++++++++++++++++++++ bindings/python/test.py | 4 +- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/bindings/python/src/error_code.cpp b/bindings/python/src/error_code.cpp index c01022b97..0f772efa3 100644 --- a/bindings/python/src/error_code.cpp +++ b/bindings/python/src/error_code.cpp @@ -34,12 +34,81 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include +#if defined TORRENT_USE_OPENSSL +#include +#endif #include "boost_python.hpp" using namespace boost::python; using namespace libtorrent; using boost::system::error_category; +namespace { + + struct ec_pickle_suite : boost::python::pickle_suite + { + static boost::python::tuple + getinitargs(error_code const& ec) + { + return boost::python::tuple(); + } + + static boost::python::tuple + getstate(error_code const& ec) + { + return boost::python::make_tuple(ec.value(), ec.category().name()); + } + + static void + setstate(error_code& ec, boost::python::tuple state) + { + using namespace boost::python; + if (len(state) != 2) + { + PyErr_SetObject(PyExc_ValueError, + ("expected 2-item tuple in call to __setstate__; got %s" + % state).ptr()); + throw_error_already_set(); + } + + int const value = extract(state[0]); + std::string const category = extract(state[1]); + if (category == "system") + ec.assign(value, libtorrent::system_category()); + else if (category == "generic") + ec.assign(value, libtorrent::generic_category()); + else if (category == "libtorrent") + ec.assign(value, libtorrent::libtorrent_category()); + else if (category == "http error") + ec.assign(value, libtorrent::http_category()); + else if (category == "UPnP error") + ec.assign(value, libtorrent::upnp_category()); + else if (category == "bdecode error") + ec.assign(value, libtorrent::bdecode_category()); + else if (category == "asio.netdb") + ec.assign(value, boost::asio::error::get_netdb_category()); + else if (category == "asio.addinfo") + ec.assign(value, boost::asio::error::get_addrinfo_category()); + else if (category == "asio.misc") + ec.assign(value, boost::asio::error::get_misc_category()); + else if (category == "asio.misc") + ec.assign(value, boost::asio::error::get_misc_category()); +#if defined TORRENT_USE_OPENSSL + else if (category == "asio.ssl") + ec.assign(value, boost::asio::error::get_ssl_category()); +#endif + else + { + PyErr_SetObject(PyExc_ValueError, + ("unexpected error_category passed to __setstate__; got '%s'" + % object(category)).ptr()); + throw_error_already_set(); + } + } + }; +} + void bind_error_code() { class_("error_category", no_init) @@ -58,6 +127,7 @@ void bind_error_code() .def("category", &error_code::category , return_internal_reference<>()) .def("assign", &error_code::assign) + .def_pickle(ec_pickle_suite()) ; typedef return_value_policy return_existing; diff --git a/bindings/python/test.py b/bindings/python/test.py index 41da3d7e2..bf6d9e674 100644 --- a/bindings/python/test.py +++ b/bindings/python/test.py @@ -85,7 +85,7 @@ class test_torrent_handle(unittest.TestCase): pickled_trackers = pickle.dumps(tracker_list) unpickled_trackers = pickle.loads(pickled_trackers) self.assertEqual(unpickled_trackers[0]['url'], 'udp://tracker1.com') - self.assertEqual(unpickled_trackers[0]['last_error']['value'], 0) + self.assertEqual(unpickled_trackers[0]['last_error'].value(), 0) def test_file_status(self): self.setup() @@ -173,7 +173,7 @@ class test_torrent_info(unittest.TestCase): self.assertEquals(ae.can_announce(False), True) self.assertEquals(ae.scrape_incomplete, -1) self.assertEquals(ae.next_announce, None) - self.assertEquals(ae.last_error['value'], 0) + self.assertEquals(ae.last_error.value(), 0) class test_alerts(unittest.TestCase):