Python bindings: work around Python 3.5 behaviour change
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 27 Oct 2015 20:10:03 +0000 (16:10 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 27 Oct 2015 20:12:09 +0000 (16:12 -0400)
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 <jeremie.galarneau@efficios.com>
bindings/python/nativebt.i
bindings/python/python-complements.c
bindings/python/python-complements.h
bindings/python/reader.py

index daab4da4b39fef787f00d917e1d8c1dcfbd69d82..ac1f8586fdd6652cb695e80bfd5bb73a85393ce1 100644 (file)
@@ -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);
index 35ca33dcc40a422a838944719e97f9b94b28b083..a962b804618df05dc8ff6d1ceb7bc46bb9037d94 100644 (file)
@@ -31,6 +31,8 @@
 #include <babeltrace/ctf-ir/event-types.h>
 #include <babeltrace/ctf-ir/event.h>
 #include <babeltrace/ctf-ir/clock-internal.h>
+#include <babeltrace/iterator.h>
+#include <glib.h>
 
 /* 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);
+}
index d6f3321f17d68d5a3d96041fca37728e5219ca50..c243160c72154488aeba7ebaa62b0d29be512f08 100644 (file)
@@ -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);
index 6758043599276d3c535708cd08054f034e22895f..354403362d534d363e9f2fb73b21c129bd466ad2 100644 (file)
@@ -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):
         """
This page took 0.02785 seconds and 4 git commands to generate.