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