Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit345e1e0

Browse files
authored
gh-112730: Make the test suite resilient to color-activation environment variables (#117672)
1 parent59a4d52 commit345e1e0

File tree

13 files changed

+89
-16
lines changed

13 files changed

+89
-16
lines changed

‎.github/workflows/reusable-ubuntu.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ jobs:
1414
timeout-minutes:60
1515
runs-on:ubuntu-20.04
1616
env:
17+
FORCE_COLOR:1
1718
OPENSSL_VER:3.0.13
1819
PYTHONSTRICTEXTENSIONBUILD:1
1920
steps:

‎Lib/doctest.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,11 @@ def out(s):
15561556
# Make sure sys.displayhook just prints the value to stdout
15571557
save_displayhook=sys.displayhook
15581558
sys.displayhook=sys.__displayhook__
1559-
1559+
saved_can_colorize=traceback._can_colorize
1560+
traceback._can_colorize=lambda:False
1561+
color_variables= {"PYTHON_COLORS":None,"FORCE_COLOR":None}
1562+
forkeyincolor_variables:
1563+
color_variables[key]=os.environ.pop(key,None)
15601564
try:
15611565
returnself.__run(test,compileflags,out)
15621566
finally:
@@ -1565,6 +1569,10 @@ def out(s):
15651569
sys.settrace(save_trace)
15661570
linecache.getlines=self.save_linecache_getlines
15671571
sys.displayhook=save_displayhook
1572+
traceback._can_colorize=saved_can_colorize
1573+
forkey,valueincolor_variables.items():
1574+
ifvalueisnotNone:
1575+
os.environ[key]=value
15681576
ifclear_globs:
15691577
test.globs.clear()
15701578
importbuiltins

‎Lib/idlelib/idle_test/test_run.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
fromunittestimportmock
99
importidlelib
1010
fromidlelib.idle_test.mock_idleimportFunc
11+
fromtest.supportimportforce_not_colorized
1112

1213
idlelib.testing=True# Use {} for executing test user code.
1314

@@ -46,6 +47,7 @@ def __eq__(self, other):
4647
"Did you mean: 'real'?\n"),
4748
)
4849

50+
@force_not_colorized
4951
deftest_get_message(self):
5052
forcode,exc,msginself.data:
5153
withself.subTest(code=code):
@@ -57,6 +59,7 @@ def test_get_message(self):
5759
expect=f'{exc.__name__}:{msg}'
5860
self.assertEqual(actual,expect)
5961

62+
@force_not_colorized
6063
@mock.patch.object(run,'cleanup_traceback',
6164
new_callable=lambda: (lambdat,e:None))
6265
deftest_get_multiple_message(self,mock):

‎Lib/test/support/__init__.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
"Py_DEBUG","exceeds_recursion_limit","get_c_recursion_limit",
6060
"skip_on_s390x",
6161
"without_optimizer",
62+
"force_not_colorized"
6263
]
6364

6465

@@ -2557,3 +2558,22 @@ def copy_python_src_ignore(path, names):
25572558
'build',
25582559
}
25592560
returnignored
2561+
2562+
defforce_not_colorized(func):
2563+
"""Force the terminal not to be colorized."""
2564+
@functools.wraps(func)
2565+
defwrapper(*args,**kwargs):
2566+
importtraceback
2567+
original_fn=traceback._can_colorize
2568+
variables= {"PYTHON_COLORS":None,"FORCE_COLOR":None}
2569+
try:
2570+
forkeyinvariables:
2571+
variables[key]=os.environ.pop(key,None)
2572+
traceback._can_colorize=lambda:False
2573+
returnfunc(*args,**kwargs)
2574+
finally:
2575+
traceback._can_colorize=original_fn
2576+
forkey,valueinvariables.items():
2577+
ifvalueisnotNone:
2578+
os.environ[key]=value
2579+
returnwrapper

‎Lib/test/test_cmd_line.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
importunittest
1111
fromtestimportsupport
1212
fromtest.supportimportos_helper
13+
fromtest.supportimportforce_not_colorized
1314
fromtest.support.script_helperimport (
1415
spawn_python,kill_python,assert_python_ok,assert_python_failure,
1516
interpreter_requires_environment
@@ -1027,6 +1028,7 @@ def test_sys_flags_not_set(self):
10271028

10281029

10291030
classSyntaxErrorTests(unittest.TestCase):
1031+
@force_not_colorized
10301032
defcheck_string(self,code):
10311033
proc=subprocess.run([sys.executable,"-"],input=code,
10321034
stdout=subprocess.PIPE,stderr=subprocess.PIPE)

‎Lib/test/test_exceptions.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
fromtest.supportimport (captured_stderr,check_impl_detail,
1313
cpython_only,gc_collect,
1414
no_tracing,script_helper,
15-
SuppressCrashReport)
15+
SuppressCrashReport,
16+
force_not_colorized)
1617
fromtest.support.import_helperimportimport_module
1718
fromtest.support.os_helperimportTESTFN,unlink
1819
fromtest.support.warnings_helperimportcheck_warnings
@@ -41,6 +42,7 @@ def __str__(self):
4142

4243
# XXX This is not really enough, each *operation* should be tested!
4344

45+
4446
classExceptionTests(unittest.TestCase):
4547

4648
defraise_catch(self,exc,excname):
@@ -1994,6 +1996,7 @@ def write_source(self, source):
19941996
_rc,_out,err=script_helper.assert_python_failure('-Wd','-X','utf8',TESTFN)
19951997
returnerr.decode('utf-8').splitlines()
19961998

1999+
@force_not_colorized
19972000
deftest_assertion_error_location(self):
19982001
cases= [
19992002
('assert None',
@@ -2070,6 +2073,7 @@ def test_assertion_error_location(self):
20702073
result=self.write_source(source)
20712074
self.assertEqual(result[-3:],expected)
20722075

2076+
@force_not_colorized
20732077
deftest_multiline_not_highlighted(self):
20742078
cases= [
20752079
("""
@@ -2102,6 +2106,7 @@ def test_multiline_not_highlighted(self):
21022106

21032107

21042108
classSyntaxErrorTests(unittest.TestCase):
2109+
@force_not_colorized
21052110
deftest_range_of_offsets(self):
21062111
cases= [
21072112
# Basic range from 2->7

‎Lib/test/test_interpreters/test_api.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
_interpreters=import_helper.import_module('_interpreters')
1313
fromtest.supportimportPy_GIL_DISABLED
1414
fromtest.supportimportinterpreters
15+
fromtest.supportimportforce_not_colorized
1516
fromtest.support.interpretersimport (
1617
InterpreterError,InterpreterNotFoundError,ExecutionFailed,
1718
)
@@ -735,6 +736,7 @@ def test_failure(self):
735736
withself.assertRaises(ExecutionFailed):
736737
interp.exec('raise Exception')
737738

739+
@force_not_colorized
738740
deftest_display_preserved_exception(self):
739741
tempdir=self.temp_dir()
740742
modfile=self.make_module('spam',tempdir,text="""

‎Lib/test/test_sys.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
fromtest.support.script_helperimportassert_python_ok,assert_python_failure
1717
fromtest.supportimportthreading_helper
1818
fromtest.supportimportimport_helper
19+
fromtest.supportimportforce_not_colorized
1920
try:
2021
fromtest.supportimportinterpreters
2122
exceptImportError:
@@ -145,6 +146,7 @@ def f():
145146

146147
classExceptHookTest(unittest.TestCase):
147148

149+
@force_not_colorized
148150
deftest_original_excepthook(self):
149151
try:
150152
raiseValueError(42)
@@ -156,6 +158,7 @@ def test_original_excepthook(self):
156158

157159
self.assertRaises(TypeError,sys.__excepthook__)
158160

161+
@force_not_colorized
159162
deftest_excepthook_bytes_filename(self):
160163
# bpo-37467: sys.excepthook() must not crash if a filename
161164
# is a bytes string
@@ -793,6 +796,7 @@ def test_sys_getwindowsversion_no_instantiation(self):
793796
deftest_clear_type_cache(self):
794797
sys._clear_type_cache()
795798

799+
@force_not_colorized
796800
@support.requires_subprocess()
797801
deftest_ioencoding(self):
798802
env=dict(os.environ)
@@ -1108,6 +1112,7 @@ def test_getandroidapilevel(self):
11081112
self.assertIsInstance(level,int)
11091113
self.assertGreater(level,0)
11101114

1115+
@force_not_colorized
11111116
@support.requires_subprocess()
11121117
deftest_sys_tracebacklimit(self):
11131118
code="""if 1:

‎Lib/test/test_threading.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
fromtest.supportimportverbose,cpython_only,os_helper
88
fromtest.support.import_helperimportimport_module
99
fromtest.support.script_helperimportassert_python_ok,assert_python_failure
10+
fromtest.supportimportforce_not_colorized
1011

1112
importrandom
1213
importsys
@@ -1793,6 +1794,7 @@ def setUp(self):
17931794
restore_default_excepthook(self)
17941795
super().setUp()
17951796

1797+
@force_not_colorized
17961798
deftest_excepthook(self):
17971799
withsupport.captured_output("stderr")asstderr:
17981800
thread=ThreadRunFail(name="excepthook thread")
@@ -1806,6 +1808,7 @@ def test_excepthook(self):
18061808
self.assertIn('ValueError: run failed',stderr)
18071809

18081810
@support.cpython_only
1811+
@force_not_colorized
18091812
deftest_excepthook_thread_None(self):
18101813
# threading.excepthook called with thread=None: log the thread
18111814
# identifier in this case.

‎Lib/test/test_traceback.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
fromtest.support.os_helperimportTESTFN,unlink
2222
fromtest.support.script_helperimportassert_python_ok,assert_python_failure
2323
fromtest.support.import_helperimportforget
24+
fromtest.supportimportforce_not_colorized
2425

2526
importjson
2627
importtextwrap
@@ -39,6 +40,13 @@
3940

4041
LEVENSHTEIN_DATA_FILE=Path(__file__).parent/'levenshtein_examples.json'
4142

43+
ORIGINAL_CAN_COLORIZE=traceback._can_colorize
44+
45+
defsetUpModule():
46+
traceback._can_colorize=lambda:False
47+
48+
deftearDownModule():
49+
traceback._can_colorize=ORIGINAL_CAN_COLORIZE
4250

4351
classTracebackCases(unittest.TestCase):
4452
# For now, a very minimal set of tests. I want to be sure that
@@ -124,6 +132,7 @@ def test_nocaret(self):
124132
self.assertEqual(len(err),3)
125133
self.assertEqual(err[1].strip(),"bad syntax")
126134

135+
@force_not_colorized
127136
deftest_no_caret_with_no_debug_ranges_flag(self):
128137
# Make sure that if `-X no_debug_ranges` is used, there are no carets
129138
# in the traceback.
@@ -401,7 +410,7 @@ def do_test(firstlines, message, charset, lineno):
401410
""".format(firstlines,message))
402411

403412
process=subprocess.Popen([sys.executable,TESTFN],
404-
stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
413+
stdout=subprocess.PIPE,stderr=subprocess.STDOUT,env={})
405414
stdout,stderr=process.communicate()
406415
stdout=stdout.decode(output_encoding).splitlines()
407416
finally:
@@ -4354,13 +4363,18 @@ def foo():
43544363
f'{boldm}ZeroDivisionError{reset}:{magenta}division by zero{reset}']
43554364
self.assertEqual(actual,expected)
43564365

4366+
@force_not_colorized
43574367
deftest_colorized_detection_checks_for_environment_variables(self):
43584368
ifsys.platform=="win32":
43594369
virtual_patching=unittest.mock.patch("nt._supports_virtual_terminal",return_value=True)
43604370
else:
43614371
virtual_patching=contextlib.nullcontext()
43624372
withvirtual_patching:
4363-
withunittest.mock.patch("os.isatty")asisatty_mock:
4373+
4374+
flags=unittest.mock.MagicMock(ignore_environment=False)
4375+
with (unittest.mock.patch("os.isatty")asisatty_mock,
4376+
unittest.mock.patch("sys.flags",flags),
4377+
unittest.mock.patch("traceback._can_colorize",ORIGINAL_CAN_COLORIZE)):
43644378
isatty_mock.return_value=True
43654379
withunittest.mock.patch("os.environ", {'TERM':'dumb'}):
43664380
self.assertEqual(traceback._can_colorize(),False)
@@ -4379,7 +4393,8 @@ def test_colorized_detection_checks_for_environment_variables(self):
43794393
withunittest.mock.patch("os.environ", {'FORCE_COLOR':'1',"PYTHON_COLORS":'0'}):
43804394
self.assertEqual(traceback._can_colorize(),False)
43814395
isatty_mock.return_value=False
4382-
self.assertEqual(traceback._can_colorize(),False)
4396+
withunittest.mock.patch("os.environ", {}):
4397+
self.assertEqual(traceback._can_colorize(),False)
43834398

43844399
if__name__=="__main__":
43854400
unittest.main()

‎Lib/test/test_tracemalloc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,7 @@ def check_env_var_invalid(self, nframe):
942942
withsupport.SuppressCrashReport():
943943
ok,stdout,stderr=assert_python_failure(
944944
'-c','pass',
945-
PYTHONTRACEMALLOC=str(nframe))
945+
PYTHONTRACEMALLOC=str(nframe),__cleanenv=True)
946946

947947
ifb'ValueError: the number of frames must be in range'instderr:
948948
return

‎Lib/test/test_warnings/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
fromtest.supportimportimport_helper
1313
fromtest.supportimportos_helper
1414
fromtest.supportimportwarnings_helper
15+
fromtest.supportimportforce_not_colorized
1516
fromtest.support.script_helperimportassert_python_ok,assert_python_failure
1617

1718
fromtest.test_warnings.dataimportpackage_helper
@@ -1239,6 +1240,7 @@ def test_comma_separated_warnings(self):
12391240
self.assertEqual(stdout,
12401241
b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']")
12411242

1243+
@force_not_colorized
12421244
deftest_envvar_and_command_line(self):
12431245
rc,stdout,stderr=assert_python_ok("-Wignore::UnicodeWarning","-c",
12441246
"import sys; sys.stdout.write(str(sys.warnoptions))",
@@ -1247,6 +1249,7 @@ def test_envvar_and_command_line(self):
12471249
self.assertEqual(stdout,
12481250
b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']")
12491251

1252+
@force_not_colorized
12501253
deftest_conflicting_envvar_and_command_line(self):
12511254
rc,stdout,stderr=assert_python_failure("-Werror::DeprecationWarning","-c",
12521255
"import sys, warnings; sys.stdout.write(str(sys.warnoptions)); "

‎Lib/traceback.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,24 +141,30 @@ def _can_colorize():
141141
returnFalse
142142
except (ImportError,AttributeError):
143143
returnFalse
144-
145-
ifos.environ.get("PYTHON_COLORS")=="0":
146-
returnFalse
147-
ifos.environ.get("PYTHON_COLORS")=="1":
148-
returnTrue
149-
if"NO_COLOR"inos.environ:
150-
returnFalse
144+
ifnotsys.flags.ignore_environment:
145+
ifos.environ.get("PYTHON_COLORS")=="0":
146+
returnFalse
147+
ifos.environ.get("PYTHON_COLORS")=="1":
148+
returnTrue
149+
if"NO_COLOR"inos.environ:
150+
returnFalse
151151
ifnot_COLORIZE:
152152
returnFalse
153-
if"FORCE_COLOR"inos.environ:
154-
returnTrue
155-
ifos.environ.get("TERM")=="dumb":
153+
ifnotsys.flags.ignore_environment:
154+
if"FORCE_COLOR"inos.environ:
155+
returnTrue
156+
ifos.environ.get("TERM")=="dumb":
157+
returnFalse
158+
159+
ifnothasattr(sys.stderr,"fileno"):
156160
returnFalse
161+
157162
try:
158163
returnos.isatty(sys.stderr.fileno())
159164
exceptio.UnsupportedOperation:
160165
returnsys.stderr.isatty()
161166

167+
162168
def_print_exception_bltin(exc,/):
163169
file=sys.stderrifsys.stderrisnotNoneelsesys.__stderr__
164170
colorize=_can_colorize()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp