10
10
import unittest
11
11
from test import support
12
12
from test .support import os_helper
13
+ from test .support import force_not_colorized
13
14
from test .support .script_helper import (
14
15
spawn_python , kill_python , assert_python_ok , assert_python_failure ,
15
16
interpreter_requires_environment
@@ -38,8 +39,7 @@ def verify_valid_flag(self, cmd_line):
38
39
self .assertNotIn (b'Traceback' , err )
39
40
return out
40
41
41
- # TODO: RUSTPYTHON
42
- @unittest .expectedFailure
42
+ @support .cpython_only
43
43
def test_help (self ):
44
44
self .verify_valid_flag ('-h' )
45
45
self .verify_valid_flag ('-?' )
@@ -50,20 +50,17 @@ def test_help(self):
50
50
self .assertNotIn (b'-X dev' , out )
51
51
self .assertLess (len (lines ), 50 )
52
52
53
- # TODO: RUSTPYTHON
54
- @unittest .expectedFailure
53
+ @support .cpython_only
55
54
def test_help_env (self ):
56
55
out = self .verify_valid_flag ('--help-env' )
57
56
self .assertIn (b'PYTHONHOME' , out )
58
57
59
- # TODO: RUSTPYTHON
60
- @unittest .expectedFailure
58
+ @support .cpython_only
61
59
def test_help_xoptions (self ):
62
60
out = self .verify_valid_flag ('--help-xoptions' )
63
61
self .assertIn (b'-X dev' , out )
64
62
65
- # TODO: RUSTPYTHON
66
- @unittest .expectedFailure
63
+ @support .cpython_only
67
64
def test_help_all (self ):
68
65
out = self .verify_valid_flag ('--help-all' )
69
66
lines = out .splitlines ()
@@ -82,15 +79,16 @@ def test_optimize(self):
82
79
def test_site_flag (self ):
83
80
self .verify_valid_flag ('-S' )
84
81
85
- # NOTE: RUSTPYTHON version never starts with Python
86
- @unittest .expectedFailure
82
+ @support .cpython_only
87
83
def test_version (self ):
88
84
version = ('Python %d.%d' % sys .version_info [:2 ]).encode ("ascii" )
89
85
for switch in '-V' , '--version' , '-VV' :
90
86
rc , out , err = assert_python_ok (switch )
91
87
self .assertFalse (err .startswith (version ))
92
88
self .assertTrue (out .startswith (version ))
93
89
90
+ # TODO: RUSTPYTHON
91
+ @unittest .expectedFailure
94
92
def test_verbose (self ):
95
93
# -v causes imports to write to stderr. If the write to
96
94
# stderr itself causes an import to happen (for the output
@@ -149,8 +147,7 @@ def run_python(*args):
149
147
else :
150
148
self .assertEqual (err , b'' )
151
149
152
- # TODO: RUSTPYTHON
153
- @unittest .expectedFailure
150
+ @support .cpython_only
154
151
def test_xoption_frozen_modules (self ):
155
152
tests = {
156
153
('=on' , 'FrozenImporter' ),
@@ -165,6 +162,18 @@ def test_xoption_frozen_modules(self):
165
162
res = assert_python_ok (* cmd )
166
163
self .assertRegex (res .out .decode ('utf-8' ), expected )
167
164
165
+ @support .cpython_only
166
+ def test_env_var_frozen_modules (self ):
167
+ tests = {
168
+ ('on' , 'FrozenImporter' ),
169
+ ('off' , 'SourceFileLoader' ),
170
+ }
171
+ for raw , expected in tests :
172
+ cmd = ['-c' , 'import os; print(os.__spec__.loader, end="")' ]
173
+ with self .subTest (raw ):
174
+ res = assert_python_ok (* cmd , PYTHON_FROZEN_MODULES = raw )
175
+ self .assertRegex (res .out .decode ('utf-8' ), expected )
176
+
168
177
def test_run_module (self ):
169
178
# Test expected operation of the '-m' switch
170
179
# Switch needs an argument
@@ -226,8 +235,6 @@ def test_coding(self):
226
235
# command line, but how subprocess does decode bytes to unicode. Python
227
236
# doesn't decode the command line because Windows provides directly the
228
237
# arguments as unicode (using wmain() instead of main()).
229
- # TODO: RUSTPYTHON
230
- @unittest .expectedFailure
231
238
@unittest .skipIf (sys .platform == 'win32' ,
232
239
'Windows has a native unicode API' )
233
240
def test_undecodable_code (self ):
@@ -263,7 +270,6 @@ def test_undecodable_code(self):
263
270
if not stdout .startswith (pattern ):
264
271
raise AssertionError ("%a doesn't start with %a" % (stdout , pattern ))
265
272
266
- @unittest .skip ("TODO: RUSTPYTHON, thread 'main' panicked at 'unexpected invalid UTF-8 code point'" )
267
273
@unittest .skipIf (sys .platform == 'win32' ,
268
274
'Windows has a native unicode API' )
269
275
def test_invalid_utf8_arg (self ):
@@ -275,20 +281,17 @@ def test_invalid_utf8_arg(self):
275
281
# Test with default config, in the C locale, in the Python UTF-8 Mode.
276
282
code = 'import sys, os; s=os.fsencode(sys.argv[1]); print(ascii(s))'
277
283
278
- # TODO: RUSTPYTHON
279
284
def run_default (arg ):
280
285
cmd = [sys .executable , '-c' , code , arg ]
281
286
return subprocess .run (cmd , stdout = subprocess .PIPE , text = True )
282
287
283
- # TODO: RUSTPYTHON
284
288
def run_c_locale (arg ):
285
289
cmd = [sys .executable , '-c' , code , arg ]
286
290
env = dict (os .environ )
287
291
env ['LC_ALL' ] = 'C'
288
292
return subprocess .run (cmd , stdout = subprocess .PIPE ,
289
293
text = True , env = env )
290
294
291
- # TODO: RUSTPYTHON
292
295
def run_utf8_mode (arg ):
293
296
cmd = [sys .executable , '-X' , 'utf8' , '-c' , code , arg ]
294
297
return subprocess .run (cmd , stdout = subprocess .PIPE , text = True )
@@ -402,8 +405,7 @@ def test_empty_PYTHONPATH_issue16309(self):
402
405
path = ":".join(sys.path)
403
406
path = path.encode("ascii", "backslashreplace")
404
407
sys.stdout.buffer.write(path)"""
405
- # TODO: RUSTPYTHON we must unset RUSTPYTHONPATH as well
406
- rc1 , out1 , err1 = assert_python_ok ('-c' , code , PYTHONPATH = "" , RUSTPYTHONPATH = "" )
408
+ rc1 , out1 , err1 = assert_python_ok ('-c' , code , PYTHONPATH = "" )
407
409
rc2 , out2 , err2 = assert_python_ok ('-c' , code , __isolated = False )
408
410
# regarding to Posix specification, outputs should be equal
409
411
# for empty and unset PYTHONPATH
@@ -491,8 +493,9 @@ def test_stdout_flush_at_shutdown(self):
491
493
rc , out , err = assert_python_failure ('-c' , code )
492
494
self .assertEqual (b'' , out )
493
495
self .assertEqual (120 , rc )
494
- self .assertRegex (err .decode ('ascii' , 'ignore' ),
495
- 'Exception ignored in.*\n OSError: .*' )
496
+ self .assertIn (b'Exception ignored on flushing sys.stdout:\n '
497
+ b'OSError: ' .replace (b'\n ' , os .linesep .encode ()),
498
+ err )
496
499
497
500
def test_closed_stdout (self ):
498
501
# Issue #13444: if stdout has been explicitly closed, we should
@@ -600,8 +603,7 @@ def test_del___main__(self):
600
603
print ("del sys.modules['__main__']" , file = script )
601
604
assert_python_ok (filename )
602
605
603
- # TODO: RUSTPYTHON
604
- @unittest .expectedFailure
606
+ @support .cpython_only
605
607
def test_unknown_options (self ):
606
608
rc , out , err = assert_python_failure ('-E' , '-z' )
607
609
self .assertIn (b'Unknown option: -z' , err )
@@ -648,6 +650,8 @@ def test_isolatedmode(self):
648
650
cwd = tmpdir )
649
651
self .assertEqual (out .strip (), b"ok" )
650
652
653
+ # TODO: RUSTPYTHON
654
+ @unittest .expectedFailure
651
655
def test_sys_flags_set (self ):
652
656
# Issue 31845: a startup refactoring broke reading flags from env vars
653
657
for value , expected in (("" , 0 ), ("1" , 1 ), ("text" , 1 ), ("2" , 2 )):
@@ -657,15 +661,13 @@ def test_sys_flags_set(self):
657
661
PYTHONDONTWRITEBYTECODE = value ,
658
662
PYTHONVERBOSE = value ,
659
663
)
660
- dont_write_bytecode = int (bool (value ))
664
+ expected_bool = int (bool (value ))
661
665
code = (
662
666
"import sys; "
663
667
"sys.stderr.write(str(sys.flags)); "
664
668
f"""sys.exit(not (
665
- sys.flags.debug == sys.flags.optimize ==
666
- sys.flags.verbose ==
667
- { expected }
668
- and sys.flags.dont_write_bytecode == { dont_write_bytecode }
669
+ sys.flags.optimize == sys.flags.verbose == { expected }
670
+ and sys.flags.debug == sys.flags.dont_write_bytecode == { expected_bool }
669
671
))"""
670
672
)
671
673
with self .subTest (envar_value = value ):
@@ -718,8 +720,7 @@ def run_xdev(self, *args, check_exitcode=True, xdev=True):
718
720
self .assertEqual (proc .returncode , 0 , proc )
719
721
return proc .stdout .rstrip ()
720
722
721
- # TODO: RUSTPYTHON
722
- @unittest .expectedFailure
723
+ @support .cpython_only
723
724
def test_xdev (self ):
724
725
# sys.flags.dev_mode
725
726
code = "import sys; print(sys.flags.dev_mode)"
@@ -756,15 +757,17 @@ def test_xdev(self):
756
757
757
758
# Memory allocator debug hooks
758
759
try :
759
- import _testcapi
760
+ import _testinternalcapi
760
761
except ImportError :
761
762
pass
762
763
else :
763
- code = "import _testcapi ; print(_testcapi .pymem_getallocatorsname())"
764
+ code = "import _testinternalcapi ; print(_testinternalcapi .pymem_getallocatorsname())"
764
765
with support .SuppressCrashReport ():
765
766
out = self .run_xdev ("-c" , code , check_exitcode = False )
766
767
if support .with_pymalloc ():
767
768
alloc_name = "pymalloc_debug"
769
+ elif support .Py_GIL_DISABLED :
770
+ alloc_name = "mimalloc_debug"
768
771
else :
769
772
alloc_name = "malloc_debug"
770
773
self .assertEqual (out , alloc_name )
@@ -824,7 +827,7 @@ def test_warnings_filter_precedence(self):
824
827
self .assertEqual (out , expected_filters )
825
828
826
829
def check_pythonmalloc (self , env_var , name ):
827
- code = 'import _testcapi ; print(_testcapi .pymem_getallocatorsname())'
830
+ code = 'import _testinternalcapi ; print(_testinternalcapi .pymem_getallocatorsname())'
828
831
env = dict (os .environ )
829
832
env .pop ('PYTHONDEVMODE' , None )
830
833
if env_var is not None :
@@ -840,12 +843,16 @@ def check_pythonmalloc(self, env_var, name):
840
843
self .assertEqual (proc .stdout .rstrip (), name )
841
844
self .assertEqual (proc .returncode , 0 )
842
845
843
- # TODO: RUSTPYTHON
844
- @unittest .expectedFailure
846
+ @support .cpython_only
845
847
def test_pythonmalloc (self ):
846
848
# Test the PYTHONMALLOC environment variable
849
+ malloc = not support .Py_GIL_DISABLED
847
850
pymalloc = support .with_pymalloc ()
848
- if pymalloc :
851
+ mimalloc = support .with_mimalloc ()
852
+ if support .Py_GIL_DISABLED :
853
+ default_name = 'mimalloc_debug' if support .Py_DEBUG else 'mimalloc'
854
+ default_name_debug = 'mimalloc_debug'
855
+ elif pymalloc :
849
856
default_name = 'pymalloc_debug' if support .Py_DEBUG else 'pymalloc'
850
857
default_name_debug = 'pymalloc_debug'
851
858
else :
@@ -855,14 +862,22 @@ def test_pythonmalloc(self):
855
862
tests = [
856
863
(None , default_name ),
857
864
('debug' , default_name_debug ),
858
- ('malloc' , 'malloc' ),
859
- ('malloc_debug' , 'malloc_debug' ),
860
865
]
866
+ if malloc :
867
+ tests .extend ([
868
+ ('malloc' , 'malloc' ),
869
+ ('malloc_debug' , 'malloc_debug' ),
870
+ ])
861
871
if pymalloc :
862
872
tests .extend ((
863
873
('pymalloc' , 'pymalloc' ),
864
874
('pymalloc_debug' , 'pymalloc_debug' ),
865
875
))
876
+ if mimalloc :
877
+ tests .extend ((
878
+ ('mimalloc' , 'mimalloc' ),
879
+ ('mimalloc_debug' , 'mimalloc_debug' ),
880
+ ))
866
881
867
882
for env_var , name in tests :
868
883
with self .subTest (env_var = env_var , name = name ):
@@ -888,6 +903,51 @@ def test_pythondevmode_env(self):
888
903
self .assertEqual (proc .stdout .rstrip (), 'True' )
889
904
self .assertEqual (proc .returncode , 0 , proc )
890
905
906
+ # TODO: RUSTPYTHON
907
+ @unittest .expectedFailure
908
+ def test_python_gil (self ):
909
+ cases = [
910
+ # (env, opt, expected, msg)
911
+ ('1' , None , '1' , "PYTHON_GIL=1" ),
912
+ (None , '1' , '1' , "-X gil=1" ),
913
+ ]
914
+
915
+ if support .Py_GIL_DISABLED :
916
+ cases .extend (
917
+ [
918
+ (None , None , 'None' , "no options set" ),
919
+ ('0' , None , '0' , "PYTHON_GIL=0" ),
920
+ ('1' , '0' , '0' , "-X gil=0 overrides PYTHON_GIL=1" ),
921
+ (None , '0' , '0' , "-X gil=0" ),
922
+ ]
923
+ )
924
+ else :
925
+ cases .extend (
926
+ [
927
+ (None , None , '1' , '-X gil=0 (unsupported by this build)' ),
928
+ ('1' , None , '1' , 'PYTHON_GIL=0 (unsupported by this build)' ),
929
+ ]
930
+ )
931
+ code = "import sys; print(sys.flags.gil)"
932
+ environ = dict (os .environ )
933
+
934
+ for env , opt , expected , msg in cases :
935
+ with self .subTest (msg , env = env , opt = opt ):
936
+ environ .pop ('PYTHON_GIL' , None )
937
+ if env is not None :
938
+ environ ['PYTHON_GIL' ] = env
939
+ extra_args = []
940
+ if opt is not None :
941
+ extra_args = ['-X' , f'gil={ opt } ' ]
942
+
943
+ proc = subprocess .run ([sys .executable , * extra_args , '-c' , code ],
944
+ stdout = subprocess .PIPE ,
945
+ stderr = subprocess .PIPE ,
946
+ text = True , env = environ )
947
+ self .assertEqual (proc .returncode , 0 , proc )
948
+ self .assertEqual (proc .stdout .rstrip (), expected )
949
+ self .assertEqual (proc .stderr , '' )
950
+
891
951
@unittest .skipUnless (sys .platform == 'win32' ,
892
952
'bpo-32457 only applies on Windows' )
893
953
def test_argv0_normalization (self ):
@@ -900,8 +960,7 @@ def test_argv0_normalization(self):
900
960
self .assertEqual (proc .returncode , 0 , proc )
901
961
self .assertEqual (proc .stdout .strip (), b'0' )
902
962
903
- # TODO: RUSTPYTHON
904
- @unittest .expectedFailure
963
+ @support .cpython_only
905
964
def test_parsing_error (self ):
906
965
args = [sys .executable , '-I' , '--unknown-option' ]
907
966
proc = subprocess .run (args ,
@@ -924,11 +983,8 @@ def test_int_max_str_digits(self):
924
983
assert_python_failure ('-c' , code , PYTHONINTMAXSTRDIGITS = 'foo' )
925
984
assert_python_failure ('-c' , code , PYTHONINTMAXSTRDIGITS = '100' )
926
985
927
- def res2int (res ):
928
- out = res .out .strip ().decode ("utf-8" )
929
- return tuple (int (i ) for i in out .split ())
930
-
931
986
res = assert_python_ok ('-c' , code )
987
+ res2int = self .res2int
932
988
current_max = sys .get_int_max_str_digits ()
933
989
self .assertEqual (res2int (res ), (current_max , current_max ))
934
990
res = assert_python_ok ('-X' , 'int_max_str_digits=0' , '-c' , code )
@@ -948,6 +1004,30 @@ def res2int(res):
948
1004
)
949
1005
self .assertEqual (res2int (res ), (6000 , 6000 ))
950
1006
1007
+ # TODO: RUSTPYTHON
1008
+ @unittest .expectedFailure
1009
+ def test_cpu_count (self ):
1010
+ code = "import os; print(os.cpu_count(), os.process_cpu_count())"
1011
+ res = assert_python_ok ('-X' , 'cpu_count=4321' , '-c' , code )
1012
+ self .assertEqual (self .res2int (res ), (4321 , 4321 ))
1013
+ res = assert_python_ok ('-c' , code , PYTHON_CPU_COUNT = '1234' )
1014
+ self .assertEqual (self .res2int (res ), (1234 , 1234 ))
1015
+
1016
+ # TODO: RUSTPYTHON
1017
+ @unittest .expectedFailure
1018
+ def test_cpu_count_default (self ):
1019
+ code = "import os; print(os.cpu_count(), os.process_cpu_count())"
1020
+ res = assert_python_ok ('-X' , 'cpu_count=default' , '-c' , code )
1021
+ self .assertEqual (self .res2int (res ), (os .cpu_count (), os .process_cpu_count ()))
1022
+ res = assert_python_ok ('-X' , 'cpu_count=default' , '-c' , code , PYTHON_CPU_COUNT = '1234' )
1023
+ self .assertEqual (self .res2int (res ), (os .cpu_count (), os .process_cpu_count ()))
1024
+ es = assert_python_ok ('-c' , code , PYTHON_CPU_COUNT = 'default' )
1025
+ self .assertEqual (self .res2int (res ), (os .cpu_count (), os .process_cpu_count ()))
1026
+
1027
+ def res2int (self , res ):
1028
+ out = res .out .strip ().decode ("utf-8" )
1029
+ return tuple (int (i ) for i in out .split ())
1030
+
951
1031
952
1032
@unittest .skipIf (interpreter_requires_environment (),
953
1033
'Cannot run -I tests when PYTHON env vars are required.' )
@@ -990,6 +1070,7 @@ def test_sys_flags_not_set(self):
990
1070
991
1071
992
1072
class SyntaxErrorTests (unittest .TestCase ):
1073
+ @force_not_colorized
993
1074
def check_string (self , code ):
994
1075
proc = subprocess .run ([sys .executable , "-" ], input = code ,
995
1076
stdout = subprocess .PIPE , stderr = subprocess .PIPE )
0 commit comments