diff options
Diffstat (limited to 'Lib/test/test_float.py')
| -rw-r--r-- | Lib/test/test_float.py | 76 |
1 files changed, 65 insertions, 11 deletions
diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index 96d907a..24fe128 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -1,12 +1,16 @@ -import unittest, struct +import fractions +import math +import operator import os +import random import sys +import struct +import time +import unittest + from test import support -import math from math import isinf, isnan, copysign, ldexp -import operator -import random, fractions INF = float("inf") NAN = float("nan") @@ -21,13 +25,18 @@ requires_setformat = unittest.skipUnless(hasattr(float, "__setformat__"), test_dir = os.path.dirname(__file__) or os.curdir format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt') +class FloatSubclass(float): + pass + +class OtherFloatSubclass(float): + pass + class GeneralFloatCases(unittest.TestCase): def test_float(self): self.assertEqual(float(3.14), 3.14) self.assertEqual(float(314), 314.0) self.assertEqual(float(" 3.14 "), 3.14) - self.assertEqual(float(b" 3.14 "), 3.14) self.assertRaises(ValueError, float, " 0x3.1 ") self.assertRaises(ValueError, float, " -0x3.p-1 ") self.assertRaises(ValueError, float, " +0x3.p-1 ") @@ -39,8 +48,8 @@ class GeneralFloatCases(unittest.TestCase): self.assertRaises(ValueError, float, "+.inf") self.assertRaises(ValueError, float, ".") self.assertRaises(ValueError, float, "-.") - self.assertRaises(ValueError, float, b"-") self.assertRaises(TypeError, float, {}) + self.assertRaisesRegex(TypeError, "not 'dict'", float, {}) # Lone surrogate self.assertRaises(UnicodeEncodeError, float, '\uD8F0') # check that we don't accept alternate exponent markers @@ -52,6 +61,42 @@ class GeneralFloatCases(unittest.TestCase): float(b'.' + b'1'*1000) float('.' + '1'*1000) + def test_non_numeric_input_types(self): + # Test possible non-numeric types for the argument x, including + # subclasses of the explicitly documented accepted types. + class CustomStr(str): pass + class CustomBytes(bytes): pass + class CustomByteArray(bytearray): pass + + factories = [ + bytes, + bytearray, + lambda b: CustomStr(b.decode()), + CustomBytes, + CustomByteArray, + memoryview, + ] + try: + from array import array + except ImportError: + pass + else: + factories.append(lambda b: array('B', b)) + + for f in factories: + x = f(b" 3.14 ") + with self.subTest(type(x)): + self.assertEqual(float(x), 3.14) + with self.assertRaisesRegex(ValueError, "could not convert"): + float(f(b'A' * 0x10)) + + def test_float_memoryview(self): + self.assertEqual(float(memoryview(b'12.3')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.3\x00')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.3 ')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.3A')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.34')[1:4]), 2.3) + def test_error_message(self): testlist = ('\xbd', '123\xbd', ' 123 456 ') for s in testlist: @@ -92,10 +137,6 @@ class GeneralFloatCases(unittest.TestCase): def test_floatconversion(self): # Make sure that calls to __float__() work properly - class Foo0: - def __float__(self): - return 42. - class Foo1(object): def __float__(self): return 42. @@ -121,13 +162,26 @@ class GeneralFloatCases(unittest.TestCase): def __float__(self): return float(str(self)) + 1 - self.assertAlmostEqual(float(Foo0()), 42.) self.assertAlmostEqual(float(Foo1()), 42.) self.assertAlmostEqual(float(Foo2()), 42.) self.assertAlmostEqual(float(Foo3(21)), 42.) self.assertRaises(TypeError, float, Foo4(42)) self.assertAlmostEqual(float(FooStr('8')), 9.) + class Foo5: + def __float__(self): + return "" + self.assertRaises(TypeError, time.sleep, Foo5()) + + # Issue #24731 + class F: + def __float__(self): + return OtherFloatSubclass(42.) + self.assertAlmostEqual(float(F()), 42.) + self.assertIs(type(float(F())), OtherFloatSubclass) + self.assertAlmostEqual(FloatSubclass(F()), 42.) + self.assertIs(type(FloatSubclass(F())), FloatSubclass) + def test_is_integer(self): self.assertFalse((1.1).is_integer()) self.assertTrue((1.).is_integer()) |
