2424from inspect import CO_COROUTINE
2525from itertools import product
2626from textwrap import dedent
27- from types import AsyncGeneratorType , FunctionType
27+ from types import AsyncGeneratorType , FunctionType , CellType
2828from operator import neg
2929from test import support
3030from test .support import (swap_attr , maybe_get_event_loop_policy )
@@ -94,7 +94,7 @@ def write(self, line):
9494 ('' , ValueError ),
9595 (' ' , ValueError ),
9696 (' \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 ),
9898 (chr (0x200 ), ValueError ),
9999]
100100
@@ -116,7 +116,7 @@ def write(self, line):
116116 ('' , ValueError ),
117117 (' ' , ValueError ),
118118 (' \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 ),
120120 (chr (0x200 ), ValueError ),
121121]
122122
@@ -161,7 +161,7 @@ def test_import(self):
161161 __import__ ('string' )
162162 __import__ (name = 'sys' )
163163 __import__ (name = 'time' , level = 0 )
164- self .assertRaises (ImportError , __import__ , 'spamspam' )
164+ self .assertRaises (ModuleNotFoundError , __import__ , 'spamspam' )
165165 self .assertRaises (TypeError , __import__ , 1 , 2 , 3 , 4 )
166166 self .assertRaises (ValueError , __import__ , '' )
167167 self .assertRaises (TypeError , __import__ , 'sys' , name = 'sys' )
@@ -403,6 +403,10 @@ def test_compile_top_level_await_no_coro(self):
403403
404404 # TODO: RUSTPYTHON
405405 @unittest .expectedFailure
406+ @unittest .skipIf (
407+ support .is_emscripten or support .is_wasi ,
408+ "socket.accept is broken"
409+ )
406410 def test_compile_top_level_await (self ):
407411 """Test whether code some top level await can be compiled.
408412
@@ -519,10 +523,15 @@ def test_compile_async_generator(self):
519523 exec (co , glob )
520524 self .assertEqual (type (glob ['ticker' ]()), AsyncGeneratorType )
521525
526+ # TODO: RUSTPYTHON
527+ @unittest .expectedFailure
522528 def test_delattr (self ):
523529 sys .spam = 1
524530 delattr (sys , 'spam' )
525531 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 )
526535
527536 # TODO: RUSTPYTHON
528537 @unittest .expectedFailure
@@ -748,11 +757,9 @@ def test_exec_globals(self):
748757 self .assertRaises (TypeError ,
749758 exec , code , {'__builtins__' : 123 })
750759
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 ):
756763 class frozendict_error (Exception ):
757764 pass
758765
@@ -769,12 +776,55 @@ def __setitem__(self, key, value):
769776 self .assertRaises (frozendict_error ,
770777 exec , code , {'__builtins__' : frozen_builtins })
771778
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+
772788 # read-only globals
773789 namespace = frozendict ({})
774790 code = compile ("x=1" , "test" , "exec" )
775791 self .assertRaises (frozendict_error ,
776792 exec , code , namespace )
777793
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+
778828 def test_exec_redirected (self ):
779829 savestdout = sys .stdout
780830 sys .stdout = None # Whatever that cannot flush()
@@ -786,6 +836,86 @@ def test_exec_redirected(self):
786836 finally :
787837 sys .stdout = savestdout
788838
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+
789919 def test_filter (self ):
790920 self .assertEqual (list (filter (lambda c : 'a' <= c <= 'z' , 'Hello World' )), list ('elloorld' ))
791921 self .assertEqual (list (filter (None , [1 , 'hello' , [], [3 ], '' , None , 9 , 0 ])), [1 , 'hello' , [3 ], 9 ])
@@ -817,19 +947,27 @@ def test_filter_pickle(self):
817947 f2 = filter (filter_char , "abcdeabcde" )
818948 self .check_iter_pickle (f1 , list (f2 ), proto )
819949
950+ # TODO: RUSTPYTHON
951+ @unittest .expectedFailure
820952 def test_getattr (self ):
821953 self .assertTrue (getattr (sys , 'stdout' ) is sys .stdout )
822- self .assertRaises (TypeError , getattr , sys , 1 )
823- self .assertRaises (TypeError , getattr , sys , 1 , "foo" )
824954 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' )
825959 self .assertRaises (AttributeError , getattr , sys , chr (sys .maxunicode ))
826960 # unicode surrogates are not encodable to the default encoding (utf8)
827961 self .assertRaises (AttributeError , getattr , 1 , "\uDAD1 \uD51E " )
828962
963+ # TODO: RUSTPYTHON
964+ @unittest .expectedFailure
829965 def test_hasattr (self ):
830966 self .assertTrue (hasattr (sys , 'stdout' ))
831- self .assertRaises (TypeError , hasattr , sys , 1 )
832967 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 )
833971 self .assertEqual (False , hasattr (sys , chr (sys .maxunicode )))
834972
835973 # Check that hasattr propagates all exceptions outside of
@@ -1216,7 +1354,7 @@ def test_open_default_encoding(self):
12161354 del os .environ [key ]
12171355
12181356 self .write_testfile ()
1219- current_locale_encoding = locale .getpreferredencoding ( False )
1357+ current_locale_encoding = locale .getencoding ( )
12201358 with warnings .catch_warnings ():
12211359 warnings .simplefilter ("ignore" , EncodingWarning )
12221360 fp = open (TESTFN , 'w' )
@@ -1227,6 +1365,7 @@ def test_open_default_encoding(self):
12271365 os .environ .update (old_environ )
12281366
12291367 @unittest .skipIf (sys .platform == 'win32' , 'TODO: RUSTPYTHON Windows' )
1368+ @support .requires_subprocess ()
12301369 def test_open_non_inheritable (self ):
12311370 fileobj = open (__file__ , encoding = "utf-8" )
12321371 with fileobj :
@@ -1475,11 +1614,16 @@ def test_bug_27936(self):
14751614 self .assertEqual (round (x , None ), round (x ))
14761615 self .assertEqual (type (round (x , None )), type (round (x )))
14771616
1617+ # TODO: RUSTPYTHON
1618+ @unittest .expectedFailure
14781619 def test_setattr (self ):
14791620 setattr (sys , 'spam' , 1 )
14801621 self .assertEqual (sys .spam , 1 )
1481- self .assertRaises (TypeError , setattr , sys , 1 , 'spam' )
14821622 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' )
14831627
14841628 # test_str(): see test_unicode.py and test_bytes.py for str() tests.
14851629
@@ -1998,10 +2142,6 @@ def test_envar_ignored_when_hook_is_set(self):
19982142 breakpoint ()
19992143 mock .assert_not_called ()
20002144
2001- def test_runtime_error_when_hook_is_lost (self ):
2002- del sys .breakpointhook
2003- with self .assertRaises (RuntimeError ):
2004- breakpoint ()
20052145
20062146@unittest .skipUnless (pty , "the pty and signal modules must be available" )
20072147class PtyTests (unittest .TestCase ):
@@ -2270,6 +2410,8 @@ def test_type_nokwargs(self):
22702410 with self .assertRaises (TypeError ):
22712411 type ('a' , (), dict = {})
22722412
2413+ # TODO: RUSTPYTHON
2414+ @unittest .expectedFailure
22732415 def test_type_name (self ):
22742416 for name in 'A' , '\xc4 ' , '\U0001f40d ' , 'B.A' , '42' , '' :
22752417 with self .subTest (name = name ):
@@ -2279,10 +2421,8 @@ def test_type_name(self):
22792421 self .assertEqual (A .__module__ , __name__ )
22802422 with self .assertRaises (ValueError ):
22812423 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' , (), {})
22862426 with self .assertRaises (TypeError ):
22872427 type (b'A' , (), {})
22882428
@@ -2298,13 +2438,9 @@ def test_type_name(self):
22982438 with self .assertRaises (ValueError ):
22992439 A .__name__ = 'A\x00 B'
23002440 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' )
23082444 with self .assertRaises (TypeError ):
23092445 A .__name__ = b'A'
23102446 self .assertEqual (A .__name__ , 'C' )
0 commit comments