Merge pull request #5127 from NakanoMiku39/main

Update test files from CPython v3.12.0
This commit is contained in:
Jeong, YunWon authored and GitHub committed 2023-12-01 04:14:02 +09:00
commit 0fab6e6063
17 files changed
+1186 -61

No files matched your search

+9 -9
View File
@@ -18,9 +18,6 @@ from test.support.script_helper import (
if not support.has_subprocess_support:
raise unittest.SkipTest("test module requires subprocess")
# Debug build?
Py_DEBUG = hasattr(sys, "gettotalrefcount")
# XXX (ncoghlan): Move to script_helper and make consistent with run_python
def _kill_python_and_exit_code(p):
@@ -144,7 +141,7 @@ class CmdLineTest(unittest.TestCase):
# "-X showrefcount" shows the refcount, but only in debug builds
rc, out, err = run_python('-I', '-X', 'showrefcount', '-c', code)
self.assertEqual(out.rstrip(), b"{'showrefcount': True}")
if Py_DEBUG:
if support.Py_DEBUG:
# bpo-46417: Tolerate negative reference count which can occur
# because of bugs in C extensions. This test is only about checking
# the showrefcount feature.
@@ -753,7 +750,7 @@ class CmdLineTest(unittest.TestCase):
code = ("import warnings; "
"print(' '.join('%s::%s' % (f[0], f[2].__name__) "
"for f in warnings.filters))")
if Py_DEBUG:
if support.Py_DEBUG:
expected_filters = "default::Warning"
else:
expected_filters = ("default::Warning "
@@ -827,7 +824,7 @@ class CmdLineTest(unittest.TestCase):
expected_filters = ("error::BytesWarning "
"once::UserWarning "
"always::UserWarning")
if not Py_DEBUG:
if not support.Py_DEBUG:
expected_filters += (" "
"default::DeprecationWarning "
"ignore::DeprecationWarning "
@@ -867,10 +864,10 @@ class CmdLineTest(unittest.TestCase):
# Test the PYTHONMALLOC environment variable
pymalloc = support.with_pymalloc()
if pymalloc:
default_name = 'pymalloc_debug' if Py_DEBUG else 'pymalloc'
default_name = 'pymalloc_debug' if support.Py_DEBUG else 'pymalloc'
default_name_debug = 'pymalloc_debug'
else:
default_name = 'malloc_debug' if Py_DEBUG else 'malloc'
default_name = 'malloc_debug' if support.Py_DEBUG else 'malloc'
default_name_debug = 'malloc_debug'
tests = [
@@ -933,6 +930,8 @@ class CmdLineTest(unittest.TestCase):
self.assertTrue(proc.stderr.startswith(err_msg), proc.stderr)
self.assertNotEqual(proc.returncode, 0)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_int_max_str_digits(self):
code = "import sys; print(sys.flags.int_max_str_digits, sys.get_int_max_str_digits())"
@@ -950,7 +949,8 @@ class CmdLineTest(unittest.TestCase):
return tuple(int(i) for i in out.split())
res = assert_python_ok('-c', code)
self.assertEqual(res2int(res), (-1, sys.get_int_max_str_digits()))
current_max = sys.get_int_max_str_digits()
self.assertEqual(res2int(res), (current_max, current_max))
res = assert_python_ok('-X', 'int_max_str_digits=0', '-c', code)
self.assertEqual(res2int(res), (0, 0))
res = assert_python_ok('-X', 'int_max_str_digits=4000', '-c', code)
+33 -4
View File
@@ -662,9 +662,9 @@ class CmdLineTest(unittest.TestCase):
self.assertEqual(
stderr.splitlines()[-3:],
[
b' foo"""',
b' ^',
b'SyntaxError: f-string: empty expression not allowed',
b' foo = f"""{}',
b' ^',
b'SyntaxError: f-string: valid expression required before \'}\'',
],
)
@@ -685,6 +685,35 @@ class CmdLineTest(unittest.TestCase):
],
)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_syntaxerror_null_bytes(self):
script = "x = '\0' nothing to see here\n';import os;os.system('echo pwnd')\n"
with os_helper.temp_dir() as script_dir:
script_name = _make_test_script(script_dir, 'script', script)
exitcode, stdout, stderr = assert_python_failure(script_name)
self.assertEqual(
stderr.splitlines()[-2:],
[ b" x = '",
b'SyntaxError: source code cannot contain null bytes'
],
)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_syntaxerror_null_bytes_in_multiline_string(self):
scripts = ["\n'''\nmultilinestring\0\n'''", "\nf'''\nmultilinestring\0\n'''"] # Both normal and f-strings
with os_helper.temp_dir() as script_dir:
for script in scripts:
script_name = _make_test_script(script_dir, 'script', script)
_, _, stderr = assert_python_failure(script_name)
self.assertEqual(
stderr.splitlines()[-2:],
[ b" multilinestring",
b'SyntaxError: source code cannot contain null bytes'
]
)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_consistent_sys_path_for_direct_execution(self):
@@ -785,7 +814,7 @@ class CmdLineTest(unittest.TestCase):
with os_helper.temp_dir() as work_dir:
script_name = _make_test_script(work_dir, 'script.py', script)
with open(script_name, "r") as fp:
p = spawn_python(f"/dev/fd/{fp.fileno()}", close_fds=False, pass_fds=(0,1,2,fp.fileno()))
p = spawn_python(f"/dev/fd/{fp.fileno()}", close_fds=True, pass_fds=(0,1,2,fp.fileno()))
out, err = p.communicate()
self.assertEqual(out, b"12345678912345678912345\n")
+1
View File
@@ -6,6 +6,7 @@ from contextlib import ExitStack
from unittest import mock
from test.support import import_helper
code = import_helper.import_module('code')
+409 -17
View File
@@ -1,21 +1,27 @@
"""Test equality and order comparisons."""
import unittest
from test.support import ALWAYS_EQ
from fractions import Fraction
from decimal import Decimal
class Empty:
def __repr__(self):
return '<Empty>'
class Cmp:
def __init__(self,arg):
self.arg = arg
class ComparisonSimpleTest(unittest.TestCase):
"""Test equality and order comparisons for some simple cases."""
def __repr__(self):
return '<Cmp %s>' % self.arg
class Empty:
def __repr__(self):
return '<Empty>'
def __eq__(self, other):
return self.arg == other
class Cmp:
def __init__(self, arg):
self.arg = arg
def __repr__(self):
return '<Cmp %s>' % self.arg
def __eq__(self, other):
return self.arg == other
class ComparisonTest(unittest.TestCase):
set1 = [2, 2.0, 2, 2+0j, Cmp(2.0)]
set2 = [[1], (3,), None, Empty()]
candidates = set1 + set2
@@ -32,16 +38,15 @@ class ComparisonTest(unittest.TestCase):
# Ensure default comparison compares id() of args
L = []
for i in range(10):
L.insert(len(L)//2, Empty())
L.insert(len(L)//2, self.Empty())
for a in L:
for b in L:
self.assertEqual(a == b, id(a) == id(b),
'a=%r, b=%r' % (a, b))
self.assertEqual(a == b, a is b, 'a=%r, b=%r' % (a, b))
def test_ne_defaults_to_not_eq(self):
a = Cmp(1)
b = Cmp(1)
c = Cmp(2)
a = self.Cmp(1)
b = self.Cmp(1)
c = self.Cmp(2)
self.assertIs(a == b, True)
self.assertIs(a != b, False)
self.assertIs(a != c, True)
@@ -114,5 +119,392 @@ class ComparisonTest(unittest.TestCase):
self.assertEqual(ALWAYS_EQ, y)
class ComparisonFullTest(unittest.TestCase):
"""Test equality and ordering comparisons for built-in types and
user-defined classes that implement relevant combinations of rich
comparison methods.
"""
class CompBase:
"""Base class for classes with rich comparison methods.
The "x" attribute should be set to an underlying value to compare.
Derived classes have a "meth" tuple attribute listing names of
comparison methods implemented. See assert_total_order().
"""
# Class without any rich comparison methods.
class CompNone(CompBase):
meth = ()
# Classes with all combinations of value-based equality comparison methods.
class CompEq(CompBase):
meth = ("eq",)
def __eq__(self, other):
return self.x == other.x
class CompNe(CompBase):
meth = ("ne",)
def __ne__(self, other):
return self.x != other.x
class CompEqNe(CompBase):
meth = ("eq", "ne")
def __eq__(self, other):
return self.x == other.x
def __ne__(self, other):
return self.x != other.x
# Classes with all combinations of value-based less/greater-than order
# comparison methods.
class CompLt(CompBase):
meth = ("lt",)
def __lt__(self, other):
return self.x < other.x
class CompGt(CompBase):
meth = ("gt",)
def __gt__(self, other):
return self.x > other.x
class CompLtGt(CompBase):
meth = ("lt", "gt")
def __lt__(self, other):
return self.x < other.x
def __gt__(self, other):
return self.x > other.x
# Classes with all combinations of value-based less/greater-or-equal-than
# order comparison methods
class CompLe(CompBase):
meth = ("le",)
def __le__(self, other):
return self.x <= other.x
class CompGe(CompBase):
meth = ("ge",)
def __ge__(self, other):
return self.x >= other.x
class CompLeGe(CompBase):
meth = ("le", "ge")
def __le__(self, other):
return self.x <= other.x
def __ge__(self, other):
return self.x >= other.x
# It should be sufficient to combine the comparison methods only within
# each group.
all_comp_classes = (
CompNone,
CompEq, CompNe, CompEqNe, # equal group
CompLt, CompGt, CompLtGt, # less/greater-than group
CompLe, CompGe, CompLeGe) # less/greater-or-equal group
def create_sorted_instances(self, class_, values):
"""Create objects of type `class_` and return them in a list.
`values` is a list of values that determines the value of data
attribute `x` of each object.
Objects in the returned list are sorted by their identity. They
assigned values in `values` list order. By assign decreasing
values to objects with increasing identities, testcases can assert
that order comparison is performed by value and not by identity.
"""
instances = [class_() for __ in range(len(values))]
instances.sort(key=id)
# Assign the provided values to the instances.
for inst, value in zip(instances, values):
inst.x = value
return instances
def assert_equality_only(self, a, b, equal):
"""Assert equality result and that ordering is not implemented.
a, b: Instances to be tested (of same or different type).
equal: Boolean indicating the expected equality comparison results.
"""
self.assertEqual(a == b, equal)
self.assertEqual(b == a, equal)
self.assertEqual(a != b, not equal)
self.assertEqual(b != a, not equal)
with self.assertRaisesRegex(TypeError, "not supported"):
a < b
with self.assertRaisesRegex(TypeError, "not supported"):
a <= b
with self.assertRaisesRegex(TypeError, "not supported"):
a > b
with self.assertRaisesRegex(TypeError, "not supported"):
a >= b
with self.assertRaisesRegex(TypeError, "not supported"):
b < a
with self.assertRaisesRegex(TypeError, "not supported"):
b <= a
with self.assertRaisesRegex(TypeError, "not supported"):
b > a
with self.assertRaisesRegex(TypeError, "not supported"):
b >= a
def assert_total_order(self, a, b, comp, a_meth=None, b_meth=None):
"""Test total ordering comparison of two instances.
a, b: Instances to be tested (of same or different type).
comp: -1, 0, or 1 indicates that the expected order comparison
result for operations that are supported by the classes is
a <, ==, or > b.
a_meth, b_meth: Either None, indicating that all rich comparison
methods are available, aa for builtins, or the tuple (subset)
of "eq", "ne", "lt", "le", "gt", and "ge" that are available
for the corresponding instance (of a user-defined class).
"""
self.assert_eq_subtest(a, b, comp, a_meth, b_meth)
self.assert_ne_subtest(a, b, comp, a_meth, b_meth)
self.assert_lt_subtest(a, b, comp, a_meth, b_meth)
self.assert_le_subtest(a, b, comp, a_meth, b_meth)
self.assert_gt_subtest(a, b, comp, a_meth, b_meth)
self.assert_ge_subtest(a, b, comp, a_meth, b_meth)
# The body of each subtest has form:
#
# if value-based comparison methods:
# expect what the testcase defined for a op b and b rop a;
# else: no value-based comparison
# expect default behavior of object for a op b and b rop a.
def assert_eq_subtest(self, a, b, comp, a_meth, b_meth):
if a_meth is None or "eq" in a_meth or "eq" in b_meth:
self.assertEqual(a == b, comp == 0)
self.assertEqual(b == a, comp == 0)
else:
self.assertEqual(a == b, a is b)
self.assertEqual(b == a, a is b)
def assert_ne_subtest(self, a, b, comp, a_meth, b_meth):
if a_meth is None or not {"ne", "eq"}.isdisjoint(a_meth + b_meth):
self.assertEqual(a != b, comp != 0)
self.assertEqual(b != a, comp != 0)
else:
self.assertEqual(a != b, a is not b)
self.assertEqual(b != a, a is not b)
def assert_lt_subtest(self, a, b, comp, a_meth, b_meth):
if a_meth is None or "lt" in a_meth or "gt" in b_meth:
self.assertEqual(a < b, comp < 0)
self.assertEqual(b > a, comp < 0)
else:
with self.assertRaisesRegex(TypeError, "not supported"):
a < b
with self.assertRaisesRegex(TypeError, "not supported"):
b > a
def assert_le_subtest(self, a, b, comp, a_meth, b_meth):
if a_meth is None or "le" in a_meth or "ge" in b_meth:
self.assertEqual(a <= b, comp <= 0)
self.assertEqual(b >= a, comp <= 0)
else:
with self.assertRaisesRegex(TypeError, "not supported"):
a <= b
with self.assertRaisesRegex(TypeError, "not supported"):
b >= a
def assert_gt_subtest(self, a, b, comp, a_meth, b_meth):
if a_meth is None or "gt" in a_meth or "lt" in b_meth:
self.assertEqual(a > b, comp > 0)
self.assertEqual(b < a, comp > 0)
else:
with self.assertRaisesRegex(TypeError, "not supported"):
a > b
with self.assertRaisesRegex(TypeError, "not supported"):
b < a
def assert_ge_subtest(self, a, b, comp, a_meth, b_meth):
if a_meth is None or "ge" in a_meth or "le" in b_meth:
self.assertEqual(a >= b, comp >= 0)
self.assertEqual(b <= a, comp >= 0)
else:
with self.assertRaisesRegex(TypeError, "not supported"):
a >= b
with self.assertRaisesRegex(TypeError, "not supported"):
b <= a
def test_objects(self):
"""Compare instances of type 'object'."""
a = object()
b = object()
self.assert_equality_only(a, a, True)
self.assert_equality_only(a, b, False)
def test_comp_classes_same(self):
"""Compare same-class instances with comparison methods."""
for cls in self.all_comp_classes:
with self.subTest(cls):
instances = self.create_sorted_instances(cls, (1, 2, 1))
# Same object.
self.assert_total_order(instances[0], instances[0], 0,
cls.meth, cls.meth)
# Different objects, same value.
self.assert_total_order(instances[0], instances[2], 0,
cls.meth, cls.meth)
# Different objects, value ascending for ascending identities.
self.assert_total_order(instances[0], instances[1], -1,
cls.meth, cls.meth)
# different objects, value descending for ascending identities.
# This is the interesting case to assert that order comparison
# is performed based on the value and not based on the identity.
self.assert_total_order(instances[1], instances[2], +1,
cls.meth, cls.meth)
def test_comp_classes_different(self):
"""Compare different-class instances with comparison methods."""
for cls_a in self.all_comp_classes:
for cls_b in self.all_comp_classes:
with self.subTest(a=cls_a, b=cls_b):
a1 = cls_a()
a1.x = 1
b1 = cls_b()
b1.x = 1
b2 = cls_b()
b2.x = 2
self.assert_total_order(
a1, b1, 0, cls_a.meth, cls_b.meth)
self.assert_total_order(
a1, b2, -1, cls_a.meth, cls_b.meth)
def test_str_subclass(self):
"""Compare instances of str and a subclass."""
class StrSubclass(str):
pass
s1 = str("a")
s2 = str("b")
c1 = StrSubclass("a")
c2 = StrSubclass("b")
c3 = StrSubclass("b")
self.assert_total_order(s1, s1, 0)
self.assert_total_order(s1, s2, -1)
self.assert_total_order(c1, c1, 0)
self.assert_total_order(c1, c2, -1)
self.assert_total_order(c2, c3, 0)
self.assert_total_order(s1, c2, -1)
self.assert_total_order(s2, c3, 0)
self.assert_total_order(c1, s2, -1)
self.assert_total_order(c2, s2, 0)
def test_numbers(self):
"""Compare number types."""
# Same types.
i1 = 1001
i2 = 1002
self.assert_total_order(i1, i1, 0)
self.assert_total_order(i1, i2, -1)
f1 = 1001.0
f2 = 1001.1
self.assert_total_order(f1, f1, 0)
self.assert_total_order(f1, f2, -1)
q1 = Fraction(2002, 2)
q2 = Fraction(2003, 2)
self.assert_total_order(q1, q1, 0)
self.assert_total_order(q1, q2, -1)
d1 = Decimal('1001.0')
d2 = Decimal('1001.1')
self.assert_total_order(d1, d1, 0)
self.assert_total_order(d1, d2, -1)
c1 = 1001+0j
c2 = 1001+1j
self.assert_equality_only(c1, c1, True)
self.assert_equality_only(c1, c2, False)
# Mixing types.
for n1, n2 in ((i1,f1), (i1,q1), (i1,d1), (f1,q1), (f1,d1), (q1,d1)):
self.assert_total_order(n1, n2, 0)
for n1 in (i1, f1, q1, d1):
self.assert_equality_only(n1, c1, True)
def test_sequences(self):
"""Compare list, tuple, and range."""
l1 = [1, 2]
l2 = [2, 3]
self.assert_total_order(l1, l1, 0)
self.assert_total_order(l1, l2, -1)
t1 = (1, 2)
t2 = (2, 3)
self.assert_total_order(t1, t1, 0)
self.assert_total_order(t1, t2, -1)
r1 = range(1, 2)
r2 = range(2, 2)
self.assert_equality_only(r1, r1, True)
self.assert_equality_only(r1, r2, False)
self.assert_equality_only(t1, l1, False)
self.assert_equality_only(l1, r1, False)
self.assert_equality_only(r1, t1, False)
def test_bytes(self):
"""Compare bytes and bytearray."""
bs1 = b'a1'
bs2 = b'b2'
self.assert_total_order(bs1, bs1, 0)
self.assert_total_order(bs1, bs2, -1)
ba1 = bytearray(b'a1')
ba2 = bytearray(b'b2')
self.assert_total_order(ba1, ba1, 0)
self.assert_total_order(ba1, ba2, -1)
self.assert_total_order(bs1, ba1, 0)
self.assert_total_order(bs1, ba2, -1)
self.assert_total_order(ba1, bs1, 0)
self.assert_total_order(ba1, bs2, -1)
def test_sets(self):
"""Compare set and frozenset."""
s1 = {1, 2}
s2 = {1, 2, 3}
self.assert_total_order(s1, s1, 0)
self.assert_total_order(s1, s2, -1)
f1 = frozenset(s1)
f2 = frozenset(s2)
self.assert_total_order(f1, f1, 0)
self.assert_total_order(f1, f2, -1)
self.assert_total_order(s1, f1, 0)
self.assert_total_order(s1, f2, -1)
self.assert_total_order(f1, s1, 0)
self.assert_total_order(f1, s2, -1)
def test_mappings(self):
""" Compare dict.
"""
d1 = {1: "a", 2: "b"}
d2 = {2: "b", 3: "c"}
d3 = {3: "c", 2: "b"}
self.assert_equality_only(d1, d1, True)
self.assert_equality_only(d1, d2, False)
self.assert_equality_only(d2, d3, True)
if __name__ == '__main__':
unittest.main()
+58
View File
@@ -109,6 +109,8 @@ class ComplexTest(unittest.TestCase):
complex(random(), random()))
self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j)
self.assertRaises(TypeError, operator.truediv, 1j, None)
self.assertRaises(TypeError, operator.truediv, None, 1j)
for denom_real, denom_imag in [(0, NAN), (NAN, 0), (NAN, NAN)]:
z = complex(0, 0) / complex(denom_real, denom_imag)
@@ -140,6 +142,7 @@ class ComplexTest(unittest.TestCase):
def test_richcompare(self):
self.assertIs(complex.__eq__(1+1j, 1<<10000), False)
self.assertIs(complex.__lt__(1+1j, None), NotImplemented)
self.assertIs(complex.__eq__(1+1j, None), NotImplemented)
self.assertIs(complex.__eq__(1+1j, 1+1j), True)
self.assertIs(complex.__eq__(1+1j, 2+2j), False)
self.assertIs(complex.__ne__(1+1j, 1+1j), False)
@@ -162,6 +165,7 @@ class ComplexTest(unittest.TestCase):
self.assertIs(operator.eq(1+1j, 2+2j), False)
self.assertIs(operator.ne(1+1j, 1+1j), False)
self.assertIs(operator.ne(1+1j, 2+2j), True)
self.assertIs(operator.eq(1+1j, 2.0), False)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@@ -182,6 +186,27 @@ class ComplexTest(unittest.TestCase):
check(2 ** pow, range(1, 101), lambda delta: False, float(i))
check(2 ** 53, range(-100, 0), lambda delta: True)
def test_add(self):
self.assertEqual(1j + int(+1), complex(+1, 1))
self.assertEqual(1j + int(-1), complex(-1, 1))
self.assertRaises(OverflowError, operator.add, 1j, 10**1000)
self.assertRaises(TypeError, operator.add, 1j, None)
self.assertRaises(TypeError, operator.add, None, 1j)
def test_sub(self):
self.assertEqual(1j - int(+1), complex(-1, 1))
self.assertEqual(1j - int(-1), complex(1, 1))
self.assertRaises(OverflowError, operator.sub, 1j, 10**1000)
self.assertRaises(TypeError, operator.sub, 1j, None)
self.assertRaises(TypeError, operator.sub, None, 1j)
def test_mul(self):
self.assertEqual(1j * int(20), complex(0, 20))
self.assertEqual(1j * int(-1), complex(0, -1))
self.assertRaises(OverflowError, operator.mul, 1j, 10**1000)
self.assertRaises(TypeError, operator.mul, 1j, None)
self.assertRaises(TypeError, operator.mul, None, 1j)
def test_mod(self):
# % is no longer supported on complex numbers
with self.assertRaises(TypeError):
@@ -211,14 +236,23 @@ class ComplexTest(unittest.TestCase):
for a, b in ZERO_DIVISION:
self.assertRaises(TypeError, divmod, a, b)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_pow(self):
self.assertAlmostEqual(pow(1+1j, 0+0j), 1.0)
self.assertAlmostEqual(pow(0+0j, 2+0j), 0.0)
self.assertEqual(pow(0+0j, 2000+0j), 0.0)
self.assertEqual(pow(0, 0+0j), 1.0)
self.assertEqual(pow(-1, 0+0j), 1.0)
self.assertRaises(ZeroDivisionError, pow, 0+0j, 1j)
self.assertRaises(ZeroDivisionError, pow, 0+0j, -1000)
self.assertAlmostEqual(pow(1j, -1), 1/1j)
self.assertAlmostEqual(pow(1j, 200), 1)
self.assertRaises(ValueError, pow, 1+1j, 1+1j, 1+1j)
self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j)
self.assertRaises(TypeError, pow, 1j, None)
self.assertRaises(TypeError, pow, None, 1j)
self.assertAlmostEqual(pow(1j, 0.5), 0.7071067811865476+0.7071067811865475j)
a = 3.33+4.43j
self.assertEqual(a ** 0j, 1)
@@ -303,6 +337,7 @@ class ComplexTest(unittest.TestCase):
for i in range(100):
self.assertTrue(complex(random() + 1e-6, random() + 1e-6))
self.assertTrue(not complex(0.0, 0.0))
self.assertTrue(1j)
def test_conjugate(self):
self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j)
@@ -318,6 +353,8 @@ class ComplexTest(unittest.TestCase):
self.assertRaises(TypeError, complex, {})
self.assertRaises(TypeError, complex, NS(1.5))
self.assertRaises(TypeError, complex, NS(1))
self.assertRaises(TypeError, complex, object())
self.assertRaises(TypeError, complex, NS(4.25+0.5j), object())
self.assertAlmostEqual(complex("1+10j"), 1+10j)
self.assertAlmostEqual(complex(10), 10+0j)
@@ -363,6 +400,8 @@ class ComplexTest(unittest.TestCase):
self.assertAlmostEqual(complex('1e-500'), 0.0 + 0.0j)
self.assertAlmostEqual(complex('-1e-500j'), 0.0 - 0.0j)
self.assertAlmostEqual(complex('-1e-500+1e-500j'), -0.0 + 0.0j)
self.assertEqual(complex('1-1j'), 1.0 - 1j)
self.assertEqual(complex('1J'), 1j)
class complex2(complex): pass
self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j)
@@ -533,6 +572,14 @@ class ComplexTest(unittest.TestCase):
self.assertFloatsAreIdentical(z.real, x)
self.assertFloatsAreIdentical(z.imag, y)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_constructor_negative_nans_from_string(self):
self.assertEqual(copysign(1., complex("-nan").real), -1.)
self.assertEqual(copysign(1., complex("-nanj").imag), -1.)
self.assertEqual(copysign(1., complex("-nan-nanj").real), -1.)
self.assertEqual(copysign(1., complex("-nan-nanj").imag), -1.)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_underscores(self):
@@ -553,6 +600,8 @@ class ComplexTest(unittest.TestCase):
x /= 3.0 # now check against floating point
self.assertEqual(hash(x), hash(complex(x, 0.)))
self.assertNotEqual(hash(2000005 - 1j), -1)
def test_abs(self):
nums = [complex(x/3., y/7.) for x in range(-9,9) for y in range(-9,9)]
for num in nums:
@@ -575,6 +624,7 @@ class ComplexTest(unittest.TestCase):
test(complex(NAN, 1), "(nan+1j)")
test(complex(1, NAN), "(1+nanj)")
test(complex(NAN, NAN), "(nan+nanj)")
test(complex(-NAN, -NAN), "(nan+nanj)")
test(complex(0, INF), "infj")
test(complex(0, -INF), "-infj")
@@ -601,6 +651,14 @@ class ComplexTest(unittest.TestCase):
test(complex(-0., 0.), "(-0+0j)")
test(complex(-0., -0.), "(-0-0j)")
def test_pos(self):
class ComplexSubclass(complex):
pass
self.assertEqual(+(1+6j), 1+6j)
self.assertEqual(+ComplexSubclass(1, 6), 1+6j)
self.assertIs(type(+ComplexSubclass(1, 6)), complex)
def test_neg(self):
self.assertEqual(-(1+6j), -1-6j)
+2
View File
@@ -6,6 +6,7 @@ import random
import time
import unittest
import weakref
from test import support
from test.support import threading_helper
try:
@@ -608,6 +609,7 @@ class HamtTest(unittest.TestCase):
self.assertEqual({k.name for k in h.keys()}, {'C', 'D', 'E'})
@support.requires_resource('cpu')
def test_hamt_stress(self):
COLLECTION_SIZE = 7000
TEST_ITERS_EVERY = 647
-1
View File
@@ -1,4 +1,3 @@
from test import support
import unittest
from types import MethodType
-2
View File
@@ -1,9 +1,7 @@
"""Unit tests for collections.defaultdict."""
import os
import copy
import pickle
import tempfile
import unittest
from collections import defaultdict
+47 -15
View File
@@ -21,6 +21,11 @@ try:
except ImportError:
_testcapi = None
try:
import xxsubtype
except ImportError:
xxsubtype = None
class OperatorsTest(unittest.TestCase):
@@ -299,6 +304,7 @@ class OperatorsTest(unittest.TestCase):
self.assertEqual(float.__rsub__(3.0, 1), -2.0)
@support.impl_detail("the module 'xxsubtype' is internal")
@unittest.skipIf(xxsubtype is None, "requires xxsubtype module")
def test_spam_lists(self):
# Testing spamlist operations...
import copy, xxsubtype as spam
@@ -343,6 +349,7 @@ class OperatorsTest(unittest.TestCase):
self.assertEqual(a.getstate(), 42)
@support.impl_detail("the module 'xxsubtype' is internal")
@unittest.skipIf(xxsubtype is None, "requires xxsubtype module")
def test_spam_dicts(self):
# Testing spamdict operations...
import copy, xxsubtype as spam
@@ -426,7 +433,7 @@ class ClassPropertiesAndMethods(unittest.TestCase):
def __getitem__(self, key):
return self.get(key, 0)
def __setitem__(self_local, key, value):
self.assertIsInstance(key, type(0))
self.assertIsInstance(key, int)
dict.__setitem__(self_local, key, value)
def setstate(self, state):
self.state = state
@@ -842,7 +849,7 @@ class ClassPropertiesAndMethods(unittest.TestCase):
("getattr", "foo"),
("delattr", "foo")])
# http://python.org/sf/1174712
# https://bugs.python.org/issue1174712
try:
class Module(types.ModuleType, str):
pass
@@ -875,7 +882,7 @@ class ClassPropertiesAndMethods(unittest.TestCase):
self.assertEqual(a.getstate(), 10)
class D(dict, C):
def __init__(self):
type({}).__init__(self)
dict.__init__(self)
C.__init__(self)
d = D()
self.assertEqual(list(d.keys()), [])
@@ -1627,6 +1634,7 @@ order (MRO) for bases """
self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10)
@support.impl_detail("the module 'xxsubtype' is internal")
@unittest.skipIf(xxsubtype is None, "requires xxsubtype module")
def test_classmethods_in_c(self):
# Testing C-based class methods...
import xxsubtype as spam
@@ -1712,6 +1720,7 @@ order (MRO) for bases """
self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10)
@support.impl_detail("the module 'xxsubtype' is internal")
@unittest.skipIf(xxsubtype is None, "requires xxsubtype module")
def test_staticmethods_in_c(self):
# Testing C-based static methods...
import xxsubtype as spam
@@ -1848,9 +1857,8 @@ order (MRO) for bases """
object.__init__(A(3))
self.assertRaises(TypeError, object.__init__, A(3), 5)
# TODO: RUSTPYTHON, CPython 3.5 and above expect this test case to fail, but in RustPython this currently passes.
# See https://github.com/python/cpython/issues/49572 for more details.
# @unittest.expectedFailure
@unittest.expectedFailure
@unittest.skip("TODO: RUSTPYTHON")
def test_restored_object_new(self):
class A(object):
def __new__(cls, *args, **kwargs):
@@ -2006,7 +2014,7 @@ order (MRO) for bases """
ns = {}
exec(code, ns)
number_attrs = ns["number_attrs"]
# Warm up the the function for quickening (PEP 659)
# Warm up the function for quickening (PEP 659)
for _ in range(30):
self.assertEqual(number_attrs(Numbers()), list(range(280)))
@@ -3298,12 +3306,8 @@ order (MRO) for bases """
if otype:
otype = otype.__name__
return 'object=%s; type=%s' % (object, otype)
class OldClass:
class NewClass:
__doc__ = DocDescr()
class NewClass(object):
__doc__ = DocDescr()
self.assertEqual(OldClass.__doc__, 'object=None; type=OldClass')
self.assertEqual(OldClass().__doc__, 'object=OldClass instance; type=OldClass')
self.assertEqual(NewClass.__doc__, 'object=None; type=NewClass')
self.assertEqual(NewClass().__doc__, 'object=NewClass instance; type=NewClass')
@@ -3345,7 +3349,7 @@ order (MRO) for bases """
cant(True, int)
cant(2, bool)
o = object()
cant(o, type(1))
cant(o, int)
cant(o, type(None))
del o
class G(object):
@@ -3622,7 +3626,6 @@ order (MRO) for bases """
def test_str_of_str_subclass(self):
# Testing __str__ defined in subclass of str ...
import binascii
import io
class octetstring(str):
def __str__(self):
@@ -4527,8 +4530,9 @@ order (MRO) for bases """
o = Oops()
o.whatever = Provoker(o)
del o
@unittest.skip("TODO: RUSTPYTHON, rustpython segmentation fault")
@support.requires_resource('cpu')
def test_wrapper_segfault(self):
# SF 927248: deeply nested wrappers could cause stack overflow
f = lambda:None
@@ -5095,6 +5099,34 @@ order (MRO) for bases """
gc.collect()
self.assertEqual(Parent.__subclasses__(), [])
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_attr_raise_through_property(self):
# test case for gh-103272
class A:
def __getattr__(self, name):
raise ValueError("FOO")
@property
def foo(self):
return self.__getattr__("asdf")
with self.assertRaisesRegex(ValueError, "FOO"):
A().foo
# test case for gh-103551
class B:
@property
def __getattr__(self, name):
raise ValueError("FOO")
@property
def foo(self):
raise NotImplementedError("BAR")
with self.assertRaisesRegex(NotImplementedError, "BAR"):
B().foo
class DictProxyTests(unittest.TestCase):
def setUp(self):
+484
View File
@@ -0,0 +1,484 @@
# This contains most of the executable examples from Guido's descr
# tutorial, once at
#
# https://www.python.org/download/releases/2.2.3/descrintro/
#
# A few examples left implicit in the writeup were fleshed out, a few were
# skipped due to lack of interest (e.g., faking super() by hand isn't
# of much interest anymore), and a few were fiddled to make the output
# deterministic.
from test.support import sortdict
import doctest
import unittest
class defaultdict(dict):
def __init__(self, default=None):
dict.__init__(self)
self.default = default
def __getitem__(self, key):
try:
return dict.__getitem__(self, key)
except KeyError:
return self.default
def get(self, key, *args):
if not args:
args = (self.default,)
return dict.get(self, key, *args)
def merge(self, other):
for key in other:
if key not in self:
self[key] = other[key]
test_1 = """
Here's the new type at work:
>>> print(defaultdict) # show our type
<class 'test.test_descrtut.defaultdict'>
>>> print(type(defaultdict)) # its metatype
<class 'type'>
>>> a = defaultdict(default=0.0) # create an instance
>>> print(a) # show the instance
{}
>>> print(type(a)) # show its type
<class 'test.test_descrtut.defaultdict'>
>>> print(a.__class__) # show its class
<class 'test.test_descrtut.defaultdict'>
>>> print(type(a) is a.__class__) # its type is its class
True
>>> a[1] = 3.25 # modify the instance
>>> print(a) # show the new value
{1: 3.25}
>>> print(a[1]) # show the new item
3.25
>>> print(a[0]) # a non-existent item
0.0
>>> a.merge({1:100, 2:200}) # use a dict method
>>> print(sortdict(a)) # show the result
{1: 3.25, 2: 200}
>>>
We can also use the new type in contexts where classic only allows "real"
dictionaries, such as the locals/globals dictionaries for the exec
statement or the built-in function eval():
>>> print(sorted(a.keys()))
[1, 2]
>>> a['print'] = print # need the print function here
>>> exec("x = 3; print(x)", a)
3
>>> print(sorted(a.keys(), key=lambda x: (str(type(x)), x)))
[1, 2, '__builtins__', 'print', 'x']
>>> print(a['x'])
3
>>>
Now I'll show that defaultdict instances have dynamic instance variables,
just like classic classes:
>>> a.default = -1
>>> print(a["noway"])
-1
>>> a.default = -1000
>>> print(a["noway"])
-1000
>>> 'default' in dir(a)
True
>>> a.x1 = 100
>>> a.x2 = 200
>>> print(a.x1)
100
>>> d = dir(a)
>>> 'default' in d and 'x1' in d and 'x2' in d
True
>>> print(sortdict(a.__dict__))
{'default': -1000, 'x1': 100, 'x2': 200}
>>>
"""
class defaultdict2(dict):
__slots__ = ['default']
def __init__(self, default=None):
dict.__init__(self)
self.default = default
def __getitem__(self, key):
try:
return dict.__getitem__(self, key)
except KeyError:
return self.default
def get(self, key, *args):
if not args:
args = (self.default,)
return dict.get(self, key, *args)
def merge(self, other):
for key in other:
if key not in self:
self[key] = other[key]
test_2 = """
The __slots__ declaration takes a list of instance variables, and reserves
space for exactly these in the instance. When __slots__ is used, other
instance variables cannot be assigned to:
>>> a = defaultdict2(default=0.0)
>>> a[1]
0.0
>>> a.default = -1
>>> a[1]
-1
>>> a.x1 = 1
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'defaultdict2' object has no attribute 'x1'
>>>
"""
test_3 = """
Introspecting instances of built-in types
For instance of built-in types, x.__class__ is now the same as type(x):
>>> type([])
<class 'list'>
>>> [].__class__
<class 'list'>
>>> list
<class 'list'>
>>> isinstance([], list)
True
>>> isinstance([], dict)
False
>>> isinstance([], object)
True
>>>
You can get the information from the list type:
>>> import pprint
>>> pprint.pprint(dir(list)) # like list.__dict__.keys(), but sorted
['__add__',
'__class__',
'__class_getitem__',
'__contains__',
'__delattr__',
'__delitem__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__getstate__',
'__gt__',
'__hash__',
'__iadd__',
'__imul__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__mul__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__reversed__',
'__rmul__',
'__setattr__',
'__setitem__',
'__sizeof__',
'__str__',
'__subclasshook__',
'append',
'clear',
'copy',
'count',
'extend',
'index',
'insert',
'pop',
'remove',
'reverse',
'sort']
The new introspection API gives more information than the old one: in
addition to the regular methods, it also shows the methods that are
normally invoked through special notations, e.g. __iadd__ (+=), __len__
(len), __ne__ (!=). You can invoke any method from this list directly:
>>> a = ['tic', 'tac']
>>> list.__len__(a) # same as len(a)
2
>>> a.__len__() # ditto
2
>>> list.append(a, 'toe') # same as a.append('toe')
>>> a
['tic', 'tac', 'toe']
>>>
This is just like it is for user-defined classes.
"""
test_4 = """
Static methods and class methods
The new introspection API makes it possible to add static methods and class
methods. Static methods are easy to describe: they behave pretty much like
static methods in C++ or Java. Here's an example:
>>> class C:
...
... @staticmethod
... def foo(x, y):
... print("staticmethod", x, y)
>>> C.foo(1, 2)
staticmethod 1 2
>>> c = C()
>>> c.foo(1, 2)
staticmethod 1 2
Class methods use a similar pattern to declare methods that receive an
implicit first argument that is the *class* for which they are invoked.
>>> class C:
... @classmethod
... def foo(cls, y):
... print("classmethod", cls, y)
>>> C.foo(1)
classmethod <class 'test.test_descrtut.C'> 1
>>> c = C()
>>> c.foo(1)
classmethod <class 'test.test_descrtut.C'> 1
>>> class D(C):
... pass
>>> D.foo(1)
classmethod <class 'test.test_descrtut.D'> 1
>>> d = D()
>>> d.foo(1)
classmethod <class 'test.test_descrtut.D'> 1
This prints "classmethod __main__.D 1" both times; in other words, the
class passed as the first argument of foo() is the class involved in the
call, not the class involved in the definition of foo().
But notice this:
>>> class E(C):
... @classmethod
... def foo(cls, y): # override C.foo
... print("E.foo() called")
... C.foo(y)
>>> E.foo(1)
E.foo() called
classmethod <class 'test.test_descrtut.C'> 1
>>> e = E()
>>> e.foo(1)
E.foo() called
classmethod <class 'test.test_descrtut.C'> 1
In this example, the call to C.foo() from E.foo() will see class C as its
first argument, not class E. This is to be expected, since the call
specifies the class C. But it stresses the difference between these class
methods and methods defined in metaclasses (where an upcall to a metamethod
would pass the target class as an explicit first argument).
"""
test_5 = """
Attributes defined by get/set methods
>>> class property(object):
...
... def __init__(self, get, set=None):
... self.__get = get
... self.__set = set
...
... def __get__(self, inst, type=None):
... return self.__get(inst)
...
... def __set__(self, inst, value):
... if self.__set is None:
... raise AttributeError("this attribute is read-only")
... return self.__set(inst, value)
Now let's define a class with an attribute x defined by a pair of methods,
getx() and setx():
>>> class C(object):
...
... def __init__(self):
... self.__x = 0
...
... def getx(self):
... return self.__x
...
... def setx(self, x):
... if x < 0: x = 0
... self.__x = x
...
... x = property(getx, setx)
Here's a small demonstration:
>>> a = C()
>>> a.x = 10
>>> print(a.x)
10
>>> a.x = -10
>>> print(a.x)
0
>>>
Hmm -- property is builtin now, so let's try it that way too.
>>> del property # unmask the builtin
>>> property
<class 'property'>
>>> class C(object):
... def __init__(self):
... self.__x = 0
... def getx(self):
... return self.__x
... def setx(self, x):
... if x < 0: x = 0
... self.__x = x
... x = property(getx, setx)
>>> a = C()
>>> a.x = 10
>>> print(a.x)
10
>>> a.x = -10
>>> print(a.x)
0
>>>
"""
test_6 = """
Method resolution order
This example is implicit in the writeup.
>>> class A: # implicit new-style class
... def save(self):
... print("called A.save()")
>>> class B(A):
... pass
>>> class C(A):
... def save(self):
... print("called C.save()")
>>> class D(B, C):
... pass
>>> D().save()
called C.save()
>>> class A(object): # explicit new-style class
... def save(self):
... print("called A.save()")
>>> class B(A):
... pass
>>> class C(A):
... def save(self):
... print("called C.save()")
>>> class D(B, C):
... pass
>>> D().save()
called C.save()
"""
class A(object):
def m(self):
return "A"
class B(A):
def m(self):
return "B" + super(B, self).m()
class C(A):
def m(self):
return "C" + super(C, self).m()
class D(C, B):
def m(self):
return "D" + super(D, self).m()
test_7 = """
Cooperative methods and "super"
>>> print(D().m()) # "DCBA"
DCBA
"""
test_8 = """
Backwards incompatibilities
>>> class A:
... def foo(self):
... print("called A.foo()")
>>> class B(A):
... pass
>>> class C(A):
... def foo(self):
... B.foo(self)
>>> C().foo()
called A.foo()
>>> class C(A):
... def foo(self):
... A.foo(self)
>>> C().foo()
called A.foo()
"""
# TODO: RUSTPYTHON
__test__ = {# "tut1": test_1,
# "tut2": test_2,
# "tut3": test_3,
# "tut4": test_4,
"tut5": test_5,
"tut6": test_6,
"tut7": test_7,
"tut8": test_8}
def load_tests(loader, tests, pattern):
tests.addTest(doctest.DocTestSuite())
return tests
if __name__ == "__main__":
unittest.main()
+17 -2
View File
@@ -8,7 +8,7 @@ import sys
import unittest
import weakref
from test import support
from test.support import import_helper
from test.support import import_helper, C_RECURSION_LIMIT
class DictTest(unittest.TestCase):
@@ -599,7 +599,7 @@ class DictTest(unittest.TestCase):
@unittest.skipIf(sys.platform == 'win32', 'TODO: RUSTPYTHON Windows')
def test_repr_deep(self):
d = {}
for i in range(sys.getrecursionlimit() + 100):
for i in range(C_RECURSION_LIMIT + 1):
d = {1: d}
self.assertRaises(RecursionError, repr, d)
@@ -1099,6 +1099,21 @@ class DictTest(unittest.TestCase):
d.update(o.__dict__)
self.assertEqual(list(d), ["c", "b", "a"])
@support.cpython_only
def test_splittable_to_generic_combinedtable(self):
"""split table must be correctly resized and converted to generic combined table"""
class C:
pass
a = C()
a.x = 1
d = a.__dict__
before_resize = sys.getsizeof(d)
d[2] = 2 # split table is resized to a generic combined table
self.assertGreater(sys.getsizeof(d), before_resize)
self.assertEqual(list(d), ['x', 2])
def test_iterator_pickling(self):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
data = {1:"a", 2:"b", 3:"c"}
+22 -1
View File
@@ -3,6 +3,7 @@ import copy
import pickle
import sys
import unittest
from test.support import C_RECURSION_LIMIT
class DictSetTest(unittest.TestCase):
@@ -170,6 +171,10 @@ class DictSetTest(unittest.TestCase):
{('a', 1), ('b', 2)})
self.assertEqual(d1.items() & set(d2.items()), {('b', 2)})
self.assertEqual(d1.items() & set(d3.items()), set())
self.assertEqual(d1.items() & (("a", 1), ("b", 2)),
{('a', 1), ('b', 2)})
self.assertEqual(d1.items() & (("a", 2), ("b", 2)), {('b', 2)})
self.assertEqual(d1.items() & (("d", 4), ("e", 5)), set())
self.assertEqual(d1.items() | d1.items(),
{('a', 1), ('b', 2)})
@@ -183,12 +188,23 @@ class DictSetTest(unittest.TestCase):
{('a', 1), ('a', 2), ('b', 2)})
self.assertEqual(d1.items() | set(d3.items()),
{('a', 1), ('b', 2), ('d', 4), ('e', 5)})
self.assertEqual(d1.items() | (('a', 1), ('b', 2)),
{('a', 1), ('b', 2)})
self.assertEqual(d1.items() | (('a', 2), ('b', 2)),
{('a', 1), ('a', 2), ('b', 2)})
self.assertEqual(d1.items() | (('d', 4), ('e', 5)),
{('a', 1), ('b', 2), ('d', 4), ('e', 5)})
self.assertEqual(d1.items() ^ d1.items(), set())
self.assertEqual(d1.items() ^ d2.items(),
{('a', 1), ('a', 2)})
self.assertEqual(d1.items() ^ d3.items(),
{('a', 1), ('b', 2), ('d', 4), ('e', 5)})
self.assertEqual(d1.items() ^ (('a', 1), ('b', 2)), set())
self.assertEqual(d1.items() ^ (("a", 2), ("b", 2)),
{('a', 1), ('a', 2)})
self.assertEqual(d1.items() ^ (("d", 4), ("e", 5)),
{('a', 1), ('b', 2), ('d', 4), ('e', 5)})
self.assertEqual(d1.items() - d1.items(), set())
self.assertEqual(d1.items() - d2.items(), {('a', 1)})
@@ -196,6 +212,9 @@ class DictSetTest(unittest.TestCase):
self.assertEqual(d1.items() - set(d1.items()), set())
self.assertEqual(d1.items() - set(d2.items()), {('a', 1)})
self.assertEqual(d1.items() - set(d3.items()), {('a', 1), ('b', 2)})
self.assertEqual(d1.items() - (('a', 1), ('b', 2)), set())
self.assertEqual(d1.items() - (("a", 2), ("b", 2)), {('a', 1)})
self.assertEqual(d1.items() - (("d", 4), ("e", 5)), {('a', 1), ('b', 2)})
self.assertFalse(d1.items().isdisjoint(d1.items()))
self.assertFalse(d1.items().isdisjoint(d2.items()))
@@ -259,9 +278,11 @@ class DictSetTest(unittest.TestCase):
# Again.
self.assertIsInstance(r, str)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_deeply_nested_repr(self):
d = {}
for i in range(sys.getrecursionlimit() + 100):
for i in range(C_RECURSION_LIMIT//2 + 100):
d = {42: d.values()}
self.assertRaises(RecursionError, repr, d)
+82
View File
@@ -3,6 +3,7 @@ import os.path
import re
import subprocess
import sys
import sysconfig
import types
import unittest
@@ -173,6 +174,87 @@ class SystemTapOptimizedTests(TraceTests, unittest.TestCase):
backend = SystemTapBackend()
optimize_python = 2
class CheckDtraceProbes(unittest.TestCase):
@classmethod
def setUpClass(cls):
if sysconfig.get_config_var('WITH_DTRACE'):
readelf_major_version, readelf_minor_version = cls.get_readelf_version()
if support.verbose:
print(f"readelf version: {readelf_major_version}.{readelf_minor_version}")
else:
raise unittest.SkipTest("CPython must be configured with the --with-dtrace option.")
@staticmethod
def get_readelf_version():
try:
cmd = ["readelf", "--version"]
proc = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
with proc:
version, stderr = proc.communicate()
if proc.returncode:
raise Exception(
f"Command {' '.join(cmd)!r} failed "
f"with exit code {proc.returncode}: "
f"stdout={version!r} stderr={stderr!r}"
)
except OSError:
raise unittest.SkipTest("Couldn't find readelf on the path")
# Regex to parse:
# 'GNU readelf (GNU Binutils) 2.40.0\n' -> 2.40
match = re.search(r"^(?:GNU) readelf.*?\b(\d+)\.(\d+)", version)
if match is None:
raise unittest.SkipTest(f"Unable to parse readelf version: {version}")
return int(match.group(1)), int(match.group(2))
def get_readelf_output(self):
command = ["readelf", "-n", sys.executable]
stdout, _ = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
).communicate()
return stdout
def test_check_probes(self):
readelf_output = self.get_readelf_output()
available_probe_names = [
"Name: import__find__load__done",
"Name: import__find__load__start",
"Name: audit",
"Name: gc__start",
"Name: gc__done",
]
for probe_name in available_probe_names:
with self.subTest(probe_name=probe_name):
self.assertIn(probe_name, readelf_output)
@unittest.expectedFailure
def test_missing_probes(self):
readelf_output = self.get_readelf_output()
# Missing probes will be added in the future.
missing_probe_names = [
"Name: function__entry",
"Name: function__return",
"Name: line",
]
for probe_name in missing_probe_names:
with self.subTest(probe_name=probe_name):
self.assertIn(probe_name, readelf_output)
if __name__ == '__main__':
unittest.main()
+7 -5
View File
@@ -142,12 +142,14 @@ class RebindBuiltinsTests(unittest.TestCase):
def __missing__(self, key):
return int(key.removeprefix("_number_"))
code = "lambda: " + "+".join(f"_number_{i}" for i in range(1000))
sum_1000 = eval(code, MyGlobals())
expected = sum(range(1000))
# Warm up the the function for quickening (PEP 659)
# Need more than 256 variables to use EXTENDED_ARGS
variables = 400
code = "lambda: " + "+".join(f"_number_{i}" for i in range(variables))
sum_func = eval(code, MyGlobals())
expected = sum(range(variables))
# Warm up the function for quickening (PEP 659)
for _ in range(30):
self.assertEqual(sum_1000(), expected)
self.assertEqual(sum_func(), expected)
class TestTracing(unittest.TestCase):
+1
View File
@@ -9,6 +9,7 @@ from test.support import script_helper
class EINTRTests(unittest.TestCase):
@unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()")
@support.requires_resource('walltime')
def test_all(self):
# Run the tester in a sub-process, to make sure there is only one
# thread (for reliable signal delivery).
+3 -1
View File
@@ -4,6 +4,7 @@ import sys
from test import support
from test.support import os_helper
from test.support import script_helper
from test.support import warnings_helper
import unittest
# TODO: RUSTPYTHON
@@ -38,10 +39,11 @@ class EOFTestCase(unittest.TestCase):
rc, out, err = script_helper.assert_python_failure(file_name)
self.assertIn(b'unterminated triple-quoted string literal (detected at line 3)', err)
@warnings_helper.ignore_warnings(category=SyntaxWarning)
def test_eof_with_line_continuation(self):
expect = "unexpected EOF while parsing (<string>, line 1)"
try:
compile('"\\xhh" \\', '<string>', 'exec', dont_inherit=True)
compile('"\\Xhh" \\', '<string>', 'exec')
except SyntaxError as msg:
self.assertEqual(str(msg), expect)
else:
+11 -4
View File
@@ -27,6 +27,7 @@ import select
import socket
import time
import unittest
from test import support
if not hasattr(select, "epoll"):
raise unittest.SkipTest("test works only on Linux 2.6")
@@ -186,10 +187,16 @@ class TestEPoll(unittest.TestCase):
client.sendall(b"Hello!")
server.sendall(b"world!!!")
now = time.monotonic()
events = ep.poll(1.0, 4)
then = time.monotonic()
self.assertFalse(then - now > 0.01)
# we might receive events one at a time, necessitating multiple calls to
# poll
events = []
for _ in support.busy_retry(support.SHORT_TIMEOUT):
now = time.monotonic()
events += ep.poll(1.0, 4)
then = time.monotonic()
self.assertFalse(then - now > 0.01)
if len(events) >= 2:
break
expected = [(client.fileno(), select.EPOLLIN | select.EPOLLOUT),
(server.fileno(), select.EPOLLIN | select.EPOLLOUT)]