diff options
Diffstat (limited to 'Lib/test')
| -rw-r--r-- | Lib/test/test_decimal.py | 60 | ||||
| -rw-r--r-- | Lib/test/test_float.py | 22 | ||||
| -rw-r--r-- | Lib/test/test_format.py | 74 | ||||
| -rw-r--r-- | Lib/test/test_types.py | 22 |
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') |
