Skip to content

Commit 056b733

Browse files
Subbarao Garlapatimeta-codesync[bot]
authored andcommitted
Fix broken tests when not in isolated mode
Summary: Tests run with Lazy Imports broke in D84660225, which switches from using isolated mode. This led us to discover that several tests were breaking with Lazy Imports on when run in sequential mode (without the `-j` flag that indicates multiprocessing to the test runner). ___ Several of the changes made in D52812410 to test files (in order to work around Lazy Imports incompatibilities such as implicit imports) weren't added in D83595369. This Diff adds the needed changes from there (discarding the ones that aren't needed and aren't preventative), as well as adding some changes here. ____ The categorization is as follows: In D52812410 but not ported over to here since they didn't affect tests: - `Lib‎/email‎/‎_header_value_parser.py` - `Lib/test/test_doctest.py` - `Lib‎/test‎/‎test___all__.py` - `Lib/test/test_clinic.py` In D52812410 and ported over to here since they seemed good from a safety perspective (even though they didn't affect tests): - `Lib‎/test‎/libregrtest‎/‎utils.py` - `Lib‎/test‎/test_capi‎/‎test_misc.py` - `Lib‎/test‎/test_unittest‎/‎test_discovery.py` In D52812410 and ported over to here since they affected tests: - `Lib‎/test‎/support‎/‎__init__.py` - `Lib/test/support/import_helper.py` - `Lib‎/test‎/test_import‎/data‎/package2‎/‎submodule1.py` - `Lib/test/test_import/__init__.py` - `Lib/test/test_heapq.py` - `Lib/test/test_pkg.py` - `Lib/test/test_traceback.py` Added to make new test failures pass: - `Lib/test/test_asyncio/test_eager_task_factory.py` - `Lib/test/test__interpreters.py` - `Lib/test/test_builtin.py` - `Lib/test/test_monitoring.py` Reviewed By: itamaro Differential Revision: D84747057 fbshipit-source-id: 3b143e045713ce1ffdf1739d288ee4f13c9b8dd4
1 parent c17e2e6 commit 056b733

15 files changed

Lines changed: 56 additions & 21 deletions

File tree

Lib/idlelib/idle_test/test_sidebar.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,15 @@
1515
from idlelib.percolator import Percolator
1616
import idlelib.pyshell
1717
from idlelib.pyshell import fix_x11_paste, PyShell, PyShellFileList
18-
from idlelib.run import fix_scaling
1918
import idlelib.sidebar
2019
from idlelib.sidebar import get_end_linenumber, get_lineno
2120

21+
# Lazy Imports Compatibility: Explictly load `fix_scaling` so that the test loader is able to find it with `getattr()`.
22+
try:
23+
import idlelib.run
24+
fix_scaling = idlelib.run.fix_scaling
25+
except Exception:
26+
pass
2227

2328
class Dummy_editwin:
2429
def __init__(self, text):

Lib/idlelib/run.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,13 @@
2727
from idlelib import stackviewer # StackTreeItem
2828
import __main__
2929

30-
import tkinter # Use tcl and, if startup fails, messagebox.
30+
# Lazy Imports Incompatibility: The following modules must be imported eagerly
31+
try:
32+
import tkinter # Use tcl and, if startup fails, messagebox.
33+
from tkinter import simpledialog, messagebox, font, dialog, filedialog, commondialog, ttk
34+
except Exception:
35+
pass
36+
3137
if not hasattr(sys.modules['idlelib.run'], 'firstrun'):
3238
# Undo modifications of tkinter by idlelib imports; see bpo-25507.
3339
for mod in ('simpledialog', 'messagebox', 'font',

Lib/test/libregrtest/utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,9 @@ def setup_threading_excepthook() -> None:
177177

178178
def clear_caches():
179179
# Clear the warnings registry, so they can be displayed again
180-
for mod in sys.modules.values():
180+
# Modules with __getattr__ could trigger imports and change sys.modules,
181+
# so we put the modules in a list of modules.
182+
for mod in list(sys.modules.values()):
181183
if hasattr(mod, '__warningregistry__'):
182184
del mod.__warningregistry__
183185

Lib/test/support/import_helper.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ def import_fresh_module(name, fresh=(), blocked=(), *,
171171
for modname in blocked:
172172
sys.modules[modname] = None
173173

174+
previously = _imp._set_lazy_imports(False)
174175
try:
175176
with frozen_modules(usefrozen):
176177
# Return None when one of the "fresh" modules can not be imported.
@@ -181,6 +182,7 @@ def import_fresh_module(name, fresh=(), blocked=(), *,
181182
return None
182183
return importlib.import_module(name)
183184
finally:
185+
_imp._set_lazy_imports(*previously)
184186
_save_and_remove_modules(names)
185187
sys.modules.update(orig_modules)
186188

Lib/test/test__interpreters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,7 @@ def test_invalid_syntax(self):
976976
modname = 'spam_spam_spam'
977977
filename = self.add_module(modname, script)
978978
self.assert_run_failed(SyntaxError, f"""
979-
import {modname}
979+
import {modname}; {modname}
980980
""")
981981

982982
def test_NameError(self):

Lib/test/test_asyncio/test_eager_task_factory.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import unittest
66

77
from unittest import mock
8-
from asyncio import tasks
8+
from asyncio import staggered, tasks
99
from test.test_asyncio import utils as test_utils
1010
from test.support.script_helper import assert_python_ok
1111

@@ -225,7 +225,7 @@ async def blocked():
225225
await fut
226226

227227
async def run():
228-
winner, index, excs = await asyncio.staggered.staggered_race(
228+
winner, index, excs = await staggered.staggered_race(
229229
[
230230
lambda: blocked(),
231231
lambda: asyncio.sleep(1, result="sleep1"),
@@ -247,7 +247,7 @@ async def fail():
247247
raise ValueError("no good")
248248

249249
async def run():
250-
winner, index, excs = await asyncio.staggered.staggered_race(
250+
winner, index, excs = await staggered.staggered_race(
251251
[
252252
lambda: fail(),
253253
lambda: asyncio.sleep(1, result="sleep1"),

Lib/test/test_builtin.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import decimal
88
import fractions
99
import gc
10+
import importlib
1011
import io
1112
import locale
1213
import math
@@ -968,12 +969,17 @@ def test_eval_builtins_mapping(self):
968969
eval, code, ns)
969970

970971
def test_exec_builtins_mapping_import(self):
971-
code = compile("import foo.bar", "test", "exec")
972+
# Force the import to happen even with Lazy Imports enabled
973+
code = compile("import foo.bar; foo.bar", "test", "exec")
972974
ns = {'__builtins__': types.MappingProxyType({})}
973975
self.assertRaisesRegex(ImportError, "__import__ not found", exec, code, ns)
974976
ns = {'__builtins__': types.MappingProxyType({'__import__': lambda *args: args})}
977+
# Go back to using original code object since bar doesn't exist
978+
code = compile("import foo.bar", "test", "exec")
975979
exec(code, ns)
976-
self.assertEqual(ns['foo'], ('foo.bar', ns, ns, None, 0))
980+
# Skip this assert since lazy imports doesn't resolve foo.bar
981+
if not importlib.is_lazy_imports_enabled():
982+
self.assertEqual(ns['foo'], ('foo.bar', ns, ns, None, 0))
977983

978984
def test_eval_builtins_mapping_reduce(self):
979985
# list_iterator.__reduce__() calls _PyEval_GetBuiltin("iter")

Lib/test/test_capi/test_misc.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,11 @@ def test_isolated_subinterpreter(self):
14341434
import time
14351435
import _testinternalcapi
14361436
from test.support import threading_helper
1437+
1438+
# FIXME: To prevent threading._shutdown() from locking (locked _shutdown_locks)
1439+
# when using Lazy Imports, we need to eagerly import threading here.
1440+
# Possibly related to gh-105716.
1441+
threading
14371442
""")
14381443

14391444
def create_pipe():

Lib/test/test_heapq.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def load_tests(loader, tests, ignore):
3939
class HeapqMergeDocTestFinder:
4040
def find(self, *args, **kwargs):
4141
dtf = doctest.DocTestFinder()
42-
return dtf.find(py_heapq.merge)
42+
return dtf.find(py_heapq.merge, module=py_heapq)
4343

4444
tests.addTests(doctest.DocTestSuite(py_heapq,
4545
test_finder=HeapqMergeDocTestFinder()))

Lib/test/test_import/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
FrozenImporter,
1212
SourceFileLoader,
1313
)
14+
from importlib import is_lazy_imports_enabled
1415
import marshal
1516
import os
1617
import py_compile
@@ -1494,6 +1495,7 @@ def test_relimport_star(self):
14941495
from .. import relimport
14951496
self.assertHasAttr(relimport, "RelativeImportTests")
14961497

1498+
@unittest.skipIf(is_lazy_imports_enabled(), "Test relevant only when running with lazy imports disabled")
14971499
def test_issue3221(self):
14981500
# Note for mergers: the 'absolute' tests from the 2.x branch
14991501
# are missing in Py3k because implicit relative imports are
@@ -1916,6 +1918,7 @@ def test_nonexistent_module(self):
19161918
self.fail("ImportError should have been raised")
19171919
self.assert_traceback(tb, [__file__])
19181920

1921+
@unittest.skipIf(is_lazy_imports_enabled(), "Lazy Imports has different behavior in nested modules")
19191922
def test_nonexistent_module_nested(self):
19201923
self.create_module("foo", "import nonexistent_xyzzy")
19211924
try:
@@ -1936,6 +1939,7 @@ def test_exec_failure(self):
19361939
self.fail("ZeroDivisionError should have been raised")
19371940
self.assert_traceback(tb, [__file__, 'foo.py'])
19381941

1942+
@unittest.skipIf(is_lazy_imports_enabled(), "Lazy Imports has different behavior in nested modules")
19391943
def test_exec_failure_nested(self):
19401944
self.create_module("foo", "import bar")
19411945
self.create_module("bar", "1/0")
@@ -2100,6 +2104,7 @@ def test_crossreference1(self):
21002104
import test.test_import.data.circular_imports.use
21012105
import test.test_import.data.circular_imports.source
21022106

2107+
@unittest.skipIf(is_lazy_imports_enabled(), "Test relevant only when running with lazy imports disabled")
21032108
def test_crossreference2(self):
21042109
with self.assertRaises(AttributeError) as cm:
21052110
import test.test_import.data.circular_imports.source
@@ -2109,6 +2114,7 @@ def test_crossreference2(self):
21092114
self.assertIn('partially initialized module', errmsg)
21102115
self.assertIn('circular import', errmsg)
21112116

2117+
@unittest.skipIf(is_lazy_imports_enabled(), "Test relevant only when running with lazy imports disabled")
21122118
def test_circular_from_import(self):
21132119
with self.assertRaises(ImportError) as cm:
21142120
import test.test_import.data.circular_imports.from_cycle1
@@ -2127,6 +2133,7 @@ def test_circular_import(self):
21272133
):
21282134
import test.test_import.data.circular_imports.import_cycle
21292135

2136+
@unittest.skipIf(is_lazy_imports_enabled(), "Test relevant only when running with lazy imports disabled")
21302137
def test_absolute_circular_submodule(self):
21312138
with self.assertRaises(AttributeError) as cm:
21322139
import test.test_import.data.circular_imports.subpkg2.parent

0 commit comments

Comments
 (0)