24
24
from inspect import CO_COROUTINE
25
25
from itertools import product
26
26
from textwrap import dedent
27
- from types import AsyncGeneratorType , FunctionType
27
+ from types import AsyncGeneratorType , FunctionType , CellType
28
28
from operator import neg
29
29
from test import support
30
30
from test .support import (swap_attr , maybe_get_event_loop_policy )
@@ -94,7 +94,7 @@ def write(self, line):
94
94
('' , ValueError ),
95
95
(' ' , ValueError ),
96
96
(' \t \t ' , ValueError ),
97
- # (str(br'\u0663\u0661\u0664 ','raw-unicode-escape'), 314), XXX RustPython
97
+ (str (br'\u0663\u0661\u0664 ' ,'raw-unicode-escape' ), 314 ),
98
98
(chr (0x200 ), ValueError ),
99
99
]
100
100
@@ -116,7 +116,7 @@ def write(self, line):
116
116
('' , ValueError ),
117
117
(' ' , ValueError ),
118
118
(' \t \t ' , ValueError ),
119
- # (str(br'\u0663\u0661\u0664 ','raw-unicode-escape'), 314), XXX RustPython
119
+ (str (br'\u0663\u0661\u0664 ' ,'raw-unicode-escape' ), 314 ),
120
120
(chr (0x200 ), ValueError ),
121
121
]
122
122
@@ -161,7 +161,7 @@ def test_import(self):
161
161
__import__ ('string' )
162
162
__import__ (name = 'sys' )
163
163
__import__ (name = 'time' , level = 0 )
164
- self .assertRaises (ImportError , __import__ , 'spamspam' )
164
+ self .assertRaises (ModuleNotFoundError , __import__ , 'spamspam' )
165
165
self .assertRaises (TypeError , __import__ , 1 , 2 , 3 , 4 )
166
166
self .assertRaises (ValueError , __import__ , '' )
167
167
self .assertRaises (TypeError , __import__ , 'sys' , name = 'sys' )
@@ -403,6 +403,10 @@ def test_compile_top_level_await_no_coro(self):
403
403
404
404
# TODO: RUSTPYTHON
405
405
@unittest .expectedFailure
406
+ @unittest .skipIf (
407
+ support .is_emscripten or support .is_wasi ,
408
+ "socket.accept is broken"
409
+ )
406
410
def test_compile_top_level_await (self ):
407
411
"""Test whether code some top level await can be compiled.
408
412
@@ -519,10 +523,15 @@ def test_compile_async_generator(self):
519
523
exec (co , glob )
520
524
self .assertEqual (type (glob ['ticker' ]()), AsyncGeneratorType )
521
525
526
+ # TODO: RUSTPYTHON
527
+ @unittest .expectedFailure
522
528
def test_delattr (self ):
523
529
sys .spam = 1
524
530
delattr (sys , 'spam' )
525
531
self .assertRaises (TypeError , delattr )
532
+ self .assertRaises (TypeError , delattr , sys )
533
+ msg = r"^attribute name must be string, not 'int'$"
534
+ self .assertRaisesRegex (TypeError , msg , delattr , sys , 1 )
526
535
527
536
# TODO: RUSTPYTHON
528
537
@unittest .expectedFailure
@@ -748,11 +757,9 @@ def test_exec_globals(self):
748
757
self .assertRaises (TypeError ,
749
758
exec , code , {'__builtins__' : 123 })
750
759
751
- # no __build_class__ function
752
- code = compile ("class A: pass" , "" , "exec" )
753
- self .assertRaisesRegex (NameError , "__build_class__ not found" ,
754
- exec , code , {'__builtins__' : {}})
755
-
760
+ # TODO: RUSTPYTHON
761
+ @unittest .expectedFailure
762
+ def test_exec_globals_frozen (self ):
756
763
class frozendict_error (Exception ):
757
764
pass
758
765
@@ -769,12 +776,55 @@ def __setitem__(self, key, value):
769
776
self .assertRaises (frozendict_error ,
770
777
exec , code , {'__builtins__' : frozen_builtins })
771
778
779
+ # no __build_class__ function
780
+ code = compile ("class A: pass" , "" , "exec" )
781
+ self .assertRaisesRegex (NameError , "__build_class__ not found" ,
782
+ exec , code , {'__builtins__' : {}})
783
+ # __build_class__ in a custom __builtins__
784
+ exec (code , {'__builtins__' : frozen_builtins })
785
+ self .assertRaisesRegex (NameError , "__build_class__ not found" ,
786
+ exec , code , {'__builtins__' : frozendict ()})
787
+
772
788
# read-only globals
773
789
namespace = frozendict ({})
774
790
code = compile ("x=1" , "test" , "exec" )
775
791
self .assertRaises (frozendict_error ,
776
792
exec , code , namespace )
777
793
794
+ # TODO: RUSTPYTHON
795
+ @unittest .expectedFailure
796
+ def test_exec_globals_error_on_get (self ):
797
+ # custom `globals` or `builtins` can raise errors on item access
798
+ class setonlyerror (Exception ):
799
+ pass
800
+
801
+ class setonlydict (dict ):
802
+ def __getitem__ (self , key ):
803
+ raise setonlyerror
804
+
805
+ # globals' `__getitem__` raises
806
+ code = compile ("globalname" , "test" , "exec" )
807
+ self .assertRaises (setonlyerror ,
808
+ exec , code , setonlydict ({'globalname' : 1 }))
809
+
810
+ # builtins' `__getitem__` raises
811
+ code = compile ("superglobal" , "test" , "exec" )
812
+ self .assertRaises (setonlyerror , exec , code ,
813
+ {'__builtins__' : setonlydict ({'superglobal' : 1 })})
814
+
815
+ # TODO: RUSTPYTHON
816
+ @unittest .expectedFailure
817
+ def test_exec_globals_dict_subclass (self ):
818
+ class customdict (dict ): # this one should not do anything fancy
819
+ pass
820
+
821
+ code = compile ("superglobal" , "test" , "exec" )
822
+ # works correctly
823
+ exec (code , {'__builtins__' : customdict ({'superglobal' : 1 })})
824
+ # custom builtins dict subclass is missing key
825
+ self .assertRaisesRegex (NameError , "name 'superglobal' is not defined" ,
826
+ exec , code , {'__builtins__' : customdict ()})
827
+
778
828
def test_exec_redirected (self ):
779
829
savestdout = sys .stdout
780
830
sys .stdout = None # Whatever that cannot flush()
@@ -786,6 +836,86 @@ def test_exec_redirected(self):
786
836
finally :
787
837
sys .stdout = savestdout
788
838
839
+ # TODO: RUSTPYTHON
840
+ @unittest .expectedFailure
841
+ def test_exec_closure (self ):
842
+ def function_without_closures ():
843
+ return 3 * 5
844
+
845
+ result = 0
846
+ def make_closure_functions ():
847
+ a = 2
848
+ b = 3
849
+ c = 5
850
+ def three_freevars ():
851
+ nonlocal result
852
+ nonlocal a
853
+ nonlocal b
854
+ result = a * b
855
+ def four_freevars ():
856
+ nonlocal result
857
+ nonlocal a
858
+ nonlocal b
859
+ nonlocal c
860
+ result = a * b * c
861
+ return three_freevars , four_freevars
862
+ three_freevars , four_freevars = make_closure_functions ()
863
+
864
+ # "smoke" test
865
+ result = 0
866
+ exec (three_freevars .__code__ ,
867
+ three_freevars .__globals__ ,
868
+ closure = three_freevars .__closure__ )
869
+ self .assertEqual (result , 6 )
870
+
871
+ # should also work with a manually created closure
872
+ result = 0
873
+ my_closure = (CellType (35 ), CellType (72 ), three_freevars .__closure__ [2 ])
874
+ exec (three_freevars .__code__ ,
875
+ three_freevars .__globals__ ,
876
+ closure = my_closure )
877
+ self .assertEqual (result , 2520 )
878
+
879
+ # should fail: closure isn't allowed
880
+ # for functions without free vars
881
+ self .assertRaises (TypeError ,
882
+ exec ,
883
+ function_without_closures .__code__ ,
884
+ function_without_closures .__globals__ ,
885
+ closure = my_closure )
886
+
887
+ # should fail: closure required but wasn't specified
888
+ self .assertRaises (TypeError ,
889
+ exec ,
890
+ three_freevars .__code__ ,
891
+ three_freevars .__globals__ ,
892
+ closure = None )
893
+
894
+ # should fail: closure of wrong length
895
+ self .assertRaises (TypeError ,
896
+ exec ,
897
+ three_freevars .__code__ ,
898
+ three_freevars .__globals__ ,
899
+ closure = four_freevars .__closure__ )
900
+
901
+ # should fail: closure using a list instead of a tuple
902
+ my_closure = list (my_closure )
903
+ self .assertRaises (TypeError ,
904
+ exec ,
905
+ three_freevars .__code__ ,
906
+ three_freevars .__globals__ ,
907
+ closure = my_closure )
908
+
909
+ # should fail: closure tuple with one non-cell-var
910
+ my_closure [0 ] = int
911
+ my_closure = tuple (my_closure )
912
+ self .assertRaises (TypeError ,
913
+ exec ,
914
+ three_freevars .__code__ ,
915
+ three_freevars .__globals__ ,
916
+ closure = my_closure )
917
+
918
+
789
919
def test_filter (self ):
790
920
self .assertEqual (list (filter (lambda c : 'a' <= c <= 'z' , 'Hello World' )), list ('elloorld' ))
791
921
self .assertEqual (list (filter (None , [1 , 'hello' , [], [3 ], '' , None , 9 , 0 ])), [1 , 'hello' , [3 ], 9 ])
@@ -817,19 +947,27 @@ def test_filter_pickle(self):
817
947
f2 = filter (filter_char , "abcdeabcde" )
818
948
self .check_iter_pickle (f1 , list (f2 ), proto )
819
949
950
+ # TODO: RUSTPYTHON
951
+ @unittest .expectedFailure
820
952
def test_getattr (self ):
821
953
self .assertTrue (getattr (sys , 'stdout' ) is sys .stdout )
822
- self .assertRaises (TypeError , getattr , sys , 1 )
823
- self .assertRaises (TypeError , getattr , sys , 1 , "foo" )
824
954
self .assertRaises (TypeError , getattr )
955
+ self .assertRaises (TypeError , getattr , sys )
956
+ msg = r"^attribute name must be string, not 'int'$"
957
+ self .assertRaisesRegex (TypeError , msg , getattr , sys , 1 )
958
+ self .assertRaisesRegex (TypeError , msg , getattr , sys , 1 , 'spam' )
825
959
self .assertRaises (AttributeError , getattr , sys , chr (sys .maxunicode ))
826
960
# unicode surrogates are not encodable to the default encoding (utf8)
827
961
self .assertRaises (AttributeError , getattr , 1 , "\uDAD1 \uD51E " )
828
962
963
+ # TODO: RUSTPYTHON
964
+ @unittest .expectedFailure
829
965
def test_hasattr (self ):
830
966
self .assertTrue (hasattr (sys , 'stdout' ))
831
- self .assertRaises (TypeError , hasattr , sys , 1 )
832
967
self .assertRaises (TypeError , hasattr )
968
+ self .assertRaises (TypeError , hasattr , sys )
969
+ msg = r"^attribute name must be string, not 'int'$"
970
+ self .assertRaisesRegex (TypeError , msg , hasattr , sys , 1 )
833
971
self .assertEqual (False , hasattr (sys , chr (sys .maxunicode )))
834
972
835
973
# Check that hasattr propagates all exceptions outside of
@@ -1216,7 +1354,7 @@ def test_open_default_encoding(self):
1216
1354
del os .environ [key ]
1217
1355
1218
1356
self .write_testfile ()
1219
- current_locale_encoding = locale .getpreferredencoding ( False )
1357
+ current_locale_encoding = locale .getencoding ( )
1220
1358
with warnings .catch_warnings ():
1221
1359
warnings .simplefilter ("ignore" , EncodingWarning )
1222
1360
fp = open (TESTFN , 'w' )
@@ -1227,6 +1365,7 @@ def test_open_default_encoding(self):
1227
1365
os .environ .update (old_environ )
1228
1366
1229
1367
@unittest .skipIf (sys .platform == 'win32' , 'TODO: RUSTPYTHON Windows' )
1368
+ @support .requires_subprocess ()
1230
1369
def test_open_non_inheritable (self ):
1231
1370
fileobj = open (__file__ , encoding = "utf-8" )
1232
1371
with fileobj :
@@ -1475,11 +1614,16 @@ def test_bug_27936(self):
1475
1614
self .assertEqual (round (x , None ), round (x ))
1476
1615
self .assertEqual (type (round (x , None )), type (round (x )))
1477
1616
1617
+ # TODO: RUSTPYTHON
1618
+ @unittest .expectedFailure
1478
1619
def test_setattr (self ):
1479
1620
setattr (sys , 'spam' , 1 )
1480
1621
self .assertEqual (sys .spam , 1 )
1481
- self .assertRaises (TypeError , setattr , sys , 1 , 'spam' )
1482
1622
self .assertRaises (TypeError , setattr )
1623
+ self .assertRaises (TypeError , setattr , sys )
1624
+ self .assertRaises (TypeError , setattr , sys , 'spam' )
1625
+ msg = r"^attribute name must be string, not 'int'$"
1626
+ self .assertRaisesRegex (TypeError , msg , setattr , sys , 1 , 'spam' )
1483
1627
1484
1628
# test_str(): see test_unicode.py and test_bytes.py for str() tests.
1485
1629
@@ -1998,10 +2142,6 @@ def test_envar_ignored_when_hook_is_set(self):
1998
2142
breakpoint ()
1999
2143
mock .assert_not_called ()
2000
2144
2001
- def test_runtime_error_when_hook_is_lost (self ):
2002
- del sys .breakpointhook
2003
- with self .assertRaises (RuntimeError ):
2004
- breakpoint ()
2005
2145
2006
2146
@unittest .skipUnless (pty , "the pty and signal modules must be available" )
2007
2147
class PtyTests (unittest .TestCase ):
@@ -2270,6 +2410,8 @@ def test_type_nokwargs(self):
2270
2410
with self .assertRaises (TypeError ):
2271
2411
type ('a' , (), dict = {})
2272
2412
2413
+ # TODO: RUSTPYTHON
2414
+ @unittest .expectedFailure
2273
2415
def test_type_name (self ):
2274
2416
for name in 'A' , '\xc4 ' , '\U0001f40d ' , 'B.A' , '42' , '' :
2275
2417
with self .subTest (name = name ):
@@ -2279,10 +2421,8 @@ def test_type_name(self):
2279
2421
self .assertEqual (A .__module__ , __name__ )
2280
2422
with self .assertRaises (ValueError ):
2281
2423
type ('A\x00 B' , (), {})
2282
- # TODO: RUSTPYTHON (https://github.com/RustPython/RustPython/issues/935)
2283
- with self .assertRaises (AssertionError ):
2284
- with self .assertRaises (ValueError ):
2285
- type ('A\udcdc B' , (), {})
2424
+ with self .assertRaises (UnicodeEncodeError ):
2425
+ type ('A\udcdc B' , (), {})
2286
2426
with self .assertRaises (TypeError ):
2287
2427
type (b'A' , (), {})
2288
2428
@@ -2298,13 +2438,9 @@ def test_type_name(self):
2298
2438
with self .assertRaises (ValueError ):
2299
2439
A .__name__ = 'A\x00 B'
2300
2440
self .assertEqual (A .__name__ , 'C' )
2301
- # TODO: RUSTPYTHON (https://github.com/RustPython/RustPython/issues/935)
2302
- with self .assertRaises (AssertionError ):
2303
- with self .assertRaises (ValueError ):
2304
- A .__name__ = 'A\udcdc B'
2305
- self .assertEqual (A .__name__ , 'C' )
2306
- # TODO: RUSTPYTHON: the previous __name__ set should fail but doesn't: reset it
2307
- A .__name__ = 'C'
2441
+ with self .assertRaises (UnicodeEncodeError ):
2442
+ A .__name__ = 'A\udcdc B'
2443
+ self .assertEqual (A .__name__ , 'C' )
2308
2444
with self .assertRaises (TypeError ):
2309
2445
A .__name__ = b'A'
2310
2446
self .assertEqual (A .__name__ , 'C' )
0 commit comments