summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_float.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_float.py')
-rw-r--r--Lib/test/test_float.py76
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())