PROTON-2430: Changed python binding to use pn_message_set/get_id/correlation_id
Stop using pn_message_id/pn_message_correlation_id which are inherently
ineefficient and should be deprecated.
Added in a SWIG typemap for pn_msgid_t that knows the types that are
necessary for msgid types.
diff --git a/python/cproton.i b/python/cproton.i
index 2a7bff9..f863cc7 100644
--- a/python/cproton.i
+++ b/python/cproton.i
@@ -96,10 +96,8 @@
// These are not used/needed in the python binding
%ignore pn_dtag;
-%ignore pn_message_get_id;
-%ignore pn_message_set_id;
-%ignore pn_message_get_correlation_id;
-%ignore pn_message_set_correlation_id;
+%ignore pn_message_id;
+%ignore pn_message_correlation_id;
%ignore pn_list;
%ignore pn_list_size;
@@ -163,6 +161,7 @@
$result = PyLong_FromVoidPtr((void*)$1);
}
+
%typemap(in) pn_bytes_t {
if ($input == Py_None) {
$1.start = NULL;
@@ -181,6 +180,81 @@
$result = PyBytes_FromStringAndSize($1.start, $1.size);
}
+%typemap(in) pn_msgid_t {
+ if (PyTuple_Check($input)) {
+ pn_type_t type = PyLong_AsUnsignedLong(PyTuple_GetItem($input, 0));
+ PyObject* obj = PyTuple_GetItem($input, 1);
+ switch (type) {
+ case PN_NULL:
+ break;
+ case PN_ULONG:
+ $1.u.as_ulong = PyLong_AsUnsignedLong(obj);
+ break;
+ case PN_UUID:
+ if (PyBytes_Check(obj)) {
+ memmove(&$1.u.as_uuid, PyBytes_AsString(obj), (PyBytes_Size(obj) < 16 ? PyBytes_Size(obj) : 16));
+ break;
+ }
+ type = PN_NULL;
+ break;
+ case PN_BINARY:
+ if (PyBytes_Check(obj)) {
+ $1.u.as_bytes = (pn_bytes_t){.size=PyBytes_Size(obj), .start=PyBytes_AsString(obj)};
+ break;
+ }
+ type = PN_NULL;
+ break;
+ case PN_STRING:
+ if (PyBytes_Check(obj)) {
+ $1.u.as_bytes = (pn_bytes_t){.size=PyBytes_Size(obj), .start=PyBytes_AsString(obj)};
+ break;
+ }
+ default:
+ type = PN_NULL;
+ break;
+ }
+ $1.type = type;
+ } else if (PyLong_Check($input)) {
+ $1.type = PN_ULONG;
+ $1.u.as_ulong = PyLong_AsUnsignedLong($input);
+ } else if (PyBytes_Check($input)) {
+ $1.type = PN_BINARY;
+ $1.u.as_bytes = (pn_bytes_t){.size=PyBytes_Size($input), .start=PyBytes_AsString($input)};
+ } else if (PyUnicode_Check($input)) {
+ $1.type = PN_STRING;
+ Py_ssize_t utf8size;
+ const char *utf8 = PyUnicode_AsUTF8AndSize($input, &utf8size);
+ $1.u.as_bytes = (pn_bytes_t){.size=utf8size, .start=utf8};
+ } else {
+ $1.type = PN_NULL;
+ }
+}
+
+%typemap(out) pn_msgid_t {
+ switch ($1.type) {
+ case PN_NULL:
+ $result = Py_None;
+ break;
+ case PN_ULONG:
+ $result = PyLong_FromUnsignedLong($1.u.as_ulong);
+ break;
+ case PN_BINARY:
+ $result = PyBytes_FromStringAndSize($1.u.as_bytes.start, $1.u.as_bytes.size);
+ break;
+ case PN_STRING:
+ $result = PyUnicode_FromStringAndSize($1.u.as_bytes.start, $1.u.as_bytes.size);
+ break;
+ case PN_UUID:
+ $result = PyTuple_New(2);
+ PyTuple_SetItem($result, 0, PyLong_FromUnsignedLong($1.type));
+ PyTuple_SetItem($result, 1, PyBytes_FromStringAndSize($1.u.as_uuid.bytes, 16));
+ break;
+ default:
+ $result = Py_None;
+ break;
+ }
+}
+
%typemap(out) pn_delivery_tag_t {
$result = PyBytes_FromStringAndSize($1.bytes, $1.size);
}
diff --git a/python/proton/_message.py b/python/proton/_message.py
index 6952c8a..cf0f7b9 100644
--- a/python/proton/_message.py
+++ b/python/proton/_message.py
@@ -19,17 +19,17 @@
from __future__ import absolute_import
-from cproton import PN_DEFAULT_PRIORITY, PN_OVERFLOW, pn_error_text, pn_message, \
- pn_message_annotations, pn_message_body, pn_message_clear, pn_message_correlation_id, pn_message_decode, \
+from cproton import PN_DEFAULT_PRIORITY, PN_STRING, PN_UUID, PN_OVERFLOW, pn_error_text, pn_message, \
+ pn_message_annotations, pn_message_body, pn_message_clear, pn_message_decode, \
pn_message_encode, pn_message_error, pn_message_free, pn_message_get_address, pn_message_get_content_encoding, \
- pn_message_get_content_type, pn_message_get_creation_time, pn_message_get_delivery_count, \
- pn_message_get_expiry_time, pn_message_get_group_id, pn_message_get_group_sequence, pn_message_get_priority, \
+ pn_message_get_content_type, pn_message_get_correlation_id, pn_message_get_creation_time, pn_message_get_delivery_count, \
+ pn_message_get_expiry_time, pn_message_get_group_id, pn_message_get_group_sequence, pn_message_get_id, pn_message_get_priority, \
pn_message_get_reply_to, pn_message_get_reply_to_group_id, pn_message_get_subject, pn_message_get_ttl, \
- pn_message_get_user_id, pn_message_id, pn_message_instructions, pn_message_is_durable, \
+ pn_message_get_user_id, pn_message_instructions, pn_message_is_durable, \
pn_message_is_first_acquirer, pn_message_is_inferred, pn_message_properties, pn_message_set_address, \
- pn_message_set_content_encoding, pn_message_set_content_type, pn_message_set_creation_time, \
+ pn_message_set_content_encoding, pn_message_set_content_type, pn_message_set_correlation_id, pn_message_set_creation_time, \
pn_message_set_delivery_count, pn_message_set_durable, pn_message_set_expiry_time, pn_message_set_first_acquirer, \
- pn_message_set_group_id, pn_message_set_group_sequence, pn_message_set_inferred, pn_message_set_priority, \
+ pn_message_set_group_id, pn_message_set_group_sequence, pn_message_set_id, pn_message_set_inferred, pn_message_set_priority, \
pn_message_set_reply_to, pn_message_set_reply_to_group_id, pn_message_set_subject, \
pn_message_set_ttl, pn_message_set_user_id
@@ -37,12 +37,12 @@
from ._data import char, Data, symbol, ulong, AnnotationDict
from ._endpoints import Link
from ._exceptions import EXCEPTIONS, MessageException
+from uuid import UUID
from typing import Dict, Optional, Union, TYPE_CHECKING, overload
if TYPE_CHECKING:
from proton._delivery import Delivery
from proton._endpoints import Sender, Receiver
- from uuid import UUID
from proton._data import Described, PythonAMQPData
@@ -69,8 +69,6 @@
**kwargs
) -> None:
self._msg = pn_message()
- self._id = Data(pn_message_id(self._msg))
- self._correlation_id = Data(pn_message_correlation_id(self._msg))
self.instructions = None
self.annotations = None
self.properties = None
@@ -273,14 +271,19 @@
* ``bytes``
* ``str``
"""
- return self._id.get_object()
+ value = pn_message_get_id(self._msg)
+ if isinstance(value, tuple):
+ if value[0] == PN_UUID:
+ value = UUID(bytes=value[1])
+ return value
@id.setter
def id(self, value: Optional[Union[str, bytes, 'UUID', int]]) -> None:
if isinteger(value):
value = ulong(value)
- self._id.rewind()
- self._id.put_object(value)
+ elif isinstance(value, UUID):
+ value = (PN_UUID, value.bytes)
+ pn_message_set_id(self._msg, value)
@property
def user_id(self) -> bytes:
@@ -341,14 +344,19 @@
* ``bytes``
* ``str``
"""
- return self._correlation_id.get_object()
+ value = pn_message_get_correlation_id(self._msg)
+ if isinstance(value, tuple):
+ if value[0] == PN_UUID:
+ value = UUID(bytes=value[1])
+ return value
@correlation_id.setter
def correlation_id(self, value: Optional[Union[str, bytes, 'UUID', int]]) -> None:
if isinteger(value):
value = ulong(value)
- self._correlation_id.rewind()
- self._correlation_id.put_object(value)
+ elif isinstance(value, UUID):
+ value = (PN_UUID, value.bytes)
+ pn_message_set_correlation_id(self._msg, value)
@property
def content_type(self) -> symbol: