bt2: make it work for Python 3.4
authorSimon Marchi <simon.marchi@efficios.com>
Mon, 23 Sep 2019 19:21:41 +0000 (15:21 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Wed, 25 Sep 2019 15:22:58 +0000 (11:22 -0400)
commit7993562851b443afb3801e5bf2b88d674734808b
treee594e7054ee882838cda2bb22f3576c1462b83c8
parent602d20a206a92e112d10baf84cb5163241a390f7
bt2: make it work for Python 3.4

The import system from Python 3.4 has some significant differences
compared to the one from Python 3.5 and later.  Notably, support for
circular references (which we use) was added in the later versions.

For example, trace.py and stream.py both import each other.  Trace
objects need Stream objects when listing streams in a trace, and Stream
objects need Trace objects when getting the containing trace of a
stream.

To make it work on Python 3.4, I think we need to break any circular
import chain that happen when "import bt2" is done.  It is fine to
import things later, once all the modules have been initialized.

To achieve this, I changed some

  from bt2 import foo as bt2_foo

to

  def _get_bt2_foo():
      from bt2 import foo as bt2_foo
      return bt2_foo

The users of bt2_foo in that file now need to use _get_bt2_foo() instead
of bt2_foo.  it is important that _get_bt2_foo doesn't get called during
the import of the module, otherwise, we come back to the initial
problem.  So in some cases, I have wrapped some calls to _get_bt2_foo in
properties, as was already done to break circular dependencies between
classes.

This is not enough though, as there is another behavior difference
between 3.4 and 3.5+, which I believe is also a consequence of the
circular import changes [1].  It is also related to the fact that we
delete submodule attributes from the bt2 module in our __init__.py.

With 3.5, it is still possible to do:

    from bt2 import value

after we've deleted the `value` attribute from bt2.  With Python 3.4, it
doesn't work.  I believe it is related to [1] in that Python 3.5+, when
processing a "from" import, searches in sys.modules if a simple getattr
on the module failed.

This is problematic for us, since we need the 'from bt2 import "foo"'
lines to work after the bt2 attributes have been deleted (to support the
changes described above).  The solution I've found is to not delete the
bt2 submodule attributes when using Python 3.4.

We delete those attributes simply to clean up the bt2 namespace and to
avoid exposing the internal organisation of the code.  I think it's
an acceptable trade-off to not do it when using Python 3.4, if it means
that it will actually work.

[1] https://bugs.python.org/issue17636

Change-Id: Ia6810972492a058f60c21e6f22afd43962f4f7a2
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/2082
Tested-by: jenkins <jenkins@lttng.org>
src/bindings/python/bt2/bt2/__init__.py
src/bindings/python/bt2/bt2/event_class.py
src/bindings/python/bt2/bt2/packet.py
src/bindings/python/bt2/bt2/port.py
src/bindings/python/bt2/bt2/query_executor.py
src/bindings/python/bt2/bt2/stream.py
src/bindings/python/bt2/bt2/stream_class.py
src/bindings/python/bt2/bt2/trace.py
This page took 0.026457 seconds and 4 git commands to generate.