1from test.test_importlib import util
2import sys
3import unittest
4from test import support
5from test.support import import_helper
6
7
8class ParentModuleTests:
9
10    """Importing a submodule should import the parent modules."""
11
12    def test_import_parent(self):
13        with util.mock_spec('pkg.__init__', 'pkg.module') as mock:
14            with util.import_state(meta_path=[mock]):
15                module = self.__import__('pkg.module')
16                self.assertIn('pkg', sys.modules)
17
18    def test_bad_parent(self):
19        with util.mock_spec('pkg.module') as mock:
20            with util.import_state(meta_path=[mock]):
21                with self.assertRaises(ImportError) as cm:
22                    self.__import__('pkg.module')
23                self.assertEqual(cm.exception.name, 'pkg')
24
25    def test_raising_parent_after_importing_child(self):
26        def __init__():
27            import pkg.module
28            1/0
29        mock = util.mock_spec('pkg.__init__', 'pkg.module',
30                                 module_code={'pkg': __init__})
31        with mock:
32            with util.import_state(meta_path=[mock]):
33                with self.assertRaises(ZeroDivisionError):
34                    self.__import__('pkg')
35                self.assertNotIn('pkg', sys.modules)
36                self.assertIn('pkg.module', sys.modules)
37                with self.assertRaises(ZeroDivisionError):
38                    self.__import__('pkg.module')
39                self.assertNotIn('pkg', sys.modules)
40                self.assertIn('pkg.module', sys.modules)
41
42    def test_raising_parent_after_relative_importing_child(self):
43        def __init__():
44            from . import module
45            1/0
46        mock = util.mock_spec('pkg.__init__', 'pkg.module',
47                                 module_code={'pkg': __init__})
48        with mock:
49            with util.import_state(meta_path=[mock]):
50                with self.assertRaises((ZeroDivisionError, ImportError)):
51                    # This raises ImportError on the "from . import module"
52                    # line, not sure why.
53                    self.__import__('pkg')
54                self.assertNotIn('pkg', sys.modules)
55                with self.assertRaises((ZeroDivisionError, ImportError)):
56                    self.__import__('pkg.module')
57                self.assertNotIn('pkg', sys.modules)
58                # XXX False
59                #self.assertIn('pkg.module', sys.modules)
60
61    def test_raising_parent_after_double_relative_importing_child(self):
62        def __init__():
63            from ..subpkg import module
64            1/0
65        mock = util.mock_spec('pkg.__init__', 'pkg.subpkg.__init__',
66                                 'pkg.subpkg.module',
67                                 module_code={'pkg.subpkg': __init__})
68        with mock:
69            with util.import_state(meta_path=[mock]):
70                with self.assertRaises((ZeroDivisionError, ImportError)):
71                    # This raises ImportError on the "from ..subpkg import module"
72                    # line, not sure why.
73                    self.__import__('pkg.subpkg')
74                self.assertNotIn('pkg.subpkg', sys.modules)
75                with self.assertRaises((ZeroDivisionError, ImportError)):
76                    self.__import__('pkg.subpkg.module')
77                self.assertNotIn('pkg.subpkg', sys.modules)
78                # XXX False
79                #self.assertIn('pkg.subpkg.module', sys.modules)
80
81    def test_module_not_package(self):
82        # Try to import a submodule from a non-package should raise ImportError.
83        assert not hasattr(sys, '__path__')
84        with self.assertRaises(ImportError) as cm:
85            self.__import__('sys.no_submodules_here')
86        self.assertEqual(cm.exception.name, 'sys.no_submodules_here')
87
88    def test_module_not_package_but_side_effects(self):
89        # If a module injects something into sys.modules as a side-effect, then
90        # pick up on that fact.
91        name = 'mod'
92        subname = name + '.b'
93        def module_injection():
94            sys.modules[subname] = 'total bunk'
95        mock_spec = util.mock_spec('mod',
96                                         module_code={'mod': module_injection})
97        with mock_spec as mock:
98            with util.import_state(meta_path=[mock]):
99                try:
100                    submodule = self.__import__(subname)
101                finally:
102                    import_helper.unload(subname)
103
104
105(Frozen_ParentTests,
106 Source_ParentTests
107 ) = util.test_both(ParentModuleTests, __import__=util.__import__)
108
109
110if __name__ == '__main__':
111    unittest.main()
112