Skip to content

Commit 28ee6cd

Browse files
author
gcarq
committed
Lib/test/test_module.py from CPython 3.8.3
1 parent 321aa02 commit 28ee6cd

File tree

1 file changed

+310
-0
lines changed

1 file changed

+310
-0
lines changed

Lib/test/test_module.py

Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
# Test the module type
2+
import unittest
3+
import weakref
4+
from test.support import gc_collect, requires_type_collecting
5+
from test.support.script_helper import assert_python_ok
6+
7+
import sys
8+
ModuleType = type(sys)
9+
10+
class FullLoader:
11+
@classmethod
12+
def module_repr(cls, m):
13+
return "<module '{}' (crafted)>".format(m.__name__)
14+
15+
class BareLoader:
16+
pass
17+
18+
19+
class ModuleTests(unittest.TestCase):
20+
# TODO: RUSTPYTHON
21+
@unittest.expectedFailure
22+
def test_uninitialized(self):
23+
# An uninitialized module has no __dict__ or __name__,
24+
# and __doc__ is None
25+
foo = ModuleType.__new__(ModuleType)
26+
self.assertTrue(foo.__dict__ is None)
27+
self.assertRaises(SystemError, dir, foo)
28+
try:
29+
s = foo.__name__
30+
self.fail("__name__ = %s" % repr(s))
31+
except AttributeError:
32+
pass
33+
self.assertEqual(foo.__doc__, ModuleType.__doc__)
34+
35+
# TODO: RUSTPYTHON
36+
@unittest.expectedFailure
37+
def test_uninitialized_missing_getattr(self):
38+
# Issue 8297
39+
# test the text in the AttributeError of an uninitialized module
40+
foo = ModuleType.__new__(ModuleType)
41+
self.assertRaisesRegex(
42+
AttributeError, "module has no attribute 'not_here'",
43+
getattr, foo, "not_here")
44+
45+
def test_missing_getattr(self):
46+
# Issue 8297
47+
# test the text in the AttributeError
48+
foo = ModuleType("foo")
49+
self.assertRaisesRegex(
50+
AttributeError, "module 'foo' has no attribute 'not_here'",
51+
getattr, foo, "not_here")
52+
53+
def test_no_docstring(self):
54+
# Regularly initialized module, no docstring
55+
foo = ModuleType("foo")
56+
self.assertEqual(foo.__name__, "foo")
57+
self.assertEqual(foo.__doc__, None)
58+
self.assertIs(foo.__loader__, None)
59+
self.assertIs(foo.__package__, None)
60+
self.assertIs(foo.__spec__, None)
61+
self.assertEqual(foo.__dict__, {"__name__": "foo", "__doc__": None,
62+
"__loader__": None, "__package__": None,
63+
"__spec__": None})
64+
65+
def test_ascii_docstring(self):
66+
# ASCII docstring
67+
foo = ModuleType("foo", "foodoc")
68+
self.assertEqual(foo.__name__, "foo")
69+
self.assertEqual(foo.__doc__, "foodoc")
70+
self.assertEqual(foo.__dict__,
71+
{"__name__": "foo", "__doc__": "foodoc",
72+
"__loader__": None, "__package__": None,
73+
"__spec__": None})
74+
75+
def test_unicode_docstring(self):
76+
# Unicode docstring
77+
foo = ModuleType("foo", "foodoc\u1234")
78+
self.assertEqual(foo.__name__, "foo")
79+
self.assertEqual(foo.__doc__, "foodoc\u1234")
80+
self.assertEqual(foo.__dict__,
81+
{"__name__": "foo", "__doc__": "foodoc\u1234",
82+
"__loader__": None, "__package__": None,
83+
"__spec__": None})
84+
85+
# TODO: RUSTPYTHON
86+
@unittest.expectedFailure
87+
def test_reinit(self):
88+
# Reinitialization should not replace the __dict__
89+
foo = ModuleType("foo", "foodoc\u1234")
90+
foo.bar = 42
91+
d = foo.__dict__
92+
foo.__init__("foo", "foodoc")
93+
self.assertEqual(foo.__name__, "foo")
94+
self.assertEqual(foo.__doc__, "foodoc")
95+
self.assertEqual(foo.bar, 42)
96+
self.assertEqual(foo.__dict__,
97+
{"__name__": "foo", "__doc__": "foodoc", "bar": 42,
98+
"__loader__": None, "__package__": None, "__spec__": None})
99+
self.assertTrue(foo.__dict__ is d)
100+
101+
def test_dont_clear_dict(self):
102+
# See issue 7140.
103+
def f():
104+
foo = ModuleType("foo")
105+
foo.bar = 4
106+
return foo
107+
gc_collect()
108+
self.assertEqual(f().__dict__["bar"], 4)
109+
110+
# TODO: RUSTPYTHON
111+
@unittest.expectedFailure
112+
@requires_type_collecting
113+
def test_clear_dict_in_ref_cycle(self):
114+
destroyed = []
115+
m = ModuleType("foo")
116+
m.destroyed = destroyed
117+
s = """class A:
118+
def __init__(self, l):
119+
self.l = l
120+
def __del__(self):
121+
self.l.append(1)
122+
a = A(destroyed)"""
123+
exec(s, m.__dict__)
124+
del m
125+
gc_collect()
126+
self.assertEqual(destroyed, [1])
127+
128+
def test_weakref(self):
129+
m = ModuleType("foo")
130+
wr = weakref.ref(m)
131+
self.assertIs(wr(), m)
132+
del m
133+
gc_collect()
134+
self.assertIs(wr(), None)
135+
136+
@unittest.skip("TODO: RUSTPYTHON")
137+
def test_module_getattr(self):
138+
import test.good_getattr as gga
139+
from test.good_getattr import test
140+
self.assertEqual(test, "There is test")
141+
self.assertEqual(gga.x, 1)
142+
self.assertEqual(gga.y, 2)
143+
with self.assertRaisesRegex(AttributeError,
144+
"Deprecated, use whatever instead"):
145+
gga.yolo
146+
self.assertEqual(gga.whatever, "There is whatever")
147+
del sys.modules['test.good_getattr']
148+
149+
@unittest.skip("TODO: RUSTPYTHON")
150+
def test_module_getattr_errors(self):
151+
import test.bad_getattr as bga
152+
from test import bad_getattr2
153+
self.assertEqual(bga.x, 1)
154+
self.assertEqual(bad_getattr2.x, 1)
155+
with self.assertRaises(TypeError):
156+
bga.nope
157+
with self.assertRaises(TypeError):
158+
bad_getattr2.nope
159+
del sys.modules['test.bad_getattr']
160+
if 'test.bad_getattr2' in sys.modules:
161+
del sys.modules['test.bad_getattr2']
162+
163+
@unittest.skip("TODO: RUSTPYTHON")
164+
def test_module_dir(self):
165+
import test.good_getattr as gga
166+
self.assertEqual(dir(gga), ['a', 'b', 'c'])
167+
del sys.modules['test.good_getattr']
168+
169+
@unittest.skip("TODO: RUSTPYTHON")
170+
def test_module_dir_errors(self):
171+
import test.bad_getattr as bga
172+
from test import bad_getattr2
173+
with self.assertRaises(TypeError):
174+
dir(bga)
175+
with self.assertRaises(TypeError):
176+
dir(bad_getattr2)
177+
del sys.modules['test.bad_getattr']
178+
if 'test.bad_getattr2' in sys.modules:
179+
del sys.modules['test.bad_getattr2']
180+
181+
@unittest.skip("TODO: RUSTPYTHON")
182+
def test_module_getattr_tricky(self):
183+
from test import bad_getattr3
184+
# these lookups should not crash
185+
with self.assertRaises(AttributeError):
186+
bad_getattr3.one
187+
with self.assertRaises(AttributeError):
188+
bad_getattr3.delgetattr
189+
if 'test.bad_getattr3' in sys.modules:
190+
del sys.modules['test.bad_getattr3']
191+
192+
def test_module_repr_minimal(self):
193+
# reprs when modules have no __file__, __name__, or __loader__
194+
m = ModuleType('foo')
195+
del m.__name__
196+
self.assertEqual(repr(m), "<module '?'>")
197+
198+
def test_module_repr_with_name(self):
199+
m = ModuleType('foo')
200+
self.assertEqual(repr(m), "<module 'foo'>")
201+
202+
def test_module_repr_with_name_and_filename(self):
203+
m = ModuleType('foo')
204+
m.__file__ = '/tmp/foo.py'
205+
self.assertEqual(repr(m), "<module 'foo' from '/tmp/foo.py'>")
206+
207+
def test_module_repr_with_filename_only(self):
208+
m = ModuleType('foo')
209+
del m.__name__
210+
m.__file__ = '/tmp/foo.py'
211+
self.assertEqual(repr(m), "<module '?' from '/tmp/foo.py'>")
212+
213+
def test_module_repr_with_loader_as_None(self):
214+
m = ModuleType('foo')
215+
assert m.__loader__ is None
216+
self.assertEqual(repr(m), "<module 'foo'>")
217+
218+
def test_module_repr_with_bare_loader_but_no_name(self):
219+
m = ModuleType('foo')
220+
del m.__name__
221+
# Yes, a class not an instance.
222+
m.__loader__ = BareLoader
223+
loader_repr = repr(BareLoader)
224+
self.assertEqual(
225+
repr(m), "<module '?' ({})>".format(loader_repr))
226+
227+
def test_module_repr_with_full_loader_but_no_name(self):
228+
# m.__loader__.module_repr() will fail because the module has no
229+
# m.__name__. This exception will get suppressed and instead the
230+
# loader's repr will be used.
231+
m = ModuleType('foo')
232+
del m.__name__
233+
# Yes, a class not an instance.
234+
m.__loader__ = FullLoader
235+
loader_repr = repr(FullLoader)
236+
self.assertEqual(
237+
repr(m), "<module '?' ({})>".format(loader_repr))
238+
239+
def test_module_repr_with_bare_loader(self):
240+
m = ModuleType('foo')
241+
# Yes, a class not an instance.
242+
m.__loader__ = BareLoader
243+
module_repr = repr(BareLoader)
244+
self.assertEqual(
245+
repr(m), "<module 'foo' ({})>".format(module_repr))
246+
247+
def test_module_repr_with_full_loader(self):
248+
m = ModuleType('foo')
249+
# Yes, a class not an instance.
250+
m.__loader__ = FullLoader
251+
self.assertEqual(
252+
repr(m), "<module 'foo' (crafted)>")
253+
254+
def test_module_repr_with_bare_loader_and_filename(self):
255+
# Because the loader has no module_repr(), use the file name.
256+
m = ModuleType('foo')
257+
# Yes, a class not an instance.
258+
m.__loader__ = BareLoader
259+
m.__file__ = '/tmp/foo.py'
260+
self.assertEqual(repr(m), "<module 'foo' from '/tmp/foo.py'>")
261+
262+
def test_module_repr_with_full_loader_and_filename(self):
263+
# Even though the module has an __file__, use __loader__.module_repr()
264+
m = ModuleType('foo')
265+
# Yes, a class not an instance.
266+
m.__loader__ = FullLoader
267+
m.__file__ = '/tmp/foo.py'
268+
self.assertEqual(repr(m), "<module 'foo' (crafted)>")
269+
270+
def test_module_repr_builtin(self):
271+
self.assertEqual(repr(sys), "<module 'sys' (built-in)>")
272+
273+
def test_module_repr_source(self):
274+
r = repr(unittest)
275+
starts_with = "<module 'unittest' from '"
276+
ends_with = "__init__.py'>"
277+
self.assertEqual(r[:len(starts_with)], starts_with,
278+
'{!r} does not start with {!r}'.format(r, starts_with))
279+
self.assertEqual(r[-len(ends_with):], ends_with,
280+
'{!r} does not end with {!r}'.format(r, ends_with))
281+
282+
# TODO: RUSTPYTHON
283+
@unittest.expectedFailure
284+
@requires_type_collecting
285+
def test_module_finalization_at_shutdown(self):
286+
# Module globals and builtins should still be available during shutdown
287+
rc, out, err = assert_python_ok("-c", "from test import final_a")
288+
self.assertFalse(err)
289+
lines = out.splitlines()
290+
self.assertEqual(set(lines), {
291+
b"x = a",
292+
b"x = b",
293+
b"final_a.x = a",
294+
b"final_b.x = b",
295+
b"len = len",
296+
b"shutil.rmtree = rmtree"})
297+
298+
def test_descriptor_errors_propagate(self):
299+
class Descr:
300+
def __get__(self, o, t):
301+
raise RuntimeError
302+
class M(ModuleType):
303+
melon = Descr()
304+
self.assertRaises(RuntimeError, getattr, M("mymod"), "melon")
305+
306+
# frozen and namespace module reprs are tested in importlib.
307+
308+
309+
if __name__ == '__main__':
310+
unittest.main()

0 commit comments

Comments
 (0)