mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Update tests from CPython 3.10.5
This commit is contained in:
1 parent
2f488cb153
commit
33690be35b
7 files changed
+6198
-5859
No files matched your search
Vendored
+20
-16
@@ -1,7 +1,6 @@
|
||||
# Test properties of bool promised by PEP 285
|
||||
|
||||
import unittest
|
||||
from test import support
|
||||
from test.support import os_helper
|
||||
|
||||
import os
|
||||
@@ -21,20 +20,11 @@ class BoolTest(unittest.TestCase):
|
||||
|
||||
self.assertRaises(TypeError, int.__new__, bool, 0)
|
||||
|
||||
def test_print(self):
|
||||
try:
|
||||
with open(os_helper.TESTFN, "w") as fo:
|
||||
print(False, True, file=fo)
|
||||
with open(os_helper.TESTFN, "r") as fi:
|
||||
self.assertEqual(fi.read(), 'False True\n')
|
||||
finally:
|
||||
os.remove(os_helper.TESTFN)
|
||||
|
||||
def test_repr(self):
|
||||
self.assertEqual(repr(False), 'False')
|
||||
self.assertEqual(repr(True), 'True')
|
||||
self.assertEqual(eval(repr(False)), False)
|
||||
self.assertEqual(eval(repr(True)), True)
|
||||
self.assertIs(eval(repr(False)), False)
|
||||
self.assertIs(eval(repr(True)), True)
|
||||
|
||||
def test_str(self):
|
||||
self.assertEqual(str(False), 'False')
|
||||
@@ -246,7 +236,7 @@ class BoolTest(unittest.TestCase):
|
||||
|
||||
def test_fileclosed(self):
|
||||
try:
|
||||
with open(os_helper.TESTFN, "w") as f:
|
||||
with open(os_helper.TESTFN, "w", encoding="utf-8") as f:
|
||||
self.assertIs(f.closed, False)
|
||||
self.assertIs(f.closed, True)
|
||||
finally:
|
||||
@@ -365,8 +355,22 @@ class BoolTest(unittest.TestCase):
|
||||
self.assertIs(type(False.real), int)
|
||||
self.assertIs(type(False.imag), int)
|
||||
|
||||
def test_main():
|
||||
support.run_unittest(BoolTest)
|
||||
def test_bool_called_at_least_once(self):
|
||||
class X:
|
||||
def __init__(self):
|
||||
self.count = 0
|
||||
def __bool__(self):
|
||||
self.count += 1
|
||||
return True
|
||||
|
||||
def f(x):
|
||||
if x or True:
|
||||
pass
|
||||
|
||||
x = X()
|
||||
f(x)
|
||||
self.assertGreaterEqual(x.count, 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_main()
|
||||
unittest.main()
|
||||
Vendored
+295
-85
@@ -1,10 +1,12 @@
|
||||
# Python test set -- built-in functions
|
||||
|
||||
import ast
|
||||
import asyncio
|
||||
import builtins
|
||||
import collections
|
||||
import decimal
|
||||
import fractions
|
||||
import gc
|
||||
import io
|
||||
import locale
|
||||
import os
|
||||
@@ -17,13 +19,18 @@ import traceback
|
||||
import types
|
||||
import unittest
|
||||
import warnings
|
||||
from functools import partial
|
||||
from contextlib import ExitStack
|
||||
from functools import partial
|
||||
from inspect import CO_COROUTINE
|
||||
from itertools import product
|
||||
from textwrap import dedent
|
||||
from types import AsyncGeneratorType, FunctionType
|
||||
from operator import neg
|
||||
from test.support import swap_attr
|
||||
from test.support.warnings_helper import check_warnings
|
||||
from test import support
|
||||
from test.support import (swap_attr, maybe_get_event_loop_policy)
|
||||
from test.support.os_helper import (EnvironmentVarGuard, TESTFN, unlink)
|
||||
from test.support.script_helper import assert_python_ok
|
||||
from test.support.os_helper import EnvironmentVarGuard, TESTFN, unlink
|
||||
from test.support.warnings_helper import check_warnings
|
||||
from unittest.mock import MagicMock, patch
|
||||
try:
|
||||
import pty, signal
|
||||
@@ -156,6 +163,11 @@ class BuiltinTest(unittest.TestCase):
|
||||
self.assertRaises(TypeError, __import__, 1, 2, 3, 4)
|
||||
self.assertRaises(ValueError, __import__, '')
|
||||
self.assertRaises(TypeError, __import__, 'sys', name='sys')
|
||||
# Relative import outside of a package with no __package__ or __spec__ (bpo-37409).
|
||||
with self.assertWarns(ImportWarning):
|
||||
self.assertRaises(ImportError, __import__, '',
|
||||
{'__package__': None, '__spec__': None, '__name__': '__main__'},
|
||||
locals={}, fromlist=('foo',), level=1)
|
||||
# embedded null character
|
||||
self.assertRaises(ModuleNotFoundError, __import__, 'string\x00')
|
||||
|
||||
@@ -320,8 +332,8 @@ class BuiltinTest(unittest.TestCase):
|
||||
bom = b'\xef\xbb\xbf'
|
||||
compile(bom + b'print(1)\n', '', 'exec')
|
||||
compile(source='pass', filename='?', mode='exec')
|
||||
compile(dont_inherit=0, filename='tmp', source='0', mode='eval')
|
||||
compile('pass', '?', dont_inherit=1, mode='exec')
|
||||
compile(dont_inherit=False, filename='tmp', source='0', mode='eval')
|
||||
compile('pass', '?', dont_inherit=True, mode='exec')
|
||||
compile(memoryview(b"text"), "name", "exec")
|
||||
self.assertRaises(TypeError, compile)
|
||||
self.assertRaises(ValueError, compile, 'print(42)\n', '<string>', 'badmode')
|
||||
@@ -364,6 +376,139 @@ class BuiltinTest(unittest.TestCase):
|
||||
rv = ns['f']()
|
||||
self.assertEqual(rv, tuple(expected))
|
||||
|
||||
def test_compile_top_level_await_no_coro(self):
|
||||
"""Make sure top level non-await codes get the correct coroutine flags"""
|
||||
modes = ('single', 'exec')
|
||||
code_samples = [
|
||||
'''def f():pass\n''',
|
||||
'''[x for x in l]''',
|
||||
'''{x for x in l}''',
|
||||
'''(x for x in l)''',
|
||||
'''{x:x for x in l}''',
|
||||
]
|
||||
for mode, code_sample in product(modes, code_samples):
|
||||
source = dedent(code_sample)
|
||||
co = compile(source,
|
||||
'?',
|
||||
mode,
|
||||
flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT)
|
||||
|
||||
self.assertNotEqual(co.co_flags & CO_COROUTINE, CO_COROUTINE,
|
||||
msg=f"source={source} mode={mode}")
|
||||
|
||||
|
||||
def test_compile_top_level_await(self):
|
||||
"""Test whether code some top level await can be compiled.
|
||||
|
||||
Make sure it compiles only with the PyCF_ALLOW_TOP_LEVEL_AWAIT flag
|
||||
set, and make sure the generated code object has the CO_COROUTINE flag
|
||||
set in order to execute it with `await eval(.....)` instead of exec,
|
||||
or via a FunctionType.
|
||||
"""
|
||||
|
||||
# helper function just to check we can run top=level async-for
|
||||
async def arange(n):
|
||||
for i in range(n):
|
||||
yield i
|
||||
|
||||
modes = ('single', 'exec')
|
||||
code_samples = [
|
||||
'''a = await asyncio.sleep(0, result=1)''',
|
||||
'''async for i in arange(1):
|
||||
a = 1''',
|
||||
'''async with asyncio.Lock() as l:
|
||||
a = 1''',
|
||||
'''a = [x async for x in arange(2)][1]''',
|
||||
'''a = 1 in {x async for x in arange(2)}''',
|
||||
'''a = {x:1 async for x in arange(1)}[0]''',
|
||||
'''a = [x async for x in arange(2) async for x in arange(2)][1]''',
|
||||
'''a = [x async for x in (x async for x in arange(5))][1]''',
|
||||
'''a, = [1 for x in {x async for x in arange(1)}]''',
|
||||
'''a = [await asyncio.sleep(0, x) async for x in arange(2)][1]'''
|
||||
]
|
||||
policy = maybe_get_event_loop_policy()
|
||||
try:
|
||||
for mode, code_sample in product(modes, code_samples):
|
||||
source = dedent(code_sample)
|
||||
with self.assertRaises(
|
||||
SyntaxError, msg=f"source={source} mode={mode}"):
|
||||
compile(source, '?', mode)
|
||||
|
||||
co = compile(source,
|
||||
'?',
|
||||
mode,
|
||||
flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT)
|
||||
|
||||
self.assertEqual(co.co_flags & CO_COROUTINE, CO_COROUTINE,
|
||||
msg=f"source={source} mode={mode}")
|
||||
|
||||
# test we can create and advance a function type
|
||||
globals_ = {'asyncio': asyncio, 'a': 0, 'arange': arange}
|
||||
async_f = FunctionType(co, globals_)
|
||||
asyncio.run(async_f())
|
||||
self.assertEqual(globals_['a'], 1)
|
||||
|
||||
# test we can await-eval,
|
||||
globals_ = {'asyncio': asyncio, 'a': 0, 'arange': arange}
|
||||
asyncio.run(eval(co, globals_))
|
||||
self.assertEqual(globals_['a'], 1)
|
||||
finally:
|
||||
asyncio.set_event_loop_policy(policy)
|
||||
|
||||
def test_compile_top_level_await_invalid_cases(self):
|
||||
# helper function just to check we can run top=level async-for
|
||||
async def arange(n):
|
||||
for i in range(n):
|
||||
yield i
|
||||
|
||||
modes = ('single', 'exec')
|
||||
code_samples = [
|
||||
'''def f(): await arange(10)\n''',
|
||||
'''def f(): [x async for x in arange(10)]\n''',
|
||||
'''def f(): [await x async for x in arange(10)]\n''',
|
||||
'''def f():
|
||||
async for i in arange(1):
|
||||
a = 1
|
||||
''',
|
||||
'''def f():
|
||||
async with asyncio.Lock() as l:
|
||||
a = 1
|
||||
'''
|
||||
]
|
||||
policy = maybe_get_event_loop_policy()
|
||||
try:
|
||||
for mode, code_sample in product(modes, code_samples):
|
||||
source = dedent(code_sample)
|
||||
with self.assertRaises(
|
||||
SyntaxError, msg=f"source={source} mode={mode}"):
|
||||
compile(source, '?', mode)
|
||||
|
||||
with self.assertRaises(
|
||||
SyntaxError, msg=f"source={source} mode={mode}"):
|
||||
co = compile(source,
|
||||
'?',
|
||||
mode,
|
||||
flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT)
|
||||
finally:
|
||||
asyncio.set_event_loop_policy(policy)
|
||||
|
||||
|
||||
def test_compile_async_generator(self):
|
||||
"""
|
||||
With the PyCF_ALLOW_TOP_LEVEL_AWAIT flag added in 3.8, we want to
|
||||
make sure AsyncGenerators are still properly not marked with the
|
||||
CO_COROUTINE flag.
|
||||
"""
|
||||
code = dedent("""async def ticker():
|
||||
for i in range(10):
|
||||
yield i
|
||||
await asyncio.sleep(0)""")
|
||||
|
||||
co = compile(code, '?', 'exec', flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT)
|
||||
glob = {}
|
||||
exec(co, glob)
|
||||
self.assertEqual(type(glob['ticker']()), AsyncGeneratorType)
|
||||
|
||||
def test_delattr(self):
|
||||
sys.spam = 1
|
||||
delattr(sys, 'spam')
|
||||
@@ -442,8 +587,8 @@ class BuiltinTest(unittest.TestCase):
|
||||
# dir(traceback)
|
||||
try:
|
||||
raise IndexError
|
||||
except:
|
||||
self.assertEqual(len(dir(sys.exc_info()[2])), 4)
|
||||
except IndexError as e:
|
||||
self.assertEqual(len(dir(e.__traceback__)), 4)
|
||||
|
||||
# test that object has a __dir__()
|
||||
self.assertEqual(sorted([].__dir__()), dir([]))
|
||||
@@ -664,66 +809,6 @@ class BuiltinTest(unittest.TestCase):
|
||||
f2 = filter(filter_char, "abcdeabcde")
|
||||
self.check_iter_pickle(f1, list(f2), proto)
|
||||
|
||||
def test_zip_pickle_strict(self):
|
||||
a = (1, 2, 3)
|
||||
b = (4, 5, 6)
|
||||
t = [(1, 4), (2, 5), (3, 6)]
|
||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||
z1 = zip(a, b, strict=True)
|
||||
self.check_iter_pickle(z1, t, proto)
|
||||
|
||||
def test_zip_pickle_strict_fail(self):
|
||||
a = (1, 2, 3)
|
||||
b = (4, 5, 6, 7)
|
||||
t = [(1, 4), (2, 5), (3, 6)]
|
||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||
z1 = zip(a, b, strict=True)
|
||||
z2 = pickle.loads(pickle.dumps(z1, proto))
|
||||
self.assertEqual(self.iter_error(z1, ValueError), t)
|
||||
self.assertEqual(self.iter_error(z2, ValueError), t)
|
||||
|
||||
def test_zip_pickle_stability(self):
|
||||
# Pickles of zip((1, 2, 3), (4, 5, 6)) dumped from 3.9:
|
||||
pickles = [
|
||||
b'citertools\nizip\np0\n(c__builtin__\niter\np1\n((I1\nI2\nI3\ntp2\ntp3\nRp4\nI0\nbg1\n((I4\nI5\nI6\ntp5\ntp6\nRp7\nI0\nbtp8\nRp9\n.',
|
||||
b'citertools\nizip\nq\x00(c__builtin__\niter\nq\x01((K\x01K\x02K\x03tq\x02tq\x03Rq\x04K\x00bh\x01((K\x04K\x05K\x06tq\x05tq\x06Rq\x07K\x00btq\x08Rq\t.',
|
||||
b'\x80\x02citertools\nizip\nq\x00c__builtin__\niter\nq\x01K\x01K\x02K\x03\x87q\x02\x85q\x03Rq\x04K\x00bh\x01K\x04K\x05K\x06\x87q\x05\x85q\x06Rq\x07K\x00b\x86q\x08Rq\t.',
|
||||
b'\x80\x03cbuiltins\nzip\nq\x00cbuiltins\niter\nq\x01K\x01K\x02K\x03\x87q\x02\x85q\x03Rq\x04K\x00bh\x01K\x04K\x05K\x06\x87q\x05\x85q\x06Rq\x07K\x00b\x86q\x08Rq\t.',
|
||||
b'\x80\x04\x95L\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x03zip\x94\x93\x94\x8c\x08builtins\x94\x8c\x04iter\x94\x93\x94K\x01K\x02K\x03\x87\x94\x85\x94R\x94K\x00bh\x05K\x04K\x05K\x06\x87\x94\x85\x94R\x94K\x00b\x86\x94R\x94.',
|
||||
b'\x80\x05\x95L\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x03zip\x94\x93\x94\x8c\x08builtins\x94\x8c\x04iter\x94\x93\x94K\x01K\x02K\x03\x87\x94\x85\x94R\x94K\x00bh\x05K\x04K\x05K\x06\x87\x94\x85\x94R\x94K\x00b\x86\x94R\x94.',
|
||||
]
|
||||
for protocol, dump in enumerate(pickles):
|
||||
z1 = zip((1, 2, 3), (4, 5, 6))
|
||||
z2 = zip((1, 2, 3), (4, 5, 6), strict=False)
|
||||
z3 = pickle.loads(dump)
|
||||
l3 = list(z3)
|
||||
self.assertEqual(type(z3), zip)
|
||||
self.assertEqual(pickle.dumps(z1, protocol), dump)
|
||||
self.assertEqual(pickle.dumps(z2, protocol), dump)
|
||||
self.assertEqual(list(z1), l3)
|
||||
self.assertEqual(list(z2), l3)
|
||||
|
||||
def test_zip_pickle_strict_stability(self):
|
||||
# Pickles of zip((1, 2, 3), (4, 5), strict=True) dumped from 3.10:
|
||||
pickles = [
|
||||
b'citertools\nizip\np0\n(c__builtin__\niter\np1\n((I1\nI2\nI3\ntp2\ntp3\nRp4\nI0\nbg1\n((I4\nI5\ntp5\ntp6\nRp7\nI0\nbtp8\nRp9\nI01\nb.',
|
||||
b'citertools\nizip\nq\x00(c__builtin__\niter\nq\x01((K\x01K\x02K\x03tq\x02tq\x03Rq\x04K\x00bh\x01((K\x04K\x05tq\x05tq\x06Rq\x07K\x00btq\x08Rq\tI01\nb.',
|
||||
b'\x80\x02citertools\nizip\nq\x00c__builtin__\niter\nq\x01K\x01K\x02K\x03\x87q\x02\x85q\x03Rq\x04K\x00bh\x01K\x04K\x05\x86q\x05\x85q\x06Rq\x07K\x00b\x86q\x08Rq\t\x88b.',
|
||||
b'\x80\x03cbuiltins\nzip\nq\x00cbuiltins\niter\nq\x01K\x01K\x02K\x03\x87q\x02\x85q\x03Rq\x04K\x00bh\x01K\x04K\x05\x86q\x05\x85q\x06Rq\x07K\x00b\x86q\x08Rq\t\x88b.',
|
||||
b'\x80\x04\x95L\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x03zip\x94\x93\x94\x8c\x08builtins\x94\x8c\x04iter\x94\x93\x94K\x01K\x02K\x03\x87\x94\x85\x94R\x94K\x00bh\x05K\x04K\x05\x86\x94\x85\x94R\x94K\x00b\x86\x94R\x94\x88b.',
|
||||
b'\x80\x05\x95L\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x03zip\x94\x93\x94\x8c\x08builtins\x94\x8c\x04iter\x94\x93\x94K\x01K\x02K\x03\x87\x94\x85\x94R\x94K\x00bh\x05K\x04K\x05\x86\x94\x85\x94R\x94K\x00b\x86\x94R\x94\x88b.',
|
||||
]
|
||||
a = (1, 2, 3)
|
||||
b = (4, 5)
|
||||
t = [(1, 4), (2, 5)]
|
||||
for protocol, dump in enumerate(pickles):
|
||||
z1 = zip(a, b, strict=True)
|
||||
z2 = pickle.loads(dump)
|
||||
self.assertEqual(pickle.dumps(z1, protocol), dump)
|
||||
self.assertEqual(type(z2), zip)
|
||||
self.assertEqual(self.iter_error(z1, ValueError), t)
|
||||
self.assertEqual(self.iter_error(z2, ValueError), t)
|
||||
|
||||
def test_getattr(self):
|
||||
self.assertTrue(getattr(sys, 'stdout') is sys.stdout)
|
||||
self.assertRaises(TypeError, getattr, sys, 1)
|
||||
@@ -758,6 +843,7 @@ class BuiltinTest(unittest.TestCase):
|
||||
self.assertEqual(hash('spam'), hash(b'spam'))
|
||||
hash((0,1,2,3))
|
||||
def f(): pass
|
||||
hash(f)
|
||||
self.assertRaises(TypeError, hash, [])
|
||||
self.assertRaises(TypeError, hash, {})
|
||||
# Bug 1536021: Allow hash to return long objects
|
||||
@@ -941,7 +1027,12 @@ class BuiltinTest(unittest.TestCase):
|
||||
self.assertEqual(max(1, 2.0, 3), 3)
|
||||
self.assertEqual(max(1.0, 2, 3), 3)
|
||||
|
||||
self.assertRaises(TypeError, max)
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
'max expected at least 1 argument, got 0'
|
||||
):
|
||||
max()
|
||||
|
||||
self.assertRaises(TypeError, max, 42)
|
||||
self.assertRaises(ValueError, max, ())
|
||||
class BadSeq:
|
||||
@@ -995,7 +1086,12 @@ class BuiltinTest(unittest.TestCase):
|
||||
self.assertEqual(min(1, 2.0, 3), 1)
|
||||
self.assertEqual(min(1.0, 2, 3), 1.0)
|
||||
|
||||
self.assertRaises(TypeError, min)
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
'min expected at least 1 argument, got 0'
|
||||
):
|
||||
min()
|
||||
|
||||
self.assertRaises(TypeError, min, 42)
|
||||
self.assertRaises(ValueError, min, ())
|
||||
class BadSeq:
|
||||
@@ -1073,7 +1169,7 @@ class BuiltinTest(unittest.TestCase):
|
||||
|
||||
def write_testfile(self):
|
||||
# NB the first 4 lines are also used to test input, below
|
||||
fp = open(TESTFN, 'w')
|
||||
fp = open(TESTFN, 'w', encoding="utf-8")
|
||||
self.addCleanup(unlink, TESTFN)
|
||||
with fp:
|
||||
fp.write('1+1\n')
|
||||
@@ -1085,7 +1181,7 @@ class BuiltinTest(unittest.TestCase):
|
||||
|
||||
def test_open(self):
|
||||
self.write_testfile()
|
||||
fp = open(TESTFN, 'r')
|
||||
fp = open(TESTFN, encoding="utf-8")
|
||||
with fp:
|
||||
self.assertEqual(fp.readline(4), '1+1\n')
|
||||
self.assertEqual(fp.readline(), 'The quick brown fox jumps over the lazy dog.\n')
|
||||
@@ -1113,16 +1209,17 @@ class BuiltinTest(unittest.TestCase):
|
||||
|
||||
self.write_testfile()
|
||||
current_locale_encoding = locale.getpreferredencoding(False)
|
||||
fp = open(TESTFN, 'w')
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", EncodingWarning)
|
||||
fp = open(TESTFN, 'w')
|
||||
with fp:
|
||||
self.assertEqual(fp.encoding, current_locale_encoding)
|
||||
finally:
|
||||
os.environ.clear()
|
||||
os.environ.update(old_environ)
|
||||
|
||||
@unittest.skipIf(sys.platform == 'win32', 'TODO: RUSTPYTHON Windows')
|
||||
def test_open_non_inheritable(self):
|
||||
fileobj = open(__file__)
|
||||
fileobj = open(__file__, encoding="utf-8")
|
||||
with fileobj:
|
||||
self.assertFalse(os.get_inheritable(fileobj.fileno()))
|
||||
|
||||
@@ -1217,7 +1314,7 @@ class BuiltinTest(unittest.TestCase):
|
||||
|
||||
def test_input(self):
|
||||
self.write_testfile()
|
||||
fp = open(TESTFN, 'r')
|
||||
fp = open(TESTFN, encoding="utf-8")
|
||||
savestdin = sys.stdin
|
||||
savestdout = sys.stdout # Eats the echo
|
||||
try:
|
||||
@@ -1387,6 +1484,24 @@ class BuiltinTest(unittest.TestCase):
|
||||
|
||||
self.assertEqual(sum(range(10), 1000), 1045)
|
||||
self.assertEqual(sum(range(10), start=1000), 1045)
|
||||
self.assertEqual(sum(range(10), 2**31-5), 2**31+40)
|
||||
self.assertEqual(sum(range(10), 2**63-5), 2**63+40)
|
||||
|
||||
self.assertEqual(sum(i % 2 != 0 for i in range(10)), 5)
|
||||
self.assertEqual(sum((i % 2 != 0 for i in range(10)), 2**31-3),
|
||||
2**31+2)
|
||||
self.assertEqual(sum((i % 2 != 0 for i in range(10)), 2**63-3),
|
||||
2**63+2)
|
||||
self.assertIs(sum([], False), False)
|
||||
|
||||
self.assertEqual(sum(i / 2 for i in range(10)), 22.5)
|
||||
self.assertEqual(sum((i / 2 for i in range(10)), 1000), 1022.5)
|
||||
self.assertEqual(sum((i / 2 for i in range(10)), 1000.25), 1022.75)
|
||||
self.assertEqual(sum([0.5, 1]), 1.5)
|
||||
self.assertEqual(sum([1, 0.5]), 1.5)
|
||||
self.assertEqual(repr(sum([-0.0])), '0.0')
|
||||
self.assertEqual(repr(sum([-0.0], -0.0)), '-0.0')
|
||||
self.assertEqual(repr(sum([], -0.0)), '-0.0')
|
||||
|
||||
self.assertRaises(TypeError, sum)
|
||||
self.assertRaises(TypeError, sum, 42)
|
||||
@@ -1398,6 +1513,9 @@ class BuiltinTest(unittest.TestCase):
|
||||
self.assertRaises(TypeError, sum, [[1], [2], [3]])
|
||||
self.assertRaises(TypeError, sum, [{2:3}])
|
||||
self.assertRaises(TypeError, sum, [{2:3}]*2, {2:3})
|
||||
self.assertRaises(TypeError, sum, [], '')
|
||||
self.assertRaises(TypeError, sum, [], b'')
|
||||
self.assertRaises(TypeError, sum, [], bytearray())
|
||||
|
||||
class BadSeq:
|
||||
def __getitem__(self, index):
|
||||
@@ -1499,6 +1617,36 @@ class BuiltinTest(unittest.TestCase):
|
||||
z1 = zip(a, b)
|
||||
self.check_iter_pickle(z1, t, proto)
|
||||
|
||||
def test_zip_pickle_strict(self):
|
||||
a = (1, 2, 3)
|
||||
b = (4, 5, 6)
|
||||
t = [(1, 4), (2, 5), (3, 6)]
|
||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||
z1 = zip(a, b, strict=True)
|
||||
self.check_iter_pickle(z1, t, proto)
|
||||
|
||||
def test_zip_pickle_strict_fail(self):
|
||||
a = (1, 2, 3)
|
||||
b = (4, 5, 6, 7)
|
||||
t = [(1, 4), (2, 5), (3, 6)]
|
||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||
z1 = zip(a, b, strict=True)
|
||||
z2 = pickle.loads(pickle.dumps(z1, proto))
|
||||
self.assertEqual(self.iter_error(z1, ValueError), t)
|
||||
self.assertEqual(self.iter_error(z2, ValueError), t)
|
||||
|
||||
def test_zip_bad_iterable(self):
|
||||
exception = TypeError()
|
||||
|
||||
class BadIterable:
|
||||
def __iter__(self):
|
||||
raise exception
|
||||
|
||||
with self.assertRaises(TypeError) as cm:
|
||||
zip(BadIterable())
|
||||
|
||||
self.assertIs(cm.exception, exception)
|
||||
|
||||
def test_zip_strict(self):
|
||||
self.assertEqual(tuple(zip((1, 2, 3), 'abc', strict=True)),
|
||||
((1, 'a'), (2, 'b'), (3, 'c')))
|
||||
@@ -1581,6 +1729,18 @@ class BuiltinTest(unittest.TestCase):
|
||||
l8 = self.iter_error(zip(Iter(3), "AB", strict=True), ValueError)
|
||||
self.assertEqual(l8, [(2, "A"), (1, "B")])
|
||||
|
||||
@support.cpython_only
|
||||
def test_zip_result_gc(self):
|
||||
# bpo-42536: zip's tuple-reuse speed trick breaks the GC's assumptions
|
||||
# about what can be untracked. Make sure we re-track result tuples
|
||||
# whenever we reuse them.
|
||||
it = zip([[]])
|
||||
gc.collect()
|
||||
# That GC collection probably untracked the recycled internal result
|
||||
# tuple, which is initialized to (None,). Make sure it's re-tracked when
|
||||
# it's mutated and returned from __next__:
|
||||
self.assertTrue(gc.is_tracked(next(it)))
|
||||
|
||||
def test_format(self):
|
||||
# Test the basic machinery of the format() builtin. Don't test
|
||||
# the specifics of the various formatters
|
||||
@@ -1696,6 +1856,11 @@ class BuiltinTest(unittest.TestCase):
|
||||
self.assertRaises(ValueError, x.translate, b"1", 1)
|
||||
self.assertRaises(TypeError, x.translate, b"1"*256, 1)
|
||||
|
||||
def test_bytearray_extend_error(self):
|
||||
array = bytearray()
|
||||
bad_iter = map(int, "X")
|
||||
self.assertRaises(ValueError, array.extend, bad_iter)
|
||||
|
||||
def test_construct_singletons(self):
|
||||
for const in None, Ellipsis, NotImplemented:
|
||||
tp = type(const)
|
||||
@@ -1703,6 +1868,20 @@ class BuiltinTest(unittest.TestCase):
|
||||
self.assertRaises(TypeError, tp, 1, 2)
|
||||
self.assertRaises(TypeError, tp, a=1, b=2)
|
||||
|
||||
def test_warning_notimplemented(self):
|
||||
# Issue #35712: NotImplemented is a sentinel value that should never
|
||||
# be evaluated in a boolean context (virtually all such use cases
|
||||
# are a result of accidental misuse implementing rich comparison
|
||||
# operations in terms of one another).
|
||||
# For the time being, it will continue to evaluate as a true value, but
|
||||
# issue a deprecation warning (with the eventual intent to make it
|
||||
# a TypeError).
|
||||
self.assertWarns(DeprecationWarning, bool, NotImplemented)
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
self.assertTrue(NotImplemented)
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
self.assertFalse(not NotImplemented)
|
||||
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON, AttributeError: module 'sys' has no attribute '__breakpointhook__'")
|
||||
class TestBreakpoint(unittest.TestCase):
|
||||
@@ -1815,7 +1994,21 @@ class PtyTests(unittest.TestCase):
|
||||
"""Tests that use a pseudo terminal to guarantee stdin and stdout are
|
||||
terminals in the test environment"""
|
||||
|
||||
@staticmethod
|
||||
def handle_sighup(signum, frame):
|
||||
# bpo-40140: if the process is the session leader, os.close(fd)
|
||||
# of "pid, fd = pty.fork()" can raise SIGHUP signal:
|
||||
# just ignore the signal.
|
||||
pass
|
||||
|
||||
def run_child(self, child, terminal_input):
|
||||
old_sighup = signal.signal(signal.SIGHUP, self.handle_sighup)
|
||||
try:
|
||||
return self._run_child(child, terminal_input)
|
||||
finally:
|
||||
signal.signal(signal.SIGHUP, old_sighup)
|
||||
|
||||
def _run_child(self, child, terminal_input):
|
||||
r, w = os.pipe() # Pipe test results from child back to parent
|
||||
try:
|
||||
pid, fd = pty.fork()
|
||||
@@ -1824,6 +2017,7 @@ class PtyTests(unittest.TestCase):
|
||||
os.close(w)
|
||||
self.skipTest("pty.fork() raised {}".format(e))
|
||||
raise
|
||||
|
||||
if pid == 0:
|
||||
# Child
|
||||
try:
|
||||
@@ -1837,11 +2031,13 @@ class PtyTests(unittest.TestCase):
|
||||
finally:
|
||||
# We don't want to return to unittest...
|
||||
os._exit(0)
|
||||
|
||||
# Parent
|
||||
os.close(w)
|
||||
os.write(fd, terminal_input)
|
||||
|
||||
# Get results from the pipe
|
||||
with open(r, "r") as rpipe:
|
||||
with open(r, encoding="utf-8") as rpipe:
|
||||
lines = []
|
||||
while True:
|
||||
line = rpipe.readline().strip()
|
||||
@@ -1849,6 +2045,7 @@ class PtyTests(unittest.TestCase):
|
||||
# The other end was closed => the child exited
|
||||
break
|
||||
lines.append(line)
|
||||
|
||||
# Check the result was got and corresponds to the user's terminal input
|
||||
if len(lines) != 2:
|
||||
# Something went wrong, try to get at stderr
|
||||
@@ -1866,10 +2063,12 @@ class PtyTests(unittest.TestCase):
|
||||
child_output = child_output.decode("ascii", "ignore")
|
||||
self.fail("got %d lines in pipe but expected 2, child output was:\n%s"
|
||||
% (len(lines), child_output))
|
||||
|
||||
# bpo-40155: Close the PTY before waiting for the child process
|
||||
# completion, otherwise the child process hangs on AIX.
|
||||
os.close(fd)
|
||||
|
||||
# Wait until the child process completes
|
||||
os.waitpid(pid, 0)
|
||||
support.wait_process(pid, exitcode=0)
|
||||
|
||||
return lines
|
||||
|
||||
@@ -1904,12 +2103,24 @@ class PtyTests(unittest.TestCase):
|
||||
# is different and invokes GNU readline if available).
|
||||
self.check_input_tty("prompt", b"quux")
|
||||
|
||||
def skip_if_readline(self):
|
||||
# bpo-13886: When the readline module is loaded, PyOS_Readline() uses
|
||||
# the readline implementation. In some cases, the Python readline
|
||||
# callback rlhandler() is called by readline with a string without
|
||||
# non-ASCII characters. Skip tests on non-ASCII characters if the
|
||||
# readline module is loaded, since test_builtin is not intented to test
|
||||
# the readline module, but the builtins module.
|
||||
if 'readline' in sys.modules:
|
||||
self.skipTest("the readline module is loaded")
|
||||
|
||||
def test_input_tty_non_ascii(self):
|
||||
# Check stdin/stdout encoding is used when invoking GNU readline
|
||||
self.skip_if_readline()
|
||||
# Check stdin/stdout encoding is used when invoking PyOS_Readline()
|
||||
self.check_input_tty("prompté", b"quux\xe9", "utf-8")
|
||||
|
||||
def test_input_tty_non_ascii_unicode_errors(self):
|
||||
# Check stdin/stdout error handler is used when invoking GNU readline
|
||||
self.skip_if_readline()
|
||||
# Check stdin/stdout error handler is used when invoking PyOS_Readline()
|
||||
self.check_input_tty("prompté", b"quux\xe9", "ascii")
|
||||
|
||||
def test_input_no_stdout_fileno(self):
|
||||
@@ -1941,7 +2152,7 @@ class TestSorted(unittest.TestCase):
|
||||
self.assertEqual(data, sorted(copy, key=lambda x: -x))
|
||||
self.assertNotEqual(data, copy)
|
||||
random.shuffle(copy)
|
||||
self.assertEqual(data, sorted(copy, reverse=1))
|
||||
self.assertEqual(data, sorted(copy, reverse=True))
|
||||
self.assertNotEqual(data, copy)
|
||||
|
||||
def test_bad_arguments(self):
|
||||
@@ -2178,9 +2389,8 @@ class TestType(unittest.TestCase):
|
||||
|
||||
|
||||
def load_tests(loader, tests, pattern):
|
||||
# XXX RustPython
|
||||
# from doctest import DocTestSuite
|
||||
# tests.addTest(DocTestSuite(builtins))
|
||||
from doctest import DocTestSuite
|
||||
tests.addTest(DocTestSuite(builtins))
|
||||
return tests
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Vendored
+1
-1
@@ -534,7 +534,7 @@ class ClassTests(unittest.TestCase):
|
||||
# In debug mode, printed XXX undetected error and
|
||||
# raises AttributeError
|
||||
I()
|
||||
except AttributeError as x:
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
self.fail("attribute error for I.__init__ got masked")
|
||||
|
||||
Vendored
+5781
-5720
File diff suppressed because it is too large.
Load diff
Vendored
+42
-6
@@ -66,6 +66,9 @@ class GeneralFloatCases(unittest.TestCase):
|
||||
# See bpo-34087
|
||||
self.assertRaises(ValueError, float, '\u3053\u3093\u306b\u3061\u306f')
|
||||
|
||||
def test_noargs(self):
|
||||
self.assertEqual(float(), 0.0)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_underscores(self):
|
||||
@@ -571,6 +574,25 @@ class GeneralFloatCases(unittest.TestCase):
|
||||
#self.assertTrue(0.0 < pow_op(2.0, -1047) < 1e-315)
|
||||
#self.assertTrue(0.0 > pow_op(-2.0, -1047) > -1e-315)
|
||||
|
||||
def test_hash(self):
|
||||
for x in range(-30, 30):
|
||||
self.assertEqual(hash(float(x)), hash(x))
|
||||
self.assertEqual(hash(float(sys.float_info.max)),
|
||||
hash(int(sys.float_info.max)))
|
||||
self.assertEqual(hash(float('inf')), sys.hash_info.inf)
|
||||
self.assertEqual(hash(float('-inf')), -sys.hash_info.inf)
|
||||
|
||||
def test_hash_nan(self):
|
||||
value = float('nan')
|
||||
self.assertEqual(hash(value), object.__hash__(value))
|
||||
class H:
|
||||
def __hash__(self):
|
||||
return 42
|
||||
class F(float, H):
|
||||
pass
|
||||
value = F('nan')
|
||||
self.assertEqual(hash(value), object.__hash__(value))
|
||||
|
||||
|
||||
@requires_setformat
|
||||
class FormatFunctionsTestCase(unittest.TestCase):
|
||||
@@ -740,7 +762,7 @@ class FormatTestCase(unittest.TestCase):
|
||||
@unittest.expectedFailure
|
||||
@support.requires_IEEE_754
|
||||
def test_format_testfile(self):
|
||||
with open(format_testfile) as testfile:
|
||||
with open(format_testfile, encoding="utf-8") as testfile:
|
||||
for line in testfile:
|
||||
if line.startswith('--'):
|
||||
continue
|
||||
@@ -782,7 +804,7 @@ class FormatTestCase(unittest.TestCase):
|
||||
class ReprTestCase(unittest.TestCase):
|
||||
def test_repr(self):
|
||||
with open(os.path.join(os.path.split(__file__)[0],
|
||||
'floating_points.txt')) as floats_file:
|
||||
'floating_points.txt'), encoding="utf-8") as floats_file:
|
||||
for line in floats_file:
|
||||
line = line.strip()
|
||||
if not line or line.startswith('#'):
|
||||
@@ -1186,10 +1208,10 @@ class HexFloatTestCase(unittest.TestCase):
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_from_hex(self):
|
||||
MIN = self.MIN;
|
||||
MAX = self.MAX;
|
||||
TINY = self.TINY;
|
||||
EPS = self.EPS;
|
||||
MIN = self.MIN
|
||||
MAX = self.MAX
|
||||
TINY = self.TINY
|
||||
EPS = self.EPS
|
||||
|
||||
# two spellings of infinity, with optional signs; case-insensitive
|
||||
self.identical(fromHex('inf'), INF)
|
||||
@@ -1470,6 +1492,20 @@ class HexFloatTestCase(unittest.TestCase):
|
||||
self.identical(fromHex('0X1.0000000000001fp0'), 1.0+2*EPS)
|
||||
self.identical(fromHex('0x1.00000000000020p0'), 1.0+2*EPS)
|
||||
|
||||
# Regression test for a corner-case bug reported in b.p.o. 44954
|
||||
self.identical(fromHex('0x.8p-1074'), 0.0)
|
||||
self.identical(fromHex('0x.80p-1074'), 0.0)
|
||||
self.identical(fromHex('0x.81p-1074'), TINY)
|
||||
self.identical(fromHex('0x8p-1078'), 0.0)
|
||||
self.identical(fromHex('0x8.0p-1078'), 0.0)
|
||||
self.identical(fromHex('0x8.1p-1078'), TINY)
|
||||
self.identical(fromHex('0x80p-1082'), 0.0)
|
||||
self.identical(fromHex('0x81p-1082'), TINY)
|
||||
self.identical(fromHex('.8p-1074'), 0.0)
|
||||
self.identical(fromHex('8p-1078'), 0.0)
|
||||
self.identical(fromHex('-.8p-1074'), -0.0)
|
||||
self.identical(fromHex('+8p-1078'), 0.0)
|
||||
|
||||
def test_roundtrip(self):
|
||||
def roundtrip(x):
|
||||
return fromHex(toHex(x))
|
||||
|
||||
Vendored
+59
-28
@@ -4,6 +4,7 @@ import unittest
|
||||
import sys
|
||||
import pickle
|
||||
import itertools
|
||||
from test.support import ALWAYS_EQ
|
||||
|
||||
# pure Python implementations (3 args only), for comparison
|
||||
def pyrange(start, stop, step):
|
||||
@@ -90,6 +91,19 @@ class RangeTest(unittest.TestCase):
|
||||
r = range(-sys.maxsize, sys.maxsize, 2)
|
||||
self.assertEqual(len(r), sys.maxsize)
|
||||
|
||||
def test_range_constructor_error_messages(self):
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
"range expected at least 1 argument, got 0"
|
||||
):
|
||||
range()
|
||||
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
"range expected at most 3 arguments, got 6"
|
||||
):
|
||||
range(1, 2, 3, 4, 5, 6)
|
||||
|
||||
def test_large_operands(self):
|
||||
x = range(10**20, 10**20+10, 3)
|
||||
self.assertEqual(len(x), 4)
|
||||
@@ -289,11 +303,7 @@ class RangeTest(unittest.TestCase):
|
||||
self.assertRaises(ValueError, range(1, 2**100, 2).index, 2**87)
|
||||
self.assertEqual(range(1, 2**100, 2).index(2**87+1), 2**86)
|
||||
|
||||
class AlwaysEqual(object):
|
||||
def __eq__(self, other):
|
||||
return True
|
||||
always_equal = AlwaysEqual()
|
||||
self.assertEqual(range(10).index(always_equal), 0)
|
||||
self.assertEqual(range(10).index(ALWAYS_EQ), 0)
|
||||
|
||||
def test_user_index_method(self):
|
||||
bignum = 2*sys.maxsize
|
||||
@@ -344,11 +354,7 @@ class RangeTest(unittest.TestCase):
|
||||
self.assertEqual(range(1, 2**100, 2).count(2**87), 0)
|
||||
self.assertEqual(range(1, 2**100, 2).count(2**87+1), 1)
|
||||
|
||||
class AlwaysEqual(object):
|
||||
def __eq__(self, other):
|
||||
return True
|
||||
always_equal = AlwaysEqual()
|
||||
self.assertEqual(range(10).count(always_equal), 10)
|
||||
self.assertEqual(range(10).count(ALWAYS_EQ), 10)
|
||||
|
||||
self.assertEqual(len(range(sys.maxsize, sys.maxsize+10)), 10)
|
||||
|
||||
@@ -368,26 +374,47 @@ class RangeTest(unittest.TestCase):
|
||||
list(r))
|
||||
|
||||
def test_iterator_pickling(self):
|
||||
testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1),
|
||||
(13, 21, 3), (-2, 2, 2), (2**65, 2**65+2)]
|
||||
testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1), (13, 21, 3),
|
||||
(-2, 2, 2)]
|
||||
for M in 2**31, 2**63:
|
||||
testcases += [
|
||||
(M-3, M-1), (4*M, 4*M+2),
|
||||
(M-2, M-1, 2), (-M+1, -M, -2),
|
||||
(1, 2, M-1), (-1, -2, -M),
|
||||
(1, M-1, M-1), (-1, -M, -M),
|
||||
]
|
||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||
for t in testcases:
|
||||
it = itorg = iter(range(*t))
|
||||
data = list(range(*t))
|
||||
with self.subTest(proto=proto, t=t):
|
||||
it = itorg = iter(range(*t))
|
||||
data = list(range(*t))
|
||||
|
||||
d = pickle.dumps(it, proto)
|
||||
it = pickle.loads(d)
|
||||
self.assertEqual(type(itorg), type(it))
|
||||
self.assertEqual(list(it), data)
|
||||
|
||||
it = pickle.loads(d)
|
||||
try:
|
||||
next(it)
|
||||
except StopIteration:
|
||||
continue
|
||||
d = pickle.dumps(it, proto)
|
||||
it = pickle.loads(d)
|
||||
self.assertEqual(list(it), data[1:])
|
||||
|
||||
def test_iterator_pickling_overflowing_index(self):
|
||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||
with self.subTest(proto=proto):
|
||||
it = iter(range(2**32 + 2))
|
||||
_, _, idx = it.__reduce__()
|
||||
self.assertEqual(idx, 0)
|
||||
it.__setstate__(2**32 + 1) # undocumented way to set r->index
|
||||
_, _, idx = it.__reduce__()
|
||||
self.assertEqual(idx, 2**32 + 1)
|
||||
d = pickle.dumps(it, proto)
|
||||
it = pickle.loads(d)
|
||||
self.assertEqual(type(itorg), type(it))
|
||||
self.assertEqual(list(it), data)
|
||||
|
||||
it = pickle.loads(d)
|
||||
try:
|
||||
next(it)
|
||||
except StopIteration:
|
||||
continue
|
||||
d = pickle.dumps(it, proto)
|
||||
it = pickle.loads(d)
|
||||
self.assertEqual(list(it), data[1:])
|
||||
self.assertEqual(next(it), 2**32 + 1)
|
||||
|
||||
def test_exhausted_iterator_pickling(self):
|
||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||
@@ -429,9 +456,7 @@ class RangeTest(unittest.TestCase):
|
||||
self.assertIn(True, range(3))
|
||||
self.assertIn(1+0j, range(3))
|
||||
|
||||
class C1:
|
||||
def __eq__(self, other): return True
|
||||
self.assertIn(C1(), range(3))
|
||||
self.assertIn(ALWAYS_EQ, range(3))
|
||||
|
||||
# Objects are never coerced into other types for comparison.
|
||||
class C2:
|
||||
@@ -644,11 +669,17 @@ class RangeTest(unittest.TestCase):
|
||||
self.assert_attrs(range(0, 10, 3), 0, 10, 3)
|
||||
self.assert_attrs(range(10, 0, -1), 10, 0, -1)
|
||||
self.assert_attrs(range(10, 0, -3), 10, 0, -3)
|
||||
self.assert_attrs(range(True), 0, 1, 1)
|
||||
self.assert_attrs(range(False, True), 0, 1, 1)
|
||||
self.assert_attrs(range(False, True, True), 0, 1, 1)
|
||||
|
||||
def assert_attrs(self, rangeobj, start, stop, step):
|
||||
self.assertEqual(rangeobj.start, start)
|
||||
self.assertEqual(rangeobj.stop, stop)
|
||||
self.assertEqual(rangeobj.step, step)
|
||||
self.assertIs(type(rangeobj.start), int)
|
||||
self.assertIs(type(rangeobj.stop), int)
|
||||
self.assertIs(type(rangeobj.step), int)
|
||||
|
||||
with self.assertRaises(AttributeError):
|
||||
rangeobj.start = 0
|
||||
|
||||
Vendored
-3
@@ -220,9 +220,6 @@ class MiscTest(unittest.TestCase):
|
||||
for func in (do, operator.not_):
|
||||
self.assertRaises(Exc, func, Bad())
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
import sys
|
||||
@unittest.skipIf(sys.platform == "win32", "TODO: RUSTPYTHON, thread 'main' has overflowed its stack")
|
||||
@support.no_tracing
|
||||
def test_recursion(self):
|
||||
# Check that comparison for recursive objects fails gracefully
|
||||
|
||||
Reference in new issue
Block a user