From: Jérémie Galarneau Date: Tue, 27 Oct 2015 20:10:03 +0000 (-0400) Subject: Python bindings: work around Python 3.5 behaviour change X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=1fa8e2371b9b7cb256cd6da67ad3326cb784ff00;p=deliverable%2Fbabeltrace.git 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/nativebt.i b/bindings/python/nativebt.i index daab4da4b..ac1f8586f 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 35ca33dcc..a962b8046 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 d6f3321f1..c243160c7 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 675804359..354403362 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): """