Skip to content

Commit 0eea760

Browse files
committed
Update test_builtin.py from CPython v3.11.2
1 parent 887ffd1 commit 0eea760

File tree

1 file changed

+147
-30
lines changed

1 file changed

+147
-30
lines changed

Lib/test/test_builtin.py

Lines changed: 147 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from inspect import CO_COROUTINE
2525
from itertools import product
2626
from textwrap import dedent
27-
from types import AsyncGeneratorType, FunctionType
27+
from types import AsyncGeneratorType, FunctionType, CellType
2828
from operator import neg
2929
from test import support
3030
from 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
@@ -523,6 +527,9 @@ def test_delattr(self):
523527
sys.spam = 1
524528
delattr(sys, 'spam')
525529
self.assertRaises(TypeError, delattr)
530+
self.assertRaises(TypeError, delattr, sys)
531+
msg = r"^attribute name must be string, not 'int'$"
532+
self.assertRaisesRegex(TypeError, msg, delattr, sys, 1)
526533

527534
# TODO: RUSTPYTHON
528535
@unittest.expectedFailure
@@ -748,11 +755,7 @@ def test_exec_globals(self):
748755
self.assertRaises(TypeError,
749756
exec, code, {'__builtins__': 123})
750757

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-
758+
def test_exec_globals_frozen(self):
756759
class frozendict_error(Exception):
757760
pass
758761

@@ -769,12 +772,51 @@ def __setitem__(self, key, value):
769772
self.assertRaises(frozendict_error,
770773
exec, code, {'__builtins__': frozen_builtins})
771774

775+
# no __build_class__ function
776+
code = compile("class A: pass", "", "exec")
777+
self.assertRaisesRegex(NameError, "__build_class__ not found",
778+
exec, code, {'__builtins__': {}})
779+
# __build_class__ in a custom __builtins__
780+
exec(code, {'__builtins__': frozen_builtins})
781+
self.assertRaisesRegex(NameError, "__build_class__ not found",
782+
exec, code, {'__builtins__': frozendict()})
783+
772784
# read-only globals
773785
namespace = frozendict({})
774786
code = compile("x=1", "test", "exec")
775787
self.assertRaises(frozendict_error,
776788
exec, code, namespace)
777789

790+
def test_exec_globals_error_on_get(self):
791+
# custom `globals` or `builtins` can raise errors on item access
792+
class setonlyerror(Exception):
793+
pass
794+
795+
class setonlydict(dict):
796+
def __getitem__(self, key):
797+
raise setonlyerror
798+
799+
# globals' `__getitem__` raises
800+
code = compile("globalname", "test", "exec")
801+
self.assertRaises(setonlyerror,
802+
exec, code, setonlydict({'globalname': 1}))
803+
804+
# builtins' `__getitem__` raises
805+
code = compile("superglobal", "test", "exec")
806+
self.assertRaises(setonlyerror, exec, code,
807+
{'__builtins__': setonlydict({'superglobal': 1})})
808+
809+
def test_exec_globals_dict_subclass(self):
810+
class customdict(dict): # this one should not do anything fancy
811+
pass
812+
813+
code = compile("superglobal", "test", "exec")
814+
# works correctly
815+
exec(code, {'__builtins__': customdict({'superglobal': 1})})
816+
# custom builtins dict subclass is missing key
817+
self.assertRaisesRegex(NameError, "name 'superglobal' is not defined",
818+
exec, code, {'__builtins__': customdict()})
819+
778820
def test_exec_redirected(self):
779821
savestdout = sys.stdout
780822
sys.stdout = None # Whatever that cannot flush()
@@ -786,6 +828,84 @@ def test_exec_redirected(self):
786828
finally:
787829
sys.stdout = savestdout
788830

831+
def test_exec_closure(self):
832+
def function_without_closures():
833+
return 3 * 5
834+
835+
result = 0
836+
def make_closure_functions():
837+
a = 2
838+
b = 3
839+
c = 5
840+
def three_freevars():
841+
nonlocal result
842+
nonlocal a
843+
nonlocal b
844+
result = a*b
845+
def four_freevars():
846+
nonlocal result
847+
nonlocal a
848+
nonlocal b
849+
nonlocal c
850+
result = a*b*c
851+
return three_freevars, four_freevars
852+
three_freevars, four_freevars = make_closure_functions()
853+
854+
# "smoke" test
855+
result = 0
856+
exec(three_freevars.__code__,
857+
three_freevars.__globals__,
858+
closure=three_freevars.__closure__)
859+
self.assertEqual(result, 6)
860+
861+
# should also work with a manually created closure
862+
result = 0
863+
my_closure = (CellType(35), CellType(72), three_freevars.__closure__[2])
864+
exec(three_freevars.__code__,
865+
three_freevars.__globals__,
866+
closure=my_closure)
867+
self.assertEqual(result, 2520)
868+
869+
# should fail: closure isn't allowed
870+
# for functions without free vars
871+
self.assertRaises(TypeError,
872+
exec,
873+
function_without_closures.__code__,
874+
function_without_closures.__globals__,
875+
closure=my_closure)
876+
877+
# should fail: closure required but wasn't specified
878+
self.assertRaises(TypeError,
879+
exec,
880+
three_freevars.__code__,
881+
three_freevars.__globals__,
882+
closure=None)
883+
884+
# should fail: closure of wrong length
885+
self.assertRaises(TypeError,
886+
exec,
887+
three_freevars.__code__,
888+
three_freevars.__globals__,
889+
closure=four_freevars.__closure__)
890+
891+
# should fail: closure using a list instead of a tuple
892+
my_closure = list(my_closure)
893+
self.assertRaises(TypeError,
894+
exec,
895+
three_freevars.__code__,
896+
three_freevars.__globals__,
897+
closure=my_closure)
898+
899+
# should fail: closure tuple with one non-cell-var
900+
my_closure[0] = int
901+
my_closure = tuple(my_closure)
902+
self.assertRaises(TypeError,
903+
exec,
904+
three_freevars.__code__,
905+
three_freevars.__globals__,
906+
closure=my_closure)
907+
908+
789909
def test_filter(self):
790910
self.assertEqual(list(filter(lambda c: 'a' <= c <= 'z', 'Hello World')), list('elloorld'))
791911
self.assertEqual(list(filter(None, [1, 'hello', [], [3], '', None, 9, 0])), [1, 'hello', [3], 9])
@@ -819,17 +939,21 @@ def test_filter_pickle(self):
819939

820940
def test_getattr(self):
821941
self.assertTrue(getattr(sys, 'stdout') is sys.stdout)
822-
self.assertRaises(TypeError, getattr, sys, 1)
823-
self.assertRaises(TypeError, getattr, sys, 1, "foo")
824942
self.assertRaises(TypeError, getattr)
943+
self.assertRaises(TypeError, getattr, sys)
944+
msg = r"^attribute name must be string, not 'int'$"
945+
self.assertRaisesRegex(TypeError, msg, getattr, sys, 1)
946+
self.assertRaisesRegex(TypeError, msg, getattr, sys, 1, 'spam')
825947
self.assertRaises(AttributeError, getattr, sys, chr(sys.maxunicode))
826948
# unicode surrogates are not encodable to the default encoding (utf8)
827949
self.assertRaises(AttributeError, getattr, 1, "\uDAD1\uD51E")
828950

829951
def test_hasattr(self):
830952
self.assertTrue(hasattr(sys, 'stdout'))
831-
self.assertRaises(TypeError, hasattr, sys, 1)
832953
self.assertRaises(TypeError, hasattr)
954+
self.assertRaises(TypeError, hasattr, sys)
955+
msg = r"^attribute name must be string, not 'int'$"
956+
self.assertRaisesRegex(TypeError, msg, hasattr, sys, 1)
833957
self.assertEqual(False, hasattr(sys, chr(sys.maxunicode)))
834958

835959
# Check that hasattr propagates all exceptions outside of
@@ -1216,7 +1340,7 @@ def test_open_default_encoding(self):
12161340
del os.environ[key]
12171341

12181342
self.write_testfile()
1219-
current_locale_encoding = locale.getpreferredencoding(False)
1343+
current_locale_encoding = locale.getencoding()
12201344
with warnings.catch_warnings():
12211345
warnings.simplefilter("ignore", EncodingWarning)
12221346
fp = open(TESTFN, 'w')
@@ -1226,7 +1350,7 @@ def test_open_default_encoding(self):
12261350
os.environ.clear()
12271351
os.environ.update(old_environ)
12281352

1229-
@unittest.skipIf(sys.platform == 'win32', 'TODO: RUSTPYTHON Windows')
1353+
@support.requires_subprocess()
12301354
def test_open_non_inheritable(self):
12311355
fileobj = open(__file__, encoding="utf-8")
12321356
with fileobj:
@@ -1478,8 +1602,11 @@ def test_bug_27936(self):
14781602
def test_setattr(self):
14791603
setattr(sys, 'spam', 1)
14801604
self.assertEqual(sys.spam, 1)
1481-
self.assertRaises(TypeError, setattr, sys, 1, 'spam')
14821605
self.assertRaises(TypeError, setattr)
1606+
self.assertRaises(TypeError, setattr, sys)
1607+
self.assertRaises(TypeError, setattr, sys, 'spam')
1608+
msg = r"^attribute name must be string, not 'int'$"
1609+
self.assertRaisesRegex(TypeError, msg, setattr, sys, 1, 'spam')
14831610

14841611
# test_str(): see test_unicode.py and test_bytes.py for str() tests.
14851612

@@ -1998,10 +2125,6 @@ def test_envar_ignored_when_hook_is_set(self):
19982125
breakpoint()
19992126
mock.assert_not_called()
20002127

2001-
def test_runtime_error_when_hook_is_lost(self):
2002-
del sys.breakpointhook
2003-
with self.assertRaises(RuntimeError):
2004-
breakpoint()
20052128

20062129
@unittest.skipUnless(pty, "the pty and signal modules must be available")
20072130
class PtyTests(unittest.TestCase):
@@ -2279,10 +2402,8 @@ def test_type_name(self):
22792402
self.assertEqual(A.__module__, __name__)
22802403
with self.assertRaises(ValueError):
22812404
type('A\x00B', (), {})
2282-
# TODO: RUSTPYTHON (https://github.com/RustPython/RustPython/issues/935)
2283-
with self.assertRaises(AssertionError):
2284-
with self.assertRaises(ValueError):
2285-
type('A\udcdcB', (), {})
2405+
with self.assertRaises(UnicodeEncodeError):
2406+
type('A\udcdcB', (), {})
22862407
with self.assertRaises(TypeError):
22872408
type(b'A', (), {})
22882409

@@ -2298,13 +2419,9 @@ def test_type_name(self):
22982419
with self.assertRaises(ValueError):
22992420
A.__name__ = 'A\x00B'
23002421
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\udcdcB'
2305-
self.assertEqual(A.__name__, 'C')
2306-
# TODO: RUSTPYTHON: the previous __name__ set should fail but doesn't: reset it
2307-
A.__name__ = 'C'
2422+
with self.assertRaises(UnicodeEncodeError):
2423+
A.__name__ = 'A\udcdcB'
2424+
self.assertEqual(A.__name__, 'C')
23082425
with self.assertRaises(TypeError):
23092426
A.__name__ = b'A'
23102427
self.assertEqual(A.__name__, 'C')

0 commit comments

Comments
 (0)