From: Jérémie Galarneau Date: Mon, 29 Feb 2016 20:08:15 +0000 (-0500) Subject: Python bindings: work around Python 3.5 behaviour change X-Git-Tag: v1.3.2~1 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=9132dc67804f7e868c21f759bf739ace4ce069b6 Python bindings: work around Python 3.5 behaviour change Python 3.5 changes the StopIteration exception clearing behaviour when a generator finishes its iteration. This causes the interpreter to errounously consider SWIG clean-up functions as having "set an error". This hack explicitly allocates and cleans up struct bt_iter_pos instead of relying on SWIG auto-generated code which manages the lifetime of temporary objects. An investigation of the cause of this change is under way, but at least this makes the bindings usable on Python 3.5 which is being rolled-out in some distros. Signed-off-by: Jérémie Galarneau --- diff --git a/bindings/python/babeltrace.i.in b/bindings/python/babeltrace.i.in index 5142952e..f07f2fb7 100644 --- a/bindings/python/babeltrace.i.in +++ b/bindings/python/babeltrace.i.in @@ -99,6 +99,7 @@ const char *_bt_python_get_array_string(struct bt_definition *field); const char *_bt_python_get_sequence_string(struct bt_definition *field); int _bt_python_field_integer_get_signedness(const struct bt_ctf_field *field); enum ctf_type_id _bt_python_get_field_type(const struct bt_ctf_field *field); +struct bt_iter_pos *_bt_python_create_iter_pos(void); /* ================================================================= CONTEXT.H, CONTEXT-INTERNAL.H @@ -223,21 +224,24 @@ class TraceCollection: event after the the generator has gone out of scope may result in a crash or data corruption. """ - begin_pos_ptr = _bt_iter_pos() - end_pos_ptr = _bt_iter_pos() + begin_pos_ptr = _bt_python_create_iter_pos() + end_pos_ptr = _bt_python_create_iter_pos() begin_pos_ptr.type = SEEK_BEGIN end_pos_ptr.type = SEEK_LAST for event in self._events(begin_pos_ptr, end_pos_ptr): yield event + _bt_iter_free_pos(begin_pos_ptr) + _bt_iter_free_pos(end_pos_ptr) + def events_timestamps(self, timestamp_begin, timestamp_end): """ Generator function to iterate over the events of open in the current TraceCollection from timestamp_begin to timestamp_end. """ - begin_pos_ptr = _bt_iter_pos() - end_pos_ptr = _bt_iter_pos() + begin_pos_ptr = _bt_python_create_iter_pos() + end_pos_ptr = _bt_python_create_iter_pos() begin_pos_ptr.type = end_pos_ptr.type = SEEK_TIME begin_pos_ptr.u.seek_time = timestamp_begin end_pos_ptr.u.seek_time = timestamp_end @@ -245,6 +249,9 @@ class TraceCollection: for event in self._events(begin_pos_ptr, end_pos_ptr): yield event + _bt_iter_free_pos(begin_pos_ptr) + _bt_iter_free_pos(end_pos_ptr) + @property def timestamp_begin(self): pos_ptr = _bt_iter_pos() diff --git a/bindings/python/python-complements.c b/bindings/python/python-complements.c index 6f947bd0..52465aa2 100644 --- a/bindings/python/python-complements.c +++ b/bindings/python/python-complements.c @@ -21,6 +21,8 @@ #include "python-complements.h" #include #include +#include +#include /* FILE functions ---------------------------------------------------- @@ -236,3 +238,14 @@ enum ctf_type_id _bt_python_get_field_type(const struct bt_ctf_field *field) end: return type_id; } + +/* + * Python 3.5 changes the StopIteration exception clearing behaviour which + * erroneously marks swig clean-up function as having failed. This explicit + * allocation function is intended as a work-around so SWIG doesn't manage + * the lifetime of a "temporary" object by itself. + */ +struct bt_iter_pos *_bt_python_create_iter_pos(void) +{ + return g_new0(struct bt_iter_pos, 1); +} diff --git a/bindings/python/python-complements.h b/bindings/python/python-complements.h index 0e38e6b2..bd225980 100644 --- a/bindings/python/python-complements.h +++ b/bindings/python/python-complements.h @@ -71,3 +71,6 @@ const char *_bt_python_get_sequence_string(struct bt_definition *field); /* ctf writer */ int _bt_python_field_integer_get_signedness(const struct bt_ctf_field *field); enum ctf_type_id _bt_python_get_field_type(const struct bt_ctf_field *field); + +/* iterator */ +struct bt_iter_pos *_bt_python_create_iter_pos(void);