|
| 1 | +import gc |
1 | 2 | import importlib
|
2 | 3 | import importlib.util
|
3 | 4 | import os
|
|
8 | 9 | from test.support import import_helper
|
9 | 10 | from test.support import os_helper
|
10 | 11 | from test.support import script_helper
|
| 12 | +from test.support import warnings_helper |
11 | 13 | import unittest
|
12 | 14 | import warnings
|
13 |
| -with warnings.catch_warnings(): |
14 |
| - warnings.simplefilter('ignore', DeprecationWarning) |
15 |
| - import imp |
| 15 | +imp = warnings_helper.import_deprecated('imp') |
16 | 16 | import _imp
|
17 | 17 |
|
18 | 18 |
|
| 19 | +OS_PATH_NAME = os.path.__name__ |
| 20 | + |
| 21 | + |
19 | 22 | def requires_load_dynamic(meth):
|
20 | 23 | """Decorator to skip a test if not running under CPython or lacking
|
21 | 24 | imp.load_dynamic()."""
|
22 | 25 | meth = support.cpython_only(meth)
|
23 |
| - return unittest.skipIf(not hasattr(imp, 'load_dynamic'), |
| 26 | + return unittest.skipIf(getattr(imp, 'load_dynamic', None) is None, |
24 | 27 | 'imp.load_dynamic() required')(meth)
|
25 | 28 |
|
26 | 29 |
|
@@ -216,15 +219,17 @@ def test_load_from_source(self):
|
216 | 219 | # state after reversion. Reinitialising the module contents
|
217 | 220 | # and just reverting os.environ to its previous state is an OK
|
218 | 221 | # workaround
|
219 |
| - orig_path = os.path |
220 |
| - orig_getenv = os.getenv |
221 |
| - with os_helper.EnvironmentVarGuard(): |
222 |
| - x = imp.find_module("os") |
223 |
| - self.addCleanup(x[0].close) |
224 |
| - new_os = imp.load_module("os", *x) |
225 |
| - self.assertIs(os, new_os) |
226 |
| - self.assertIs(orig_path, new_os.path) |
227 |
| - self.assertIsNot(orig_getenv, new_os.getenv) |
| 222 | + with import_helper.CleanImport('os', 'os.path', OS_PATH_NAME): |
| 223 | + import os |
| 224 | + orig_path = os.path |
| 225 | + orig_getenv = os.getenv |
| 226 | + with os_helper.EnvironmentVarGuard(): |
| 227 | + x = imp.find_module("os") |
| 228 | + self.addCleanup(x[0].close) |
| 229 | + new_os = imp.load_module("os", *x) |
| 230 | + self.assertIs(os, new_os) |
| 231 | + self.assertIs(orig_path, new_os.path) |
| 232 | + self.assertIsNot(orig_getenv, new_os.getenv) |
228 | 233 |
|
229 | 234 | @requires_load_dynamic
|
230 | 235 | def test_issue15828_load_extensions(self):
|
@@ -351,8 +356,8 @@ def test_issue_35321(self):
|
351 | 356 | # TODO: RUSTPYTHON
|
352 | 357 | @unittest.expectedFailure
|
353 | 358 | def test_source_hash(self):
|
354 |
| - self.assertEqual(_imp.source_hash(42, b'hi'), b'\xc6\xe7Z\r\x03:}\xab') |
355 |
| - self.assertEqual(_imp.source_hash(43, b'hi'), b'\x85\x9765\xf8\x9a\x8b9') |
| 359 | + self.assertEqual(_imp.source_hash(42, b'hi'), b'\xfb\xd9G\x05\xaf$\x9b~') |
| 360 | + self.assertEqual(_imp.source_hash(43, b'hi'), b'\xd0/\x87C\xccC\xff\xe2') |
356 | 361 |
|
357 | 362 | def test_pyc_invalidation_mode_from_cmdline(self):
|
358 | 363 | cases = [
|
@@ -384,6 +389,35 @@ def test_find_and_load_checked_pyc(self):
|
384 | 389 | self.assertEqual(mod.x, 42)
|
385 | 390 |
|
386 | 391 |
|
| 392 | + @support.cpython_only |
| 393 | + def test_create_builtin_subinterp(self): |
| 394 | + # gh-99578: create_builtin() behavior changes after the creation of the |
| 395 | + # first sub-interpreter. Test both code paths, before and after the |
| 396 | + # creation of a sub-interpreter. Previously, create_builtin() had |
| 397 | + # a reference leak after the creation of the first sub-interpreter. |
| 398 | + |
| 399 | + import builtins |
| 400 | + create_builtin = support.get_attribute(_imp, "create_builtin") |
| 401 | + class Spec: |
| 402 | + name = "builtins" |
| 403 | + spec = Spec() |
| 404 | + |
| 405 | + def check_get_builtins(): |
| 406 | + refcnt = sys.getrefcount(builtins) |
| 407 | + mod = _imp.create_builtin(spec) |
| 408 | + self.assertIs(mod, builtins) |
| 409 | + self.assertEqual(sys.getrefcount(builtins), refcnt + 1) |
| 410 | + # Check that a GC collection doesn't crash |
| 411 | + gc.collect() |
| 412 | + |
| 413 | + check_get_builtins() |
| 414 | + |
| 415 | + ret = support.run_in_subinterp("import builtins") |
| 416 | + self.assertEqual(ret, 0) |
| 417 | + |
| 418 | + check_get_builtins() |
| 419 | + |
| 420 | + |
387 | 421 | class ReloadTests(unittest.TestCase):
|
388 | 422 |
|
389 | 423 | """Very basic tests to make sure that imp.reload() operates just like
|
|
0 commit comments