From: Michael Jeanson Date: Thu, 11 Jul 2019 21:26:22 +0000 (-0400) Subject: Fix: bt2: remove circular import (not supported before Python 3.5) X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=493d384f2d4f0f5a91da04495420dfd35de06440 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 import bt2 File "/home/mjeanson/Git/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/__init__.py", line 26, in from bt2.clock_class import * File "/home/mjeanson/Git/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/clock_class.py", line 23, in 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 import bt2.logging File "/home/mjeanson/Git/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/logging.py", line 23, in 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) (2237)_find_and_load() (2226)_find_and_load_unlocked() (1200)_load_unlocked() (1129)_exec() (1471)exec_module() (321)_call_with_frames_removed() /home/jenkins/babeltrace/tests/plugins/src.ctf.fs/query/test_query_trace_info.py(21)() -> import bt2 (2237)_find_and_load() (2226)_find_and_load_unlocked() (1200)_load_unlocked() (1129)_exec() (1471)exec_module() (321)_call_with_frames_removed() /home/jenkins/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/__init__.py(26)() -> from bt2.clock_class import * (2237)_find_and_load() (2226)_find_and_load_unlocked() (1200)_load_unlocked() (1129)_exec() (1471)exec_module() (321)_call_with_frames_removed() /home/jenkins/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/clock_class.py(23)() -> from bt2 import native_bt, object, utils (2284)_handle_fromlist() (321)_call_with_frames_removed() (2237)_find_and_load() (2226)_find_and_load_unlocked() (1200)_load_unlocked() (1129)_exec() (1471)exec_module() (321)_call_with_frames_removed() /home/jenkins/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/utils.py(24)() -> import bt2.logging (2237)_find_and_load() (2226)_find_and_load_unlocked() (1200)_load_unlocked() (1129)_exec() (1471)exec_module() (321)_call_with_frames_removed() > /home/jenkins/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/logging.py(23)() -> 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 import reprod File "/tmp/test/reprod/__init__.py", line 3, in from reprod.start import * File "/tmp/test/reprod/start.py", line 1, in from reprod import pkg1 File "/tmp/test/reprod/pkg1.py", line 1, in from reprod import pkg2 File "/tmp/test/reprod/pkg2.py", line 1, in 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 Change-Id: If43a6f9fad3d2b082fcd912f9ff6c193537d9f77 --- diff --git a/src/bindings/python/bt2/bt2/logging.py b/src/bindings/python/bt2/bt2/logging.py index f07e8ea6..5b9929b1 100644 --- a/src/bindings/python/bt2/bt2/logging.py +++ b/src/bindings/python/bt2/bt2/logging.py @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from bt2 import native_bt, object, utils +from bt2 import native_bt import bt2