PROTON-490: port python C wrapper to Python 3 Original patch provided by Mickael Maison.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/efa1f684 Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/efa1f684 Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/efa1f684 Branch: refs/heads/master Commit: efa1f6840225baf6902d7b0eff3d6c3e2f994bc2 Parents: 93ccc73 Author: Ken Giusti <[email protected]> Authored: Wed Apr 22 15:13:01 2015 -0400 Committer: Ken Giusti <[email protected]> Committed: Wed Apr 22 15:13:01 2015 -0400 ---------------------------------------------------------------------- proton-c/bindings/python/cproton.i | 62 ++++++++++++++++-------- proton-c/bindings/python/proton/__init__.py | 33 ++++++++++--- proton-c/bindings/python/proton/handlers.py | 4 +- proton-c/bindings/python/proton/reactor.py | 6 ++- proton-c/bindings/python/proton/utils.py | 4 +- 5 files changed, 77 insertions(+), 32 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/efa1f684/proton-c/bindings/python/cproton.i ---------------------------------------------------------------------- diff --git a/proton-c/bindings/python/cproton.i b/proton-c/bindings/python/cproton.i index 70d6c42..5744a2d 100644 --- a/proton-c/bindings/python/cproton.i +++ b/proton-c/bindings/python/cproton.i @@ -38,6 +38,27 @@ %cstring_output_allocate_size(char **ALLOC_OUTPUT, size_t *ALLOC_SIZE, free(*$1)); %cstring_output_maxsize(char *OUTPUT, size_t MAX_OUTPUT_SIZE) +// Typemap for methods that return binary data: +// force the return type as binary - this is necessary for Python3 +%typemap(in,noblock=1,fragment=SWIG_AsVal_frag(size_t)) (char *BIN_OUT, size_t *BIN_SIZE) +(int res, size_t n, char *buff = 0, $*2_ltype size) { + res = SWIG_AsVal(size_t)($input, &n); + if (!SWIG_IsOK(res)) { + %argument_fail(res, "(char *BIN_OUT, size_t *BIN_SIZE)", $symname, $argnum); + } + buff= %new_array(n+1, char); + $1 = %static_cast(buff, $1_ltype); + size = %numeric_cast(n,$*2_ltype); + $2 = &size; +} +%typemap(freearg,noblock=1,match="in")(char *BIN_OUT, size_t *BIN_SIZE) { + if (buff$argnum) %delete_array(buff$argnum); +} +%typemap(argout,noblock=1) (char *BIN_OUT, size_t *BIN_SIZE) { + %append_output(PyBytes_FromStringAndSize($1,*$2)); +} + + // These are not used/needed in the python binding %ignore pn_message_get_id; %ignore pn_message_set_id; @@ -49,20 +70,21 @@ $1.start = NULL; $1.size = 0; } else { - $1.start = PyString_AsString($input); + $1.start = PyBytes_AsString($input); + if (!$1.start) { return NULL; } - $1.size = PyString_Size($input); + $1.size = PyBytes_Size($input); } } %typemap(out) pn_bytes_t { - $result = PyString_FromStringAndSize($1.start, $1.size); + $result = PyBytes_FromStringAndSize($1.start, $1.size); } %typemap(out) pn_delivery_tag_t { - $result = PyString_FromStringAndSize($1.bytes, $1.size); + $result = PyBytes_FromStringAndSize($1.bytes, $1.size); } %typemap(in) pn_uuid_t { @@ -70,9 +92,9 @@ if ($input == Py_None) { ; // Already zeroed out } else { - const char* b = PyString_AsString($input); + const char* b = PyBytes_AsString($input); if (b) { - memmove($1.bytes, b, (PyString_Size($input) < 16 ? PyString_Size($input) : 16)); + memmove($1.bytes, b, (PyBytes_Size($input) < 16 ? PyBytes_Size($input) : 16)); } else { return NULL; } @@ -80,12 +102,12 @@ } %typemap(out) pn_uuid_t { - $result = PyString_FromStringAndSize($1.bytes, 16); + $result = PyBytes_FromStringAndSize($1.bytes, 16); } %apply pn_uuid_t { pn_decimal128_t }; -int pn_message_encode(pn_message_t *msg, char *OUTPUT, size_t *OUTPUT_SIZE); +int pn_message_encode(pn_message_t *msg, char *BIN_OUT, size_t *BIN_SIZE); %ignore pn_message_encode; ssize_t pn_link_send(pn_link_t *transport, char *STRING, size_t LENGTH); @@ -93,12 +115,12 @@ ssize_t pn_link_send(pn_link_t *transport, char *STRING, size_t LENGTH); %rename(pn_link_recv) wrap_pn_link_recv; %inline %{ - int wrap_pn_link_recv(pn_link_t *link, char *OUTPUT, size_t *OUTPUT_SIZE) { - ssize_t sz = pn_link_recv(link, OUTPUT, *OUTPUT_SIZE); + int wrap_pn_link_recv(pn_link_t *link, char *BIN_OUT, size_t *BIN_SIZE) { + ssize_t sz = pn_link_recv(link, BIN_OUT, *BIN_SIZE); if (sz >= 0) { - *OUTPUT_SIZE = sz; + *BIN_SIZE = sz; } else { - *OUTPUT_SIZE = 0; + *BIN_SIZE = 0; } return sz; } @@ -110,12 +132,12 @@ ssize_t pn_transport_push(pn_transport_t *transport, char *STRING, size_t LENGTH %rename(pn_transport_peek) wrap_pn_transport_peek; %inline %{ - int wrap_pn_transport_peek(pn_transport_t *transport, char *OUTPUT, size_t *OUTPUT_SIZE) { - ssize_t sz = pn_transport_peek(transport, OUTPUT, *OUTPUT_SIZE); + int wrap_pn_transport_peek(pn_transport_t *transport, char *BIN_OUT, size_t *BIN_SIZE) { + ssize_t sz = pn_transport_peek(transport, BIN_OUT, *BIN_SIZE); if (sz >= 0) { - *OUTPUT_SIZE = sz; + *BIN_SIZE = sz; } else { - *OUTPUT_SIZE = 0; + *BIN_SIZE = 0; } return sz; } @@ -146,12 +168,12 @@ ssize_t pn_data_decode(pn_data_t *data, char *STRING, size_t LENGTH); %rename(pn_data_encode) wrap_pn_data_encode; %inline %{ - int wrap_pn_data_encode(pn_data_t *data, char *OUTPUT, size_t *OUTPUT_SIZE) { - ssize_t sz = pn_data_encode(data, OUTPUT, *OUTPUT_SIZE); + int wrap_pn_data_encode(pn_data_t *data, char *BIN_OUT, size_t *BIN_SIZE) { + ssize_t sz = pn_data_encode(data, BIN_OUT, *BIN_SIZE); if (sz >= 0) { - *OUTPUT_SIZE = sz; + *BIN_SIZE = sz; } else { - *OUTPUT_SIZE = 0; + *BIN_SIZE = 0; } return sz; } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/efa1f684/proton-c/bindings/python/proton/__init__.py ---------------------------------------------------------------------- diff --git a/proton-c/bindings/python/proton/__init__.py b/proton-c/bindings/python/proton/__init__.py index cf73a53..8871eda 100644 --- a/proton-c/bindings/python/proton/__init__.py +++ b/proton-c/bindings/python/proton/__init__.py @@ -34,7 +34,9 @@ from __future__ import absolute_import from cproton import * from .wrapper import Wrapper +import six import weakref, socket, sys, threading + try: import uuid @@ -94,10 +96,22 @@ except ImportError: def generate_uuid(): return uuid4() +# +# Hacks to provide Python2 <---> Python3 compatibility +# try: bytes() except NameError: bytes = str +try: + long() +except NameError: + long = int +try: + unicode() +except NameError: + unicode = str + VERSION_MAJOR = PN_VERSION_MAJOR VERSION_MINOR = PN_VERSION_MINOR @@ -936,7 +950,7 @@ The number of delivery attempts made for this message. def _get_id(self): return self._id.get_object() def _set_id(self, value): - if type(value) in (int, long): + if type(value) in six.integer_types: value = ulong(value) self._id.rewind() self._id.put_object(value) @@ -992,7 +1006,7 @@ The reply-to address for the message. def _get_correlation_id(self): return self._correlation_id.get_object() def _set_correlation_id(self, value): - if type(value) in (int, long): + if type(value) in six.integer_types: value = ulong(value) self._correlation_id.rewind() self._correlation_id.put_object(value) @@ -1424,7 +1438,7 @@ class Data: def type_name(type): return Data.type_names[type] def __init__(self, capacity=16): - if type(capacity) in (int, long): + if type(capacity) in six.integer_types: self._data = pn_data(capacity) self._free = True else: @@ -2146,7 +2160,6 @@ class Data: symbol: put_symbol, int: put_long, char: put_char, - long: put_long, ulong: put_ulong, timestamp: put_timestamp, float: put_double, @@ -2154,6 +2167,10 @@ class Data: Described: put_py_described, Array: put_py_array } + # for python 2.x: + if long not in put_mappings: + put_mappings[long] = put_long + get_mappings = { NULL: lambda s: None, BOOL: get_bool, @@ -2319,7 +2336,7 @@ def millis2timeout(millis): def unicode2utf8(string): if string is None: return None - if isinstance(string, unicode): + if isinstance(string, six.text_type): return string.encode('utf8') elif isinstance(string, str): return string @@ -2329,7 +2346,7 @@ def unicode2utf8(string): def utf82unicode(string): if string is None: return None - if isinstance(string, unicode): + if isinstance(string, six.text_type): return string elif isinstance(string, str): return string.decode('utf8') @@ -3733,7 +3750,7 @@ class _cadapter: def exception(self, exc, val, tb): if self.on_error is None: - raise exc, val, tb + six.reraise(exc, val, tb) else: self.on_error((exc, val, tb)) @@ -3754,7 +3771,7 @@ class WrappedHandler(Wrapper): def _on_error(self, info): on_error = getattr(self, "on_error", None) if on_error is None: - raise info[0], info[1], info[2] + six.reraise(info[0], info[1], info[2]) else: on_error(info) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/efa1f684/proton-c/bindings/python/proton/handlers.py ---------------------------------------------------------------------- diff --git a/proton-c/bindings/python/proton/handlers.py b/proton-c/bindings/python/proton/handlers.py index 6836788..8f00aa3 100644 --- a/proton-c/bindings/python/proton/handlers.py +++ b/proton-c/bindings/python/proton/handlers.py @@ -16,7 +16,9 @@ # specific language governing permissions and limitations # under the License. # -import heapq, logging, os, Queue, re, socket, time, types +import heapq, logging, os, re, socket, time, types +from six.moves import queue as Queue + from proton import dispatch, generate_uuid, PN_ACCEPTED, SASL, symbol, ulong, Url from proton import Collector, Connection, Delivery, Described, Endpoint, Event, Link, Terminus, Timeout from proton import Message, Handler, ProtonException, Transport, TransportException, ConnectionException http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/efa1f684/proton-c/bindings/python/proton/reactor.py ---------------------------------------------------------------------- diff --git a/proton-c/bindings/python/proton/reactor.py b/proton-c/bindings/python/proton/reactor.py index 03d8af3..a9bd3cc 100644 --- a/proton-c/bindings/python/proton/reactor.py +++ b/proton-c/bindings/python/proton/reactor.py @@ -17,7 +17,9 @@ from __future__ import absolute_import # specific language governing permissions and limitations # under the License. # -import logging, os, Queue, socket, time, types +import logging, os, socket, time, types +import six +from six.moves import queue as Queue from heapq import heappush, heappop, nsmallest from proton import Collector, Connection, ConnectionException, Delivery, Described, dispatch from proton import Endpoint, Event, EventBase, EventType, generate_uuid, Handler, Link, Message @@ -137,7 +139,7 @@ class Reactor(Wrapper): for exc, value, tb in self.errors[:-1]: traceback.print_exception(exc, value, tb) exc, value, tb = self.errors[-1] - raise exc, value, tb + six.reraise(exc, value, tb) def process(self): result = pn_reactor_process(self._impl) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/efa1f684/proton-c/bindings/python/proton/utils.py ---------------------------------------------------------------------- diff --git a/proton-c/bindings/python/proton/utils.py b/proton-c/bindings/python/proton/utils.py index cb65fda..0d7f39e 100644 --- a/proton-c/bindings/python/proton/utils.py +++ b/proton-c/bindings/python/proton/utils.py @@ -16,7 +16,9 @@ # specific language governing permissions and limitations # under the License. # -import collections, Queue, socket, time, threading +import collections, socket, time, threading +from six.moves import queue as Queue + from proton import ConnectionException, Delivery, Endpoint, Handler, LinkException, Message from proton import ProtonException, Timeout, Url from proton.reactor import Container --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
