summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_builtin.py1
-rw-r--r--Lib/test/test_long.py15
-rw-r--r--Lib/test/test_unicode.py16
-rw-r--r--Objects/stringlib/formatter.h28
4 files changed, 36 insertions, 24 deletions
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 2d3e1cc..e5957ae 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -540,6 +540,7 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(format(3.1415e-104, ""), str(3.1415e-104))
self.assertEqual(format(-3.1415e-104, ""), str(-3.1415e-104))
self.assertEqual(format(object, ""), str(object))
+ self.assertEqual(format(None, ""), str(None))
# TypeError because self.__format__ returns the wrong type
self.assertRaises(TypeError, format, H(), "")
diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py
index 4e15340..4ba825a 100644
--- a/Lib/test/test_long.py
+++ b/Lib/test/test_long.py
@@ -497,13 +497,25 @@ class LongTest(unittest.TestCase):
self.assertEqual(format(123456789, 'd'), '123456789')
self.assertEqual(format(123456789, 'd'), '123456789')
+ # sign and aligning are interdependent
+ self.assertEqual(format(1, "-"), '1')
+ self.assertEqual(format(-1, "-"), '-1')
+ self.assertEqual(format(1, "-3"), ' 1')
+ self.assertEqual(format(-1, "-3"), ' -1')
+ self.assertEqual(format(1, "+3"), ' +1')
+ self.assertEqual(format(-1, "+3"), ' -1')
+ self.assertEqual(format(1, " 3"), ' 1')
+ self.assertEqual(format(-1, " 3"), ' -1')
+ self.assertEqual(format(1, " "), ' 1')
+ self.assertEqual(format(-1, " "), '-1')
+
# hex
self.assertEqual(format(3, "x"), "3")
self.assertEqual(format(3, "X"), "3")
self.assertEqual(format(1234, "x"), "4d2")
self.assertEqual(format(-1234, "x"), "-4d2")
self.assertEqual(format(1234, "8x"), " 4d2")
-# XXX fix self.assertEqual(format(-1234, "8x"), " -4d2")
+ self.assertEqual(format(-1234, "8x"), " -4d2")
self.assertEqual(format(1234, "x"), "4d2")
self.assertEqual(format(-1234, "x"), "-4d2")
self.assertEqual(format(-3, "x"), "-3")
@@ -530,7 +542,6 @@ class LongTest(unittest.TestCase):
# make sure these are errors
self.assertRaises(ValueError, format, 3, "1.3") # precision disallowed
- return
self.assertRaises(ValueError, format, 3, "+c") # sign not allowed
# with 'c'
self.assertRaises(ValueError, format, 3, "R") # bogus format type
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index 47d7236..444656a 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -379,8 +379,6 @@ class UnicodeTest(
self.assertEqual("The year is {0.year}".format(d),
"The year is 2007")
- #"{0!r:20}".format("Hello")
-
# classes we'll use for testing
class C:
def __init__(self, x=100):
@@ -428,6 +426,10 @@ class UnicodeTest(
def __format__(self, format_spec):
return self.strftime(format_spec)
+ class J(int):
+ def __format__(self, format_spec):
+ return int.__format__(self * 2, format_spec)
+
self.assertEqual(''.format(), '')
self.assertEqual('abc'.format(), 'abc')
@@ -465,12 +467,6 @@ class UnicodeTest(
self.assertEqual('{0[1][0]}'.format(['abc', ['def']]), 'def')
self.assertEqual('{0[1][0].x}'.format(['abc', [D('def')]]), 'def')
- # I'm not sure if this should work, or if it's a problem if it does work
- #'{0[_{foo}]}'.format({'_FOO': 'abc'}, foo='FOO')
- #('{0[{foo}{bar}]}'.format({'FOOBAR': 'abc'}, foo='FOO', bar='BAR')
-
- # format specifiers for built in types
-
# strings
self.assertEqual('{0:.3s}'.format('abc'), 'abc')
self.assertEqual('{0:.3s}'.format('ab'), 'ab')
@@ -524,6 +520,10 @@ class UnicodeTest(
day=27)),
"date: 2007-08-27")
+ # test deriving from a builtin type and overriding __format__
+ self.assertEqual("{0}".format(J(10)), "20")
+
+
# string format specifiers
self.assertEqual('{0:}'.format('a'), 'a')
diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h
index c408350..8e2b8ef 100644
--- a/Objects/stringlib/formatter.h
+++ b/Objects/stringlib/formatter.h
@@ -145,8 +145,7 @@ parse_internal_render_format_spec(PyObject *format_spec,
}
/* The special case for 0-padding (backwards compat) */
- if (format->fill_char == '\0' &&
- end-ptr >= 1 && ptr[0] == '0') {
+ if (format->fill_char == '\0' && end-ptr >= 1 && ptr[0] == '0') {
format->fill_char = '0';
if (format->align == '\0') {
format->align = '=';
@@ -298,9 +297,10 @@ calc_number_widths(NumberFieldWidths *r, STRINGLIB_CHAR actual_sign,
r->n_lpadding = padding / 2;
r->n_rpadding = padding - r->n_lpadding;
}
- else
- /* must be '=' */
+ else if (format->align == '=')
r->n_spadding = padding;
+ else
+ r->n_lpadding = padding;
}
}
r->n_total = r->n_lpadding + r->n_lsign + r->n_spadding +
@@ -603,7 +603,7 @@ strtounicode(Py_UNICODE *buffer, const char *charbuffer)
register Py_ssize_t i;
Py_ssize_t len = strlen(charbuffer);
for (i = len - 1; i >= 0; i--)
- buffer[i] = (Py_UNICODE) charbuffer[i];
+ buffer[i] = (Py_UNICODE) charbuffer[i];
return len;
}
@@ -641,14 +641,14 @@ _format_float(STRINGLIB_CHAR type, PyObject *value,
/* Worst case length calc to ensure no buffer overrun:
'g' formats:
- fmt = %#.<prec>g
- buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp
- for any double rep.)
- len = 1 + prec + 1 + 2 + 5 = 9 + prec
+ fmt = %#.<prec>g
+ buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp
+ for any double rep.)
+ len = 1 + prec + 1 + 2 + 5 = 9 + prec
'f' formats:
- buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50)
- len = 1 + 50 + 1 + prec = 52 + prec
+ buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50)
+ len = 1 + 50 + 1 + prec = 52 + prec
If prec=0 the effective precision is 1 (the leading digit is
always given), therefore increase the length by one.
@@ -678,7 +678,7 @@ _format_float(STRINGLIB_CHAR type, PyObject *value,
x = PyFloat_AsDouble(value);
if (x == -1.0 && PyErr_Occurred())
- goto done;
+ goto done;
if (type == '%') {
type = 'f';
@@ -687,9 +687,9 @@ _format_float(STRINGLIB_CHAR type, PyObject *value,
}
if (precision < 0)
- precision = 6;
+ precision = 6;
if (type == 'f' && (fabs(x) / 1e25) >= 1e25)
- type = 'g';
+ type = 'g';
/* cast "type", because if we're in unicode we need to pass a
8-bit char. this is safe, because we've restricted what "type"