From 4dd8c769d326c0ad401c39bc1be89e15f0b40327 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 23 Apr 2017 17:45:11 +0300 Subject: [PATCH] bpo-30024: Circular imports involving absolute imports with binding a submodule to a name are now supported. --- Doc/whatsnew/3.7.rst | 4 ++++ Lib/test/test_import/__init__.py | 6 ++++++ Lib/test/test_import/data/circular_imports/binding.py | 1 + Lib/test/test_import/data/circular_imports/binding2.py | 1 + Misc/NEWS | 3 +++ Python/compile.c | 4 ++-- 6 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 Lib/test/test_import/data/circular_imports/binding.py create mode 100644 Lib/test/test_import/data/circular_imports/binding2.py diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 875fc556912cae..75b65e66737a17 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -85,6 +85,10 @@ Other Language Changes * :exc:`ImportError` now displays module name and module ``__file__`` path when ``from ... import ...`` fails. (Contributed by Matthias Bussonnier in :issue:`29546`.) +* Circular imports involving absolute imports with binding a submodule to + a name are now supported. + (Contributed by Serhiy Storchaka in :issue:`30024`.) + New Modules =========== diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index d4b44459292548..be17d6b7743f61 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -1168,6 +1168,12 @@ def test_rebinding(self): from test.test_import.data.circular_imports.subpkg import util self.assertIs(util.util, rebinding.util) + def test_binding(self): + try: + import test.test_import.data.circular_imports.binding + except ImportError: + self.fail('circular import with binding a submodule to a name failed') + if __name__ == '__main__': # Test needs to be a package, so we can do relative imports. diff --git a/Lib/test/test_import/data/circular_imports/binding.py b/Lib/test/test_import/data/circular_imports/binding.py new file mode 100644 index 00000000000000..1fbf929abb9043 --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/binding.py @@ -0,0 +1 @@ +import test.test_import.data.circular_imports.binding2 as binding2 diff --git a/Lib/test/test_import/data/circular_imports/binding2.py b/Lib/test/test_import/data/circular_imports/binding2.py new file mode 100644 index 00000000000000..3d6693769d4555 --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/binding2.py @@ -0,0 +1 @@ +import test.test_import.data.circular_imports.binding as binding diff --git a/Misc/NEWS b/Misc/NEWS index 651d17569bb796..f66b68eef84c30 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -317,6 +317,9 @@ Extension Modules Library ------- +- bpo-30024: Circular imports involving absolute imports with binding + a submodule to a name are now supported. + - bpo-29960: Preserve generator state when _random.Random.setstate() raises an exception. Patch by Bryan Olson. diff --git a/Python/compile.c b/Python/compile.c index b630863afc5084..dad7404a85f3f4 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2546,7 +2546,7 @@ compiler_import_as(struct compiler *c, identifier name, identifier asname) merely needs to bind the result to a name. If there is a dot in name, we need to split it and emit a - LOAD_ATTR for each name. + IMPORT_FROM for each name. */ Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, PyUnicode_GET_LENGTH(name), 1); @@ -2566,7 +2566,7 @@ compiler_import_as(struct compiler *c, identifier name, identifier asname) PyUnicode_GET_LENGTH(name)); if (!attr) return 0; - ADDOP_O(c, LOAD_ATTR, attr, names); + ADDOP_O(c, IMPORT_FROM, attr, names); Py_DECREF(attr); pos = dot + 1; }