| # Test the module type | 
 | import unittest | 
 | import weakref | 
 | from test.support import run_unittest, gc_collect | 
 | from test.script_helper import assert_python_ok | 
 |  | 
 | import sys | 
 | ModuleType = type(sys) | 
 |  | 
 | class FullLoader: | 
 |     @classmethod | 
 |     def module_repr(cls, m): | 
 |         return "<module '{}' (crafted)>".format(m.__name__) | 
 |  | 
 | class BareLoader: | 
 |     pass | 
 |  | 
 |  | 
 | class ModuleTests(unittest.TestCase): | 
 |     def test_uninitialized(self): | 
 |         # An uninitialized module has no __dict__ or __name__, | 
 |         # and __doc__ is None | 
 |         foo = ModuleType.__new__(ModuleType) | 
 |         self.assertTrue(foo.__dict__ is None) | 
 |         self.assertRaises(SystemError, dir, foo) | 
 |         try: | 
 |             s = foo.__name__ | 
 |             self.fail("__name__ = %s" % repr(s)) | 
 |         except AttributeError: | 
 |             pass | 
 |         self.assertEqual(foo.__doc__, ModuleType.__doc__) | 
 |  | 
 |     def test_no_docstring(self): | 
 |         # Regularly initialized module, no docstring | 
 |         foo = ModuleType("foo") | 
 |         self.assertEqual(foo.__name__, "foo") | 
 |         self.assertEqual(foo.__doc__, None) | 
 |         self.assertIs(foo.__loader__, None) | 
 |         self.assertIs(foo.__package__, None) | 
 |         self.assertIs(foo.__spec__, None) | 
 |         self.assertEqual(foo.__dict__, {"__name__": "foo", "__doc__": None, | 
 |                                         "__loader__": None, "__package__": None, | 
 |                                         "__spec__": None}) | 
 |  | 
 |     def test_ascii_docstring(self): | 
 |         # ASCII docstring | 
 |         foo = ModuleType("foo", "foodoc") | 
 |         self.assertEqual(foo.__name__, "foo") | 
 |         self.assertEqual(foo.__doc__, "foodoc") | 
 |         self.assertEqual(foo.__dict__, | 
 |                          {"__name__": "foo", "__doc__": "foodoc", | 
 |                           "__loader__": None, "__package__": None, | 
 |                           "__spec__": None}) | 
 |  | 
 |     def test_unicode_docstring(self): | 
 |         # Unicode docstring | 
 |         foo = ModuleType("foo", "foodoc\u1234") | 
 |         self.assertEqual(foo.__name__, "foo") | 
 |         self.assertEqual(foo.__doc__, "foodoc\u1234") | 
 |         self.assertEqual(foo.__dict__, | 
 |                          {"__name__": "foo", "__doc__": "foodoc\u1234", | 
 |                           "__loader__": None, "__package__": None, | 
 |                           "__spec__": None}) | 
 |  | 
 |     def test_reinit(self): | 
 |         # Reinitialization should not replace the __dict__ | 
 |         foo = ModuleType("foo", "foodoc\u1234") | 
 |         foo.bar = 42 | 
 |         d = foo.__dict__ | 
 |         foo.__init__("foo", "foodoc") | 
 |         self.assertEqual(foo.__name__, "foo") | 
 |         self.assertEqual(foo.__doc__, "foodoc") | 
 |         self.assertEqual(foo.bar, 42) | 
 |         self.assertEqual(foo.__dict__, | 
 |               {"__name__": "foo", "__doc__": "foodoc", "bar": 42, | 
 |                "__loader__": None, "__package__": None, "__spec__": None}) | 
 |         self.assertTrue(foo.__dict__ is d) | 
 |  | 
 |     def test_dont_clear_dict(self): | 
 |         # See issue 7140. | 
 |         def f(): | 
 |             foo = ModuleType("foo") | 
 |             foo.bar = 4 | 
 |             return foo | 
 |         gc_collect() | 
 |         self.assertEqual(f().__dict__["bar"], 4) | 
 |  | 
 |     def test_clear_dict_in_ref_cycle(self): | 
 |         destroyed = [] | 
 |         m = ModuleType("foo") | 
 |         m.destroyed = destroyed | 
 |         s = """class A: | 
 |     def __init__(self, l): | 
 |         self.l = l | 
 |     def __del__(self): | 
 |         self.l.append(1) | 
 | a = A(destroyed)""" | 
 |         exec(s, m.__dict__) | 
 |         del m | 
 |         gc_collect() | 
 |         self.assertEqual(destroyed, [1]) | 
 |  | 
 |     def test_weakref(self): | 
 |         m = ModuleType("foo") | 
 |         wr = weakref.ref(m) | 
 |         self.assertIs(wr(), m) | 
 |         del m | 
 |         gc_collect() | 
 |         self.assertIs(wr(), None) | 
 |  | 
 |     def test_module_repr_minimal(self): | 
 |         # reprs when modules have no __file__, __name__, or __loader__ | 
 |         m = ModuleType('foo') | 
 |         del m.__name__ | 
 |         self.assertEqual(repr(m), "<module '?'>") | 
 |  | 
 |     def test_module_repr_with_name(self): | 
 |         m = ModuleType('foo') | 
 |         self.assertEqual(repr(m), "<module 'foo'>") | 
 |  | 
 |     def test_module_repr_with_name_and_filename(self): | 
 |         m = ModuleType('foo') | 
 |         m.__file__ = '/tmp/foo.py' | 
 |         self.assertEqual(repr(m), "<module 'foo' from '/tmp/foo.py'>") | 
 |  | 
 |     def test_module_repr_with_filename_only(self): | 
 |         m = ModuleType('foo') | 
 |         del m.__name__ | 
 |         m.__file__ = '/tmp/foo.py' | 
 |         self.assertEqual(repr(m), "<module '?' from '/tmp/foo.py'>") | 
 |  | 
 |     def test_module_repr_with_loader_as_None(self): | 
 |         m = ModuleType('foo') | 
 |         assert m.__loader__ is None | 
 |         self.assertEqual(repr(m), "<module 'foo'>") | 
 |  | 
 |     def test_module_repr_with_bare_loader_but_no_name(self): | 
 |         m = ModuleType('foo') | 
 |         del m.__name__ | 
 |         # Yes, a class not an instance. | 
 |         m.__loader__ = BareLoader | 
 |         loader_repr = repr(BareLoader) | 
 |         self.assertEqual( | 
 |             repr(m), "<module '?' ({})>".format(loader_repr)) | 
 |  | 
 |     def test_module_repr_with_full_loader_but_no_name(self): | 
 |         # m.__loader__.module_repr() will fail because the module has no | 
 |         # m.__name__.  This exception will get suppressed and instead the | 
 |         # loader's repr will be used. | 
 |         m = ModuleType('foo') | 
 |         del m.__name__ | 
 |         # Yes, a class not an instance. | 
 |         m.__loader__ = FullLoader | 
 |         loader_repr = repr(FullLoader) | 
 |         self.assertEqual( | 
 |             repr(m), "<module '?' ({})>".format(loader_repr)) | 
 |  | 
 |     def test_module_repr_with_bare_loader(self): | 
 |         m = ModuleType('foo') | 
 |         # Yes, a class not an instance. | 
 |         m.__loader__ = BareLoader | 
 |         module_repr = repr(BareLoader) | 
 |         self.assertEqual( | 
 |             repr(m), "<module 'foo' ({})>".format(module_repr)) | 
 |  | 
 |     def test_module_repr_with_full_loader(self): | 
 |         m = ModuleType('foo') | 
 |         # Yes, a class not an instance. | 
 |         m.__loader__ = FullLoader | 
 |         self.assertEqual( | 
 |             repr(m), "<module 'foo' (crafted)>") | 
 |  | 
 |     def test_module_repr_with_bare_loader_and_filename(self): | 
 |         # Because the loader has no module_repr(), use the file name. | 
 |         m = ModuleType('foo') | 
 |         # Yes, a class not an instance. | 
 |         m.__loader__ = BareLoader | 
 |         m.__file__ = '/tmp/foo.py' | 
 |         self.assertEqual(repr(m), "<module 'foo' from '/tmp/foo.py'>") | 
 |  | 
 |     def test_module_repr_with_full_loader_and_filename(self): | 
 |         # Even though the module has an __file__, use __loader__.module_repr() | 
 |         m = ModuleType('foo') | 
 |         # Yes, a class not an instance. | 
 |         m.__loader__ = FullLoader | 
 |         m.__file__ = '/tmp/foo.py' | 
 |         self.assertEqual(repr(m), "<module 'foo' (crafted)>") | 
 |  | 
 |     def test_module_repr_builtin(self): | 
 |         self.assertEqual(repr(sys), "<module 'sys' (built-in)>") | 
 |  | 
 |     def test_module_repr_source(self): | 
 |         r = repr(unittest) | 
 |         starts_with = "<module 'unittest' from '" | 
 |         ends_with = "__init__.py'>" | 
 |         self.assertEqual(r[:len(starts_with)], starts_with, | 
 |                          '{!r} does not start with {!r}'.format(r, starts_with)) | 
 |         self.assertEqual(r[-len(ends_with):], ends_with, | 
 |                          '{!r} does not end with {!r}'.format(r, ends_with)) | 
 |  | 
 |     def test_module_finalization_at_shutdown(self): | 
 |         # Module globals and builtins should still be available during shutdown | 
 |         rc, out, err = assert_python_ok("-c", "from test import final_a") | 
 |         self.assertFalse(err) | 
 |         lines = out.splitlines() | 
 |         self.assertEqual(set(lines), { | 
 |             b"x = a", | 
 |             b"x = b", | 
 |             b"final_a.x = a", | 
 |             b"final_b.x = b", | 
 |             b"len = len", | 
 |             b"shutil.rmtree = rmtree"}) | 
 |  | 
 |     # frozen and namespace module reprs are tested in importlib. | 
 |  | 
 |  | 
 | def test_main(): | 
 |     run_unittest(ModuleTests) | 
 |  | 
 |  | 
 | if __name__ == '__main__': | 
 |     test_main() |