Merge pull request #7106 from moreal/test_float

Update test_float from v3.14.3
This commit is contained in:
Jeong, YunWon
2026-02-13 19:35:28 +09:00
committed by GitHub

170
Lib/test/test_float.py vendored
View File

@@ -35,6 +35,28 @@ class FloatSubclass(float):
class OtherFloatSubclass(float):
pass
class MyIndex:
def __init__(self, value):
self.value = value
def __index__(self):
return self.value
class MyInt:
def __init__(self, value):
self.value = value
def __int__(self):
return self.value
class FloatLike:
def __init__(self, value):
self.value = value
def __float__(self):
return self.value
class GeneralFloatCases(unittest.TestCase):
def test_float(self):
@@ -184,10 +206,6 @@ class GeneralFloatCases(unittest.TestCase):
def test_floatconversion(self):
# Make sure that calls to __float__() work properly
class Foo1(object):
def __float__(self):
return 42.
class Foo2(float):
def __float__(self):
return 42.
@@ -209,52 +227,35 @@ class GeneralFloatCases(unittest.TestCase):
def __float__(self):
return float(str(self)) + 1
self.assertEqual(float(Foo1()), 42.)
self.assertEqual(float(FloatLike(42.)), 42.)
self.assertEqual(float(Foo2()), 42.)
with self.assertWarns(DeprecationWarning):
self.assertEqual(float(Foo3(21)), 42.)
self.assertRaises(TypeError, float, Foo4(42))
self.assertEqual(float(FooStr('8')), 9.)
class Foo5:
def __float__(self):
return ""
self.assertRaises(TypeError, time.sleep, Foo5())
self.assertRaises(TypeError, time.sleep, FloatLike(""))
# Issue #24731
class F:
def __float__(self):
return OtherFloatSubclass(42.)
f = FloatLike(OtherFloatSubclass(42.))
with self.assertWarns(DeprecationWarning):
self.assertEqual(float(F()), 42.)
self.assertEqual(float(f), 42.)
with self.assertWarns(DeprecationWarning):
self.assertIs(type(float(F())), float)
self.assertIs(type(float(f)), float)
with self.assertWarns(DeprecationWarning):
self.assertEqual(FloatSubclass(F()), 42.)
self.assertEqual(FloatSubclass(f), 42.)
with self.assertWarns(DeprecationWarning):
self.assertIs(type(FloatSubclass(F())), FloatSubclass)
class MyIndex:
def __init__(self, value):
self.value = value
def __index__(self):
return self.value
self.assertIs(type(FloatSubclass(f)), FloatSubclass)
self.assertEqual(float(MyIndex(42)), 42.0)
self.assertRaises(OverflowError, float, MyIndex(2**2000))
class MyInt:
def __int__(self):
return 42
self.assertRaises(TypeError, float, MyInt())
self.assertRaises(TypeError, float, MyInt(42))
def test_keyword_args(self):
with self.assertRaisesRegex(TypeError, 'keyword argument'):
float(x='3.14')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: Unexpected keyword argument newarg
def test_keywords_in_subclass(self):
class subclass(float):
pass
@@ -282,6 +283,39 @@ class GeneralFloatCases(unittest.TestCase):
self.assertEqual(float(u), 2.5)
self.assertEqual(u.newarg, 3)
def assertEqualAndType(self, actual, expected_value, expected_type):
self.assertEqual(actual, expected_value)
self.assertIs(type(actual), expected_type)
@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: type object 'float' has no attribute 'from_number'
def test_from_number(self, cls=float):
def eq(actual, expected):
self.assertEqual(actual, expected)
self.assertIs(type(actual), cls)
eq(cls.from_number(3.14), 3.14)
eq(cls.from_number(314), 314.0)
eq(cls.from_number(OtherFloatSubclass(3.14)), 3.14)
eq(cls.from_number(FloatLike(3.14)), 3.14)
eq(cls.from_number(MyIndex(314)), 314.0)
x = cls.from_number(NAN)
self.assertTrue(x != x)
self.assertIs(type(x), cls)
if cls is float:
self.assertIs(cls.from_number(NAN), NAN)
self.assertRaises(TypeError, cls.from_number, '3.14')
self.assertRaises(TypeError, cls.from_number, b'3.14')
self.assertRaises(TypeError, cls.from_number, 3.14j)
self.assertRaises(TypeError, cls.from_number, MyInt(314))
self.assertRaises(TypeError, cls.from_number, {})
self.assertRaises(TypeError, cls.from_number)
@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: type object 'FloatSubclass' has no attribute 'from_number'
def test_from_number_subclass(self):
self.test_from_number(FloatSubclass)
def test_is_integer(self):
self.assertFalse((1.1).is_integer())
self.assertTrue((1.).is_integer())
@@ -400,9 +434,8 @@ class GeneralFloatCases(unittest.TestCase):
self.assertEqualAndEqualSign(mod(1e-100, -1.0), -1.0)
self.assertEqualAndEqualSign(mod(1.0, -1.0), -0.0)
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: must be real number, not complex
@support.requires_IEEE_754
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_float_pow(self):
# test builtin pow and ** operator for IEEE 754 special cases.
# Special cases taken from section F.9.4.4 of the C99 specification
@@ -622,6 +655,24 @@ class GeneralFloatCases(unittest.TestCase):
value = F('nan')
self.assertEqual(hash(value), object.__hash__(value))
def test_issue_gh143006(self):
# When comparing negative non-integer float and int with the
# same number of bits in the integer part, __neg__() in the
# int subclass returning not an int caused an assertion error.
class EvilInt(int):
def __neg__(self):
return ""
i = -1 << 50
f = float(i) - 0.5
i = EvilInt(i)
self.assertFalse(f == i)
self.assertTrue(f != i)
self.assertTrue(f < i)
self.assertTrue(f <= i)
self.assertFalse(f > i)
self.assertFalse(f >= i)
@unittest.skipUnless(hasattr(float, "__getformat__"), "requires __getformat__")
class FormatFunctionsTestCase(unittest.TestCase):
@@ -676,6 +727,7 @@ class IEEEFormatTestCase(unittest.TestCase):
class FormatTestCase(unittest.TestCase):
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: Invalid format specifier
def test_format(self):
# these should be rewritten to use both format(x, spec) and
# x.__format__(spec)
@@ -727,6 +779,44 @@ class FormatTestCase(unittest.TestCase):
self.assertEqual(format(INF, 'f'), 'inf')
self.assertEqual(format(INF, 'F'), 'INF')
# thousands separators
x = 123_456.123_456
self.assertEqual(format(x, '_f'), '123_456.123456')
self.assertEqual(format(x, ',f'), '123,456.123456')
self.assertEqual(format(x, '._f'), '123456.123_456')
self.assertEqual(format(x, '.,f'), '123456.123,456')
self.assertEqual(format(x, '_._f'), '123_456.123_456')
self.assertEqual(format(x, ',.,f'), '123,456.123,456')
self.assertEqual(format(x, '.10_f'), '123456.123_456_000_0')
self.assertEqual(format(x, '.10,f'), '123456.123,456,000,0')
self.assertEqual(format(x, '>21._f'), ' 123456.123_456')
self.assertEqual(format(x, '<21._f'), '123456.123_456 ')
self.assertEqual(format(x, '+.11_e'), '+1.234_561_234_56e+05')
self.assertEqual(format(x, '+.11,e'), '+1.234,561,234,56e+05')
self.assertEqual(format(x, '021_._f'), '0_000_123_456.123_456')
self.assertEqual(format(x, '020_._f'), '0_000_123_456.123_456')
self.assertEqual(format(x, '+021_._f'), '+0_000_123_456.123_456')
self.assertEqual(format(x, '21_._f'), ' 123_456.123_456')
self.assertEqual(format(x, '>021_._f'), '000000123_456.123_456')
self.assertEqual(format(x, '<021_._f'), '123_456.123_456000000')
self.assertEqual(format(x, '023_.10_f'), '0_123_456.123_456_000_0')
self.assertEqual(format(x, '022_.10_f'), '0_123_456.123_456_000_0')
self.assertEqual(format(x, '+023_.10_f'), '+0_123_456.123_456_000_0')
self.assertEqual(format(x, '023_.9_f'), '000_123_456.123_456_000')
self.assertEqual(format(x, '021_._e'), '0_000_001.234_561e+05')
self.assertEqual(format(x, '020_._e'), '0_000_001.234_561e+05')
self.assertEqual(format(x, '+021_._e'), '+0_000_001.234_561e+05')
self.assertEqual(format(x, '023_.10_e'), '0_001.234_561_234_6e+05')
self.assertEqual(format(x, '022_.10_e'), '0_001.234_561_234_6e+05')
self.assertEqual(format(x, '023_.9_e'), '000_001.234_561_235e+05')
self.assertRaises(ValueError, format, x, '._6f')
self.assertRaises(ValueError, format, x, '.,_f')
self.assertRaises(ValueError, format, x, '.6,_f')
self.assertRaises(ValueError, format, x, '.6_,f')
self.assertRaises(ValueError, format, x, '.6_n')
self.assertRaises(ValueError, format, x, '.6,n')
@support.requires_IEEE_754
@unittest.skipUnless(sys.float_repr_style == 'short',
"applies only when using short float repr style")
@@ -877,10 +967,9 @@ class RoundTestCase(unittest.TestCase, FloatsAreIdenticalMixin):
self.assertRaises(OverflowError, round, 1.6e308, -308)
self.assertRaises(OverflowError, round, -1.7e308, -308)
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: 56294995342131.51 != 56294995342131.5
@unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
"applies only when using short float repr style")
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_previous_round_bugs(self):
# particular cases that have occurred in bug reports
self.assertEqual(round(562949953421312.5, 1),
@@ -897,10 +986,9 @@ class RoundTestCase(unittest.TestCase, FloatsAreIdenticalMixin):
self.assertEqual(round(85.0, -1), 80.0)
self.assertEqual(round(95.0, -1), 100.0)
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: 0.01 != 0.0
@unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
"applies only when using short float repr style")
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_matches_float_format(self):
# round should give the same results as float formatting
for i in range(500):
@@ -962,6 +1050,13 @@ class RoundTestCase(unittest.TestCase, FloatsAreIdenticalMixin):
self.assertEqual(x, 2)
self.assertIsInstance(x, int)
@support.cpython_only
def test_round_with_none_arg_direct_call(self):
for val in [(1.0).__round__(None),
round(1.0),
round(1.0, None)]:
self.assertEqual(val, 1)
self.assertIs(type(val), int)
# Beginning with Python 2.6 float has cross platform compatible
# ways to create and represent inf and nan
@@ -1171,8 +1266,7 @@ class HexFloatTestCase(FloatsAreIdenticalMixin, unittest.TestCase):
self.identical(got, expected)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: invalid hexadecimal floating-point string
def test_from_hex(self):
MIN = self.MIN
MAX = self.MAX