From fb13721b1b48b814dd8efbececfbb1e6c52c1c5d Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Sat, 31 Aug 2013 10:18:55 -0700 Subject: [PATCH] Close #18780: %-formatting now prints value for int subclasses with %d, %i, and %u codes. --- Lib/test/test_unicode.py | 47 ++++++++++++++++++++++++++++++++++++++++ Misc/NEWS | 3 +++ Objects/unicodeobject.c | 8 +++---- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 9e53213a920..daab79d742d 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -1124,6 +1124,53 @@ class UnicodeTest(string_tests.CommonTest, self.assertEqual('%.1s' % "a\xe9\u20ac", 'a') self.assertEqual('%.2s' % "a\xe9\u20ac", 'a\xe9') + def test_formatting_with_enum(self): + # issue18780 + import enum + class Float(float, enum.Enum): + PI = 3.1415926 + class Int(enum.IntEnum): + IDES = 15 + class Str(str, enum.Enum): + ABC = 'abc' + # Testing Unicode formatting strings... + self.assertEqual( + "%s, %s" % (Str.ABC, Str.ABC), + 'Str.ABC, Str.ABC', + ) + self.assertEqual( + "%s, %s, %d, %i, %u, %f, %5.2f" % + (Str.ABC, Str.ABC, + Int.IDES, Int.IDES, Int.IDES, + Float.PI, Float.PI), + 'Str.ABC, Str.ABC, 15, 15, 15, 3.141593, 3.14') + + # formatting jobs delegated from the string implementation: + self.assertEqual( + '...%(foo)s...' % {'foo':Str.ABC}, + '...Str.ABC...', + ) + self.assertEqual( + '...%(foo)s...' % {'foo':Int.IDES}, + '...Int.IDES...', + ) + self.assertEqual( + '...%(foo)i...' % {'foo':Int.IDES}, + '...15...', + ) + self.assertEqual( + '...%(foo)d...' % {'foo':Int.IDES}, + '...15...', + ) + self.assertEqual( + '...%(foo)u...' % {'foo':Int.IDES, 'def':Float.PI}, + '...15...', + ) + self.assertEqual( + '...%(foo)f...' % {'foo':Float.PI,'def':123}, + '...3.141593...', + ) + @support.cpython_only def test_formatting_huge_precision(self): from _testcapi import INT_MAX diff --git a/Misc/NEWS b/Misc/NEWS index 7258ce1755f..e655fe57b2b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -48,6 +48,9 @@ Core and Builtins - Issue #17934: Add a clear() method to frame objects, to help clean up expensive details (local variables) and break reference cycles. +- Issue #18780: %-formatting codes %d, %i, and %u now treat int-subclasses + as int (displays value of int-subclass instead of str(int-subclass) ). + Library ------- diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f1d687ae9d6..6dc583517c2 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -13566,11 +13566,9 @@ formatlong(PyObject *val, struct unicode_format_arg_t *arg) case 'd': case 'i': case 'u': - /* Special-case boolean: we want 0/1 */ - if (PyBool_Check(val)) - result = PyNumber_ToBase(val, 10); - else - result = Py_TYPE(val)->tp_str(val); + /* int and int subclasses should print numerically when a numeric */ + /* format code is used (see issue18780) */ + result = PyNumber_ToBase(val, 10); break; case 'o': numnondigits = 2;