Skip to content

Commit 0674aa7

Browse files
committed
Update test_format.py from Cpython v3.11.2
1 parent 07bad48 commit 0674aa7

File tree

1 file changed

+152
-3
lines changed

1 file changed

+152
-3
lines changed

Lib/test/test_format.py

Lines changed: 152 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from test.support import verbose, TestFailed
22
import locale
33
import sys
4+
import re
45
import test.support as support
56
import unittest
67

@@ -248,7 +249,7 @@ def test_common_format(self):
248249
# base marker shouldn't change the size
249250
testcommon("%0#35.33o", big, "0o012345670123456701234567012345670")
250251

251-
# Some small ints, in both Python int and flavors).
252+
# Some small ints, in both Python int and flavors.
252253
testcommon("%d", 42, "42")
253254
testcommon("%d", -42, "-42")
254255
testcommon("%d", 42.0, "42")
@@ -274,9 +275,9 @@ def test_common_format(self):
274275
test_exc_common('% %s', 1, ValueError,
275276
"unsupported format character '%' (0x25) at index 2")
276277
test_exc_common('%d', '1', TypeError,
277-
"%d format: a number is required, not str")
278+
"%d format: a real number is required, not str")
278279
test_exc_common('%d', b'1', TypeError,
279-
"%d format: a number is required, not bytes")
280+
"%d format: a real number is required, not bytes")
280281
test_exc_common('%x', '1', TypeError,
281282
"%x format: an integer is required, not str")
282283
test_exc_common('%x', 3.14, TypeError,
@@ -493,6 +494,154 @@ def test_precision_c_limits(self):
493494
with self.assertRaises(ValueError) as cm:
494495
format(c, ".%sf" % (INT_MAX + 1))
495496

497+
def test_g_format_has_no_trailing_zeros(self):
498+
# regression test for bugs.python.org/issue40780
499+
self.assertEqual("%.3g" % 1505.0, "1.5e+03")
500+
self.assertEqual("%#.3g" % 1505.0, "1.50e+03")
501+
502+
self.assertEqual(format(1505.0, ".3g"), "1.5e+03")
503+
self.assertEqual(format(1505.0, "#.3g"), "1.50e+03")
504+
505+
self.assertEqual(format(12300050.0, ".6g"), "1.23e+07")
506+
self.assertEqual(format(12300050.0, "#.6g"), "1.23000e+07")
507+
508+
# TODO: RUSTPYTHON
509+
@unittest.expectedFailure
510+
def test_with_two_commas_in_format_specifier(self):
511+
error_msg = re.escape("Cannot specify ',' with ','.")
512+
with self.assertRaisesRegex(ValueError, error_msg):
513+
'{:,,}'.format(1)
514+
515+
# TODO: RUSTPYTHON
516+
@unittest.expectedFailure
517+
def test_with_two_underscore_in_format_specifier(self):
518+
error_msg = re.escape("Cannot specify '_' with '_'.")
519+
with self.assertRaisesRegex(ValueError, error_msg):
520+
'{:__}'.format(1)
521+
522+
# TODO: RUSTPYTHON
523+
@unittest.expectedFailure
524+
def test_with_a_commas_and_an_underscore_in_format_specifier(self):
525+
error_msg = re.escape("Cannot specify both ',' and '_'.")
526+
with self.assertRaisesRegex(ValueError, error_msg):
527+
'{:,_}'.format(1)
528+
529+
# TODO: RUSTPYTHON
530+
@unittest.expectedFailure
531+
def test_with_an_underscore_and_a_comma_in_format_specifier(self):
532+
error_msg = re.escape("Cannot specify both ',' and '_'.")
533+
with self.assertRaisesRegex(ValueError, error_msg):
534+
'{:_,}'.format(1)
535+
536+
# TODO: RUSTPYTHON
537+
@unittest.expectedFailure
538+
def test_better_error_message_format(self):
539+
# https://bugs.python.org/issue20524
540+
for value in [12j, 12, 12.0, "12"]:
541+
with self.subTest(value=value):
542+
# The format spec must be invalid for all types we're testing.
543+
# '%M' will suffice.
544+
bad_format_spec = '%M'
545+
err = re.escape("Invalid format specifier "
546+
f"'{bad_format_spec}' for object of type "
547+
f"'{type(value).__name__}'")
548+
with self.assertRaisesRegex(ValueError, err):
549+
f"xx{{value:{bad_format_spec}}}yy".format(value=value)
550+
551+
# Also test the builtin format() function.
552+
with self.assertRaisesRegex(ValueError, err):
553+
format(value, bad_format_spec)
554+
555+
# Also test f-strings.
556+
with self.assertRaisesRegex(ValueError, err):
557+
eval("f'xx{value:{bad_format_spec}}yy'")
558+
559+
# TODO: RUSTPYTHON
560+
@unittest.expectedFailure
561+
def test_unicode_in_error_message(self):
562+
str_err = re.escape(
563+
"Invalid format specifier '%ЫйЯЧ' for object of type 'str'")
564+
with self.assertRaisesRegex(ValueError, str_err):
565+
"{a:%ЫйЯЧ}".format(a='a')
566+
567+
# TODO: RUSTPYTHON
568+
@unittest.expectedFailure
569+
def test_negative_zero(self):
570+
## default behavior
571+
self.assertEqual(f"{-0.:.1f}", "-0.0")
572+
self.assertEqual(f"{-.01:.1f}", "-0.0")
573+
self.assertEqual(f"{-0:.1f}", "0.0") # integers do not distinguish -0
574+
575+
## z sign option
576+
self.assertEqual(f"{0.:z.1f}", "0.0")
577+
self.assertEqual(f"{0.:z6.1f}", " 0.0")
578+
self.assertEqual(f"{-1.:z6.1f}", " -1.0")
579+
self.assertEqual(f"{-0.:z.1f}", "0.0")
580+
self.assertEqual(f"{.01:z.1f}", "0.0")
581+
self.assertEqual(f"{-0:z.1f}", "0.0") # z is allowed for integer input
582+
self.assertEqual(f"{-.01:z.1f}", "0.0")
583+
self.assertEqual(f"{0.:z.2f}", "0.00")
584+
self.assertEqual(f"{-0.:z.2f}", "0.00")
585+
self.assertEqual(f"{.001:z.2f}", "0.00")
586+
self.assertEqual(f"{-.001:z.2f}", "0.00")
587+
588+
self.assertEqual(f"{0.:z.1e}", "0.0e+00")
589+
self.assertEqual(f"{-0.:z.1e}", "0.0e+00")
590+
self.assertEqual(f"{0.:z.1E}", "0.0E+00")
591+
self.assertEqual(f"{-0.:z.1E}", "0.0E+00")
592+
593+
self.assertEqual(f"{-0.001:z.2e}", "-1.00e-03") # tests for mishandled
594+
# rounding
595+
self.assertEqual(f"{-0.001:z.2g}", "-0.001")
596+
self.assertEqual(f"{-0.001:z.2%}", "-0.10%")
597+
598+
self.assertEqual(f"{-00000.000001:z.1f}", "0.0")
599+
self.assertEqual(f"{-00000.:z.1f}", "0.0")
600+
self.assertEqual(f"{-.0000000000:z.1f}", "0.0")
601+
602+
self.assertEqual(f"{-00000.000001:z.2f}", "0.00")
603+
self.assertEqual(f"{-00000.:z.2f}", "0.00")
604+
self.assertEqual(f"{-.0000000000:z.2f}", "0.00")
605+
606+
self.assertEqual(f"{.09:z.1f}", "0.1")
607+
self.assertEqual(f"{-.09:z.1f}", "-0.1")
608+
609+
self.assertEqual(f"{-0.: z.0f}", " 0")
610+
self.assertEqual(f"{-0.:+z.0f}", "+0")
611+
self.assertEqual(f"{-0.:-z.0f}", "0")
612+
self.assertEqual(f"{-1.: z.0f}", "-1")
613+
self.assertEqual(f"{-1.:+z.0f}", "-1")
614+
self.assertEqual(f"{-1.:-z.0f}", "-1")
615+
616+
self.assertEqual(f"{0.j:z.1f}", "0.0+0.0j")
617+
self.assertEqual(f"{-0.j:z.1f}", "0.0+0.0j")
618+
self.assertEqual(f"{.01j:z.1f}", "0.0+0.0j")
619+
self.assertEqual(f"{-.01j:z.1f}", "0.0+0.0j")
620+
621+
self.assertEqual(f"{-0.:z>6.1f}", "zz-0.0") # test fill, esp. 'z' fill
622+
self.assertEqual(f"{-0.:z>z6.1f}", "zzz0.0")
623+
self.assertEqual(f"{-0.:x>z6.1f}", "xxx0.0")
624+
self.assertEqual(f"{-0.:🖤>z6.1f}", "🖤🖤🖤0.0") # multi-byte fill char
625+
626+
# TODO: RUSTPYTHON
627+
@unittest.expectedFailure
628+
def test_specifier_z_error(self):
629+
error_msg = re.compile("Invalid format specifier '.*z.*'")
630+
with self.assertRaisesRegex(ValueError, error_msg):
631+
f"{0:z+f}" # wrong position
632+
with self.assertRaisesRegex(ValueError, error_msg):
633+
f"{0:fz}" # wrong position
634+
635+
error_msg = re.escape("Negative zero coercion (z) not allowed")
636+
with self.assertRaisesRegex(ValueError, error_msg):
637+
f"{0:zd}" # can't apply to int presentation type
638+
with self.assertRaisesRegex(ValueError, error_msg):
639+
f"{'x':zs}" # can't apply to string
640+
641+
error_msg = re.escape("unsupported format character 'z'")
642+
with self.assertRaisesRegex(ValueError, error_msg):
643+
"%z.1f" % 0 # not allowed in old style string interpolation
644+
496645

497646
if __name__ == "__main__":
498647
unittest.main()

0 commit comments

Comments
 (0)