Fix: bt2: remove circular import (not supported before Python 3.5)
This fixes the bindings failing to load with a circular import error on
SLES12 with Python 3.4:
Traceback (most recent call last):
File "/usr/lib64/python3.4/unittest/loader.py", line 323, in _find_tests
module = self._get_module_from_name(name)
File "/usr/lib64/python3.4/unittest/loader.py", line 301, in _get_module_from_name
__import__(name)
File "/home/mjeanson/Git/babeltrace/tests/bindings/python/bt2/test_clock_class.py", line 22, in <module>
import bt2
File "/home/mjeanson/Git/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/__init__.py", line 26, in <module>
from bt2.clock_class import *
File "/home/mjeanson/Git/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/clock_class.py", line 23, in <module>
from bt2 import native_bt, object, utils
File "/home/mjeanson/Git/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/utils.py", line 24, in <module>
import bt2.logging
File "/home/mjeanson/Git/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/logging.py", line 23, in <module>
from bt2 import native_bt, object, utils
ImportError: cannot import name 'utils'
Jonathan Rajotte investigated why this happens with Python 3.4:
This is due to a circular import. utils import logging, logging import
utils.
The proposed solution is valid.
PDB callstack leading to error:
-> tests = loader.discover(start_dir, pattern)
/usr/lib64/python3.4/unittest/loader.py(275)discover()
-> tests = list(self._find_tests(start_dir, pattern))
/usr/lib64/python3.4/unittest/loader.py(323)_find_tests()
-> module = self._get_module_from_name(name)
/usr/lib64/python3.4/unittest/loader.py(301)_get_module_from_name()
-> __import__(name)
<frozen importlib._bootstrap>(2237)_find_and_load()
<frozen importlib._bootstrap>(2226)_find_and_load_unlocked()
<frozen importlib._bootstrap>(1200)_load_unlocked()
<frozen importlib._bootstrap>(1129)_exec()
<frozen importlib._bootstrap>(1471)exec_module()
<frozen importlib._bootstrap>(321)_call_with_frames_removed()
/home/jenkins/babeltrace/tests/plugins/src.ctf.fs/query/test_query_trace_info.py(21)<module>()
-> import bt2
<frozen importlib._bootstrap>(2237)_find_and_load()
<frozen importlib._bootstrap>(2226)_find_and_load_unlocked()
<frozen importlib._bootstrap>(1200)_load_unlocked()
<frozen importlib._bootstrap>(1129)_exec()
<frozen importlib._bootstrap>(1471)exec_module()
<frozen importlib._bootstrap>(321)_call_with_frames_removed()
/home/jenkins/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/__init__.py(26)<module>()
-> from bt2.clock_class import *
<frozen importlib._bootstrap>(2237)_find_and_load()
<frozen importlib._bootstrap>(2226)_find_and_load_unlocked()
<frozen importlib._bootstrap>(1200)_load_unlocked()
<frozen importlib._bootstrap>(1129)_exec()
<frozen importlib._bootstrap>(1471)exec_module()
<frozen importlib._bootstrap>(321)_call_with_frames_removed()
/home/jenkins/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/clock_class.py(23)<module>()
-> from bt2 import native_bt, object, utils
<frozen importlib._bootstrap>(2284)_handle_fromlist()
<frozen importlib._bootstrap>(321)_call_with_frames_removed()
<frozen importlib._bootstrap>(2237)_find_and_load()
<frozen importlib._bootstrap>(2226)_find_and_load_unlocked()
<frozen importlib._bootstrap>(1200)_load_unlocked()
<frozen importlib._bootstrap>(1129)_exec()
<frozen importlib._bootstrap>(1471)exec_module()
<frozen importlib._bootstrap>(321)_call_with_frames_removed()
/home/jenkins/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/utils.py(24)<module>()
-> import bt2.logging
<frozen importlib._bootstrap>(2237)_find_and_load()
<frozen importlib._bootstrap>(2226)_find_and_load_unlocked()
<frozen importlib._bootstrap>(1200)_load_unlocked()
<frozen importlib._bootstrap>(1129)_exec()
<frozen importlib._bootstrap>(1471)exec_module()
<frozen importlib._bootstrap>(321)_call_with_frames_removed()
> /home/jenkins/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/logging.py(23)<module>()
-> from bt2 import native_bt, object, utils
This can be reproduce easily on python 3.4.6 using pyenv and the following reproducer:
(my-virtual-env-3.4.6) joraj@/tmp/test[]$ tree
.
├── reprod
│ ├── __init__.py
│ ├── pkg1.py
│ ├── pkg2.py
│ └── start.py
└── test.py
test.py:
import reprod
print("got here")
__init__.py:
__version__= '1.0.0'
from reprod.start import *
pkg1.py:
from reprod import pkg2
pkg2.py:
from reprod import pkg1
start.py:
from reprod import pkg1
Using Python 3.4.6:
(my-virtual-env-3.4.6) joraj@/tmp/test[]$ python --version
Python 3.4.6
(my-virtual-env-3.4.6) joraj@/tmp/test[]$ python test.py
Traceback (most recent call last):
File "test.py", line 1, in <module>
import reprod
File "/tmp/test/reprod/__init__.py", line 3, in <module>
from reprod.start import *
File "/tmp/test/reprod/start.py", line 1, in <module>
from reprod import pkg1
File "/tmp/test/reprod/pkg1.py", line 1, in <module>
from reprod import pkg2
File "/tmp/test/reprod/pkg2.py", line 1, in <module>
from reprod import pkg1
ImportError: cannot import name 'pkg1'
(my-virtual-env-3.4.6) joraj@/tmp/test[]$
The same reproducer run with python 3.5.6 works fine (again using pyenv):
(my-virtual-env-3.5.6) joraj@/tmp/test[]$ python --version
Python 3.5.6
(my-virtual-env-3.5.6) joraj@/tmp/test[]$ python test.py
got here
(my-virtual-env-3.5.6) joraj@/tmp/test[]$
This is mostly due to the work done regarding circular dependency import
involving relative import[1][2].
[1] https://docs.python.org/3.5/whatsnew/3.5.html#other-language-changes
[2] https://bugs.python.org/issue17636
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Change-Id: If43a6f9fad3d2b082fcd912f9ff6c193537d9f77
This page took 0.032493 seconds and 4 git commands to generate.