summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_decimal.py60
-rw-r--r--Lib/test/test_float.py22
-rw-r--r--Lib/test/test_format.py74
-rw-r--r--Lib/test/test_types.py22
4 files changed, 154 insertions, 24 deletions
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py
index 0e7491e..5e77e3c 100644
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -1072,6 +1072,57 @@ class FormatTest(unittest.TestCase):
(',e', '123456', '1.23456e+5'),
(',E', '123456', '1.23456E+5'),
+ # negative zero: default behavior
+ ('.1f', '-0', '-0.0'),
+ ('.1f', '-.0', '-0.0'),
+ ('.1f', '-.01', '-0.0'),
+
+ # negative zero: z option
+ ('z.1f', '0.', '0.0'),
+ ('z6.1f', '0.', ' 0.0'),
+ ('z6.1f', '-1.', ' -1.0'),
+ ('z.1f', '-0.', '0.0'),
+ ('z.1f', '.01', '0.0'),
+ ('z.1f', '-.01', '0.0'),
+ ('z.2f', '0.', '0.00'),
+ ('z.2f', '-0.', '0.00'),
+ ('z.2f', '.001', '0.00'),
+ ('z.2f', '-.001', '0.00'),
+
+ ('z.1e', '0.', '0.0e+1'),
+ ('z.1e', '-0.', '0.0e+1'),
+ ('z.1E', '0.', '0.0E+1'),
+ ('z.1E', '-0.', '0.0E+1'),
+
+ ('z.2e', '-0.001', '-1.00e-3'), # tests for mishandled rounding
+ ('z.2g', '-0.001', '-0.001'),
+ ('z.2%', '-0.001', '-0.10%'),
+
+ ('zf', '-0.0000', '0.0000'), # non-normalized form is preserved
+
+ ('z.1f', '-00000.000001', '0.0'),
+ ('z.1f', '-00000.', '0.0'),
+ ('z.1f', '-.0000000000', '0.0'),
+
+ ('z.2f', '-00000.000001', '0.00'),
+ ('z.2f', '-00000.', '0.00'),
+ ('z.2f', '-.0000000000', '0.00'),
+
+ ('z.1f', '.09', '0.1'),
+ ('z.1f', '-.09', '-0.1'),
+
+ (' z.0f', '-0.', ' 0'),
+ ('+z.0f', '-0.', '+0'),
+ ('-z.0f', '-0.', '0'),
+ (' z.0f', '-1.', '-1'),
+ ('+z.0f', '-1.', '-1'),
+ ('-z.0f', '-1.', '-1'),
+
+ ('z>6.1f', '-0.', 'zz-0.0'),
+ ('z>z6.1f', '-0.', 'zzz0.0'),
+ ('x>z6.1f', '-0.', 'xxx0.0'),
+ ('πŸ–€>z6.1f', '-0.', 'πŸ–€πŸ–€πŸ–€0.0'), # multi-byte fill char
+
# issue 6850
('a=-7.0', '0.12345', 'aaaa0.1'),
@@ -1086,6 +1137,15 @@ class FormatTest(unittest.TestCase):
# bytes format argument
self.assertRaises(TypeError, Decimal(1).__format__, b'-020')
+ def test_negative_zero_format_directed_rounding(self):
+ with self.decimal.localcontext() as ctx:
+ ctx.rounding = ROUND_CEILING
+ self.assertEqual(format(self.decimal.Decimal('-0.001'), 'z.2f'),
+ '0.00')
+
+ def test_negative_zero_bad_format(self):
+ self.assertRaises(ValueError, format, self.decimal.Decimal('1.23'), 'fz')
+
def test_n_format(self):
Decimal = self.decimal.Decimal
diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py
index 9cf223f..d8c0fe18 100644
--- a/Lib/test/test_float.py
+++ b/Lib/test/test_float.py
@@ -701,18 +701,16 @@ class FormatTestCase(unittest.TestCase):
# conversion to string should fail
self.assertRaises(ValueError, format, 3.0, "s")
- # other format specifiers shouldn't work on floats,
- # in particular int specifiers
- for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
- [chr(x) for x in range(ord('A'), ord('Z')+1)]):
- if not format_spec in 'eEfFgGn%':
- self.assertRaises(ValueError, format, 0.0, format_spec)
- self.assertRaises(ValueError, format, 1.0, format_spec)
- self.assertRaises(ValueError, format, -1.0, format_spec)
- self.assertRaises(ValueError, format, 1e100, format_spec)
- self.assertRaises(ValueError, format, -1e100, format_spec)
- self.assertRaises(ValueError, format, 1e-100, format_spec)
- self.assertRaises(ValueError, format, -1e-100, format_spec)
+ # confirm format options expected to fail on floats, such as integer
+ # presentation types
+ for format_spec in 'sbcdoxX':
+ self.assertRaises(ValueError, format, 0.0, format_spec)
+ self.assertRaises(ValueError, format, 1.0, format_spec)
+ self.assertRaises(ValueError, format, -1.0, format_spec)
+ self.assertRaises(ValueError, format, 1e100, format_spec)
+ self.assertRaises(ValueError, format, -1e100, format_spec)
+ self.assertRaises(ValueError, format, 1e-100, format_spec)
+ self.assertRaises(ValueError, format, -1e-100, format_spec)
# issue 3382
self.assertEqual(format(NAN, 'f'), 'nan')
diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py
index 16d29d1..69b0d5f 100644
--- a/Lib/test/test_format.py
+++ b/Lib/test/test_format.py
@@ -546,6 +546,80 @@ class FormatTest(unittest.TestCase):
with self.assertRaisesRegex(ValueError, str_err):
"{a:%Π«ΠΉΠ―Π§}".format(a='a')
+ def test_negative_zero(self):
+ ## default behavior
+ self.assertEqual(f"{-0.:.1f}", "-0.0")
+ self.assertEqual(f"{-.01:.1f}", "-0.0")
+ self.assertEqual(f"{-0:.1f}", "0.0") # integers do not distinguish -0
+
+ ## z sign option
+ self.assertEqual(f"{0.:z.1f}", "0.0")
+ self.assertEqual(f"{0.:z6.1f}", " 0.0")
+ self.assertEqual(f"{-1.:z6.1f}", " -1.0")
+ self.assertEqual(f"{-0.:z.1f}", "0.0")
+ self.assertEqual(f"{.01:z.1f}", "0.0")
+ self.assertEqual(f"{-0:z.1f}", "0.0") # z is allowed for integer input
+ self.assertEqual(f"{-.01:z.1f}", "0.0")
+ self.assertEqual(f"{0.:z.2f}", "0.00")
+ self.assertEqual(f"{-0.:z.2f}", "0.00")
+ self.assertEqual(f"{.001:z.2f}", "0.00")
+ self.assertEqual(f"{-.001:z.2f}", "0.00")
+
+ self.assertEqual(f"{0.:z.1e}", "0.0e+00")
+ self.assertEqual(f"{-0.:z.1e}", "0.0e+00")
+ self.assertEqual(f"{0.:z.1E}", "0.0E+00")
+ self.assertEqual(f"{-0.:z.1E}", "0.0E+00")
+
+ self.assertEqual(f"{-0.001:z.2e}", "-1.00e-03") # tests for mishandled
+ # rounding
+ self.assertEqual(f"{-0.001:z.2g}", "-0.001")
+ self.assertEqual(f"{-0.001:z.2%}", "-0.10%")
+
+ self.assertEqual(f"{-00000.000001:z.1f}", "0.0")
+ self.assertEqual(f"{-00000.:z.1f}", "0.0")
+ self.assertEqual(f"{-.0000000000:z.1f}", "0.0")
+
+ self.assertEqual(f"{-00000.000001:z.2f}", "0.00")
+ self.assertEqual(f"{-00000.:z.2f}", "0.00")
+ self.assertEqual(f"{-.0000000000:z.2f}", "0.00")
+
+ self.assertEqual(f"{.09:z.1f}", "0.1")
+ self.assertEqual(f"{-.09:z.1f}", "-0.1")
+
+ self.assertEqual(f"{-0.: z.0f}", " 0")
+ self.assertEqual(f"{-0.:+z.0f}", "+0")
+ self.assertEqual(f"{-0.:-z.0f}", "0")
+ self.assertEqual(f"{-1.: z.0f}", "-1")
+ self.assertEqual(f"{-1.:+z.0f}", "-1")
+ self.assertEqual(f"{-1.:-z.0f}", "-1")
+
+ self.assertEqual(f"{0.j:z.1f}", "0.0+0.0j")
+ self.assertEqual(f"{-0.j:z.1f}", "0.0+0.0j")
+ self.assertEqual(f"{.01j:z.1f}", "0.0+0.0j")
+ self.assertEqual(f"{-.01j:z.1f}", "0.0+0.0j")
+
+ self.assertEqual(f"{-0.:z>6.1f}", "zz-0.0") # test fill, esp. 'z' fill
+ self.assertEqual(f"{-0.:z>z6.1f}", "zzz0.0")
+ self.assertEqual(f"{-0.:x>z6.1f}", "xxx0.0")
+ self.assertEqual(f"{-0.:πŸ–€>z6.1f}", "πŸ–€πŸ–€πŸ–€0.0") # multi-byte fill char
+
+ def test_specifier_z_error(self):
+ error_msg = re.compile("Invalid format specifier '.*z.*'")
+ with self.assertRaisesRegex(ValueError, error_msg):
+ f"{0:z+f}" # wrong position
+ with self.assertRaisesRegex(ValueError, error_msg):
+ f"{0:fz}" # wrong position
+
+ error_msg = re.escape("Negative zero coercion (z) not allowed")
+ with self.assertRaisesRegex(ValueError, error_msg):
+ f"{0:zd}" # can't apply to int presentation type
+ with self.assertRaisesRegex(ValueError, error_msg):
+ f"{'x':zs}" # can't apply to string
+
+ error_msg = re.escape("unsupported format character 'z'")
+ with self.assertRaisesRegex(ValueError, error_msg):
+ "%z.1f" % 0 # not allowed in old style string interpolation
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index f8b2391..42fd4f5 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -524,18 +524,16 @@ class TypesTests(unittest.TestCase):
self.assertRaises(TypeError, 3.0.__format__, None)
self.assertRaises(TypeError, 3.0.__format__, 0)
- # other format specifiers shouldn't work on floats,
- # in particular int specifiers
- for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] +
- [chr(x) for x in range(ord('A'), ord('Z')+1)]):
- if not format_spec in 'eEfFgGn%':
- self.assertRaises(ValueError, format, 0.0, format_spec)
- self.assertRaises(ValueError, format, 1.0, format_spec)
- self.assertRaises(ValueError, format, -1.0, format_spec)
- self.assertRaises(ValueError, format, 1e100, format_spec)
- self.assertRaises(ValueError, format, -1e100, format_spec)
- self.assertRaises(ValueError, format, 1e-100, format_spec)
- self.assertRaises(ValueError, format, -1e-100, format_spec)
+ # confirm format options expected to fail on floats, such as integer
+ # presentation types
+ for format_spec in 'sbcdoxX':
+ self.assertRaises(ValueError, format, 0.0, format_spec)
+ self.assertRaises(ValueError, format, 1.0, format_spec)
+ self.assertRaises(ValueError, format, -1.0, format_spec)
+ self.assertRaises(ValueError, format, 1e100, format_spec)
+ self.assertRaises(ValueError, format, -1e100, format_spec)
+ self.assertRaises(ValueError, format, 1e-100, format_spec)
+ self.assertRaises(ValueError, format, -1e-100, format_spec)
# Alternate float formatting
test(1.0, '.0e', '1e+00')