mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Merge pull request #7106 from moreal/test_float
Update test_float from v3.14.3
This commit is contained in:
170
Lib/test/test_float.py
vendored
170
Lib/test/test_float.py
vendored
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user