From 1fa8e2371b9b7cb256cd6da67ad3326cb784ff00 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Tue, 27 Oct 2015 16:10:03 -0400 Subject: [PATCH] Python bindings: work around Python 3.5 behaviour change MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- bindings/python/nativebt.i | 2 +- bindings/python/python-complements.c | 13 +++++++++++++ bindings/python/python-complements.h | 3 +++ bindings/python/reader.py | 14 ++++++++++---- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/bindings/python/nativebt.i b/bindings/python/nativebt.i index daab4da4..ac1f8586 100644 --- a/bindings/python/nativebt.i +++ b/bindings/python/nativebt.i @@ -112,7 +112,7 @@ int _bt_python_ctf_clock_get_uuid_index(struct bt_ctf_clock *clock, size_t index, unsigned char *OUTPUT); int _bt_python_ctf_clock_set_uuid_index(struct bt_ctf_clock *clock, size_t index, unsigned char value); - +struct bt_iter_pos *_bt_python_create_iter_pos(void); /* context.h, context-internal.h */ %rename("_bt_context_create") bt_context_create(void); diff --git a/bindings/python/python-complements.c b/bindings/python/python-complements.c index 35ca33dc..a962b804 100644 --- a/bindings/python/python-complements.c +++ b/bindings/python/python-complements.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include /* List-related functions ---------------------------------------------------- @@ -386,3 +388,14 @@ int _bt_python_ctf_clock_set_uuid_index(struct bt_ctf_clock *clock, end: return ret; } + +/* + * 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 d6f3321f..c243160c 100644 --- a/bindings/python/python-complements.h +++ b/bindings/python/python-complements.h @@ -97,3 +97,6 @@ int _bt_python_ctf_clock_get_uuid_index(struct bt_ctf_clock *clock, size_t index, unsigned char *value); int _bt_python_ctf_clock_set_uuid_index(struct bt_ctf_clock *clock, size_t index, unsigned char value); + +/* iterator */ +struct bt_iter_pos *_bt_python_create_iter_pos(void); diff --git a/bindings/python/reader.py b/bindings/python/reader.py index 67580435..35440336 100644 --- a/bindings/python/reader.py +++ b/bindings/python/reader.py @@ -145,14 +145,17 @@ class TraceCollection: they need *from* an event before accessing the next one. """ - begin_pos_ptr = nbt._bt_iter_pos() - end_pos_ptr = nbt._bt_iter_pos() + begin_pos_ptr = nbt._bt_python_create_iter_pos() + end_pos_ptr = nbt._bt_python_create_iter_pos() begin_pos_ptr.type = nbt.SEEK_BEGIN end_pos_ptr.type = nbt.SEEK_LAST for event in self._events(begin_pos_ptr, end_pos_ptr): yield event + nbt._bt_iter_free_pos(begin_pos_ptr); + nbt._bt_iter_free_pos(end_pos_ptr); + def events_timestamps(self, timestamp_begin, timestamp_end): """ Generates the ordered :class:`Event` objects of all the opened @@ -165,8 +168,8 @@ class TraceCollection: See :attr:`events` for notes and limitations. """ - begin_pos_ptr = nbt._bt_iter_pos() - end_pos_ptr = nbt._bt_iter_pos() + begin_pos_ptr = nbt._bt_python_create_iter_pos() + end_pos_ptr = nbt._bt_python_create_iter_pos() begin_pos_ptr.type = end_pos_ptr.type = nbt.SEEK_TIME begin_pos_ptr.u.seek_time = timestamp_begin end_pos_ptr.u.seek_time = timestamp_end @@ -174,6 +177,9 @@ class TraceCollection: for event in self._events(begin_pos_ptr, end_pos_ptr): yield event + nbt._bt_iter_free_pos(begin_pos_ptr); + nbt._bt_iter_free_pos(end_pos_ptr); + @property def timestamp_begin(self): """ -- 2.34.1