55import sys
66import types
77
8- try :
9- import _multiprocessing
10- except ModuleNotFoundError :
11- _multiprocessing = None
12-
138
149if support .check_sanitizer (address = True , memory = True ):
15- # bpo-46633: test___all__ is skipped because importing some modules
16- # directly can trigger known problems with ASAN (like tk or crypt).
17- raise unittest .SkipTest ("workaround ASAN build issues on loading tests "
18- "like tk or crypt" )
10+ SKIP_MODULES = frozenset ((
11+ # gh-90791: Tests involving libX11 can SEGFAULT on ASAN/MSAN builds.
12+ # Skip modules, packages and tests using '_tkinter'.
13+ '_tkinter' ,
14+ 'tkinter' ,
15+ 'test_tkinter' ,
16+ 'test_ttk' ,
17+ 'test_ttk_textonly' ,
18+ 'idlelib' ,
19+ 'test_idle' ,
20+ ))
21+ else :
22+ SKIP_MODULES = ()
1923
2024
2125class NoAll (RuntimeError ):
@@ -27,17 +31,6 @@ class FailedImport(RuntimeError):
2731
2832class AllTest (unittest .TestCase ):
2933
30- def setUp (self ):
31- # concurrent.futures uses a __getattr__ hook. Its __all__ triggers
32- # import of a submodule, which fails when _multiprocessing is not
33- # available.
34- if _multiprocessing is None :
35- sys .modules ["_multiprocessing" ] = types .ModuleType ("_multiprocessing" )
36-
37- def tearDown (self ):
38- if _multiprocessing is None :
39- sys .modules .pop ("_multiprocessing" )
40-
4134 def check_all (self , modname ):
4235 names = {}
4336 with warnings_helper .check_warnings (
@@ -83,16 +76,24 @@ def walk_modules(self, basedir, modpath):
8376 for fn in sorted (os .listdir (basedir )):
8477 path = os .path .join (basedir , fn )
8578 if os .path .isdir (path ):
79+ if fn in SKIP_MODULES :
80+ continue
8681 pkg_init = os .path .join (path , '__init__.py' )
8782 if os .path .exists (pkg_init ):
8883 yield pkg_init , modpath + fn
8984 for p , m in self .walk_modules (path , modpath + fn + "." ):
9085 yield p , m
9186 continue
92- if not fn .endswith ('.py' ) or fn == '__init__.py' :
87+
88+ if fn == '__init__.py' :
9389 continue
94- yield path , modpath + fn [:- 3 ]
95-
90+ if not fn .endswith ('.py' ):
91+ continue
92+ modname = fn .removesuffix ('.py' )
93+ if modname in SKIP_MODULES :
94+ continue
95+ yield path , modpath + modname
96+
9697 # TODO: RUSTPYTHON
9798 @unittest .expectedFailure
9899 def test_all (self ):
@@ -103,7 +104,8 @@ def test_all(self):
103104 ])
104105
105106 # In case _socket fails to build, make this test fail more gracefully
106- # than an AttributeError somewhere deep in CGIHTTPServer.
107+ # than an AttributeError somewhere deep in concurrent.futures, email
108+ # or unittest.
107109 import _socket
108110
109111 ignored = []
@@ -120,14 +122,14 @@ def test_all(self):
120122 if denied :
121123 continue
122124 if support .verbose :
123- print (modname )
125+ print (f"Check { modname } " , flush = True )
124126 try :
125127 # This heuristic speeds up the process by removing, de facto,
126128 # most test modules (and avoiding the auto-executing ones).
127129 with open (path , "rb" ) as f :
128130 if b"__all__" not in f .read ():
129131 raise NoAll (modname )
130- self .check_all (modname )
132+ self .check_all (modname )
131133 except NoAll :
132134 ignored .append (modname )
133135 except FailedImport :
0 commit comments