diff --git a/Lib/test/test_import.py b/Lib/test/test_import/__init__.py rename from Lib/test/test_import.py rename to Lib/test/test_import/__init__.py --- a/Lib/test/test_import.py +++ b/Lib/test/test_import/__init__.py @@ -568,7 +568,7 @@ class RelativeImportTests(unittest.TestC def test_relimport_star(self): # This will import * from .test_import. - from . import relimport + from .. import relimport self.assertTrue(hasattr(relimport, "RelativeImportTests")) def test_issue3221(self): @@ -1067,6 +1067,46 @@ class ImportTracebackTests(unittest.Test __isolated=False) +class CircularImportTests(unittest.TestCase): + + """See the docstrings of the modules being imported for the purpose of the + test.""" + + def tearDown(self): + """Make sure no modules pre-exist in sys.modules which are being used to + test.""" + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.circular_imports.'): + del sys.modules[key] + + def test_direct(self): + try: + import test.test_import.data.circular_imports.basic + except ImportError: + self.fail('circular import through relative imports failed') + + def test_indirect(self): + try: + import test.test_import.data.circular_imports.indirect + except ImportError: + self.fail('relative import in module contributing to circular ' + 'import failed') + + def test_subpackage(self): + try: + import test.test_import.data.circular_imports.subpackage + except ImportError: + self.fail('circular import involving a subpackage failed') + + def test_rebinding(self): + try: + import test.test_import.data.circular_imports.rebinding as rebinding + except ImportError: + self.fail('circular import with rebinding of module attribute failed') + from test.test_import.data.circular_imports.subpkg import util + self.assertIs(util.util, rebinding.util) + + if __name__ == '__main__': # Test needs to be a package, so we can do relative imports. unittest.main() diff --git a/Lib/test/test_import/__main__.py b/Lib/test/test_import/__main__.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_import/__main__.py @@ -0,0 +1,3 @@ +import unittest + +unittest.main('test.test_import') \ No newline at end of file diff --git a/Lib/test/test_import/data/circular_imports/basic.py b/Lib/test/test_import/data/circular_imports/basic.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/basic.py @@ -0,0 +1,2 @@ +"""Circular imports through direct, relative imports.""" +from . import basic2 diff --git a/Lib/test/test_import/data/circular_imports/basic2.py b/Lib/test/test_import/data/circular_imports/basic2.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/basic2.py @@ -0,0 +1,1 @@ +from . import basic diff --git a/Lib/test/test_import/data/circular_imports/rebinding.py b/Lib/test/test_import/data/circular_imports/rebinding.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/rebinding.py @@ -0,0 +1,3 @@ +"""Test the binding of names when a circular import shares the same name as an +attribute.""" +from .rebinding2 import util \ No newline at end of file diff --git a/Lib/test/test_import/data/circular_imports/rebinding2.py b/Lib/test/test_import/data/circular_imports/rebinding2.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/rebinding2.py @@ -0,0 +1,3 @@ +from .subpkg import util +from . import rebinding +util = util.util \ No newline at end of file diff --git a/Lib/test/test_import/data/circular_imports/subpackage.py b/Lib/test/test_import/data/circular_imports/subpackage.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/subpackage.py @@ -0,0 +1,2 @@ +"""Circular import involving a sub-package.""" +from .subpkg import subpackage2 \ No newline at end of file diff --git a/Lib/test/test_import/data/circular_imports/subpkg/subpackage2.py b/Lib/test/test_import/data/circular_imports/subpkg/subpackage2.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/subpkg/subpackage2.py @@ -0,0 +1,2 @@ +#from .util import util +from .. import subpackage \ No newline at end of file diff --git a/Lib/test/test_import/data/circular_imports/subpkg/util.py b/Lib/test/test_import/data/circular_imports/subpkg/util.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/subpkg/util.py @@ -0,0 +1,2 @@ +def util(): + pass \ No newline at end of file diff --git a/Lib/test/test_import/data/circular_imports/util.py b/Lib/test/test_import/data/circular_imports/util.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/util.py @@ -0,0 +1,2 @@ +def util(): + pass \ No newline at end of file