cpython: 99abb731ea7a (original) (raw)

--- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -300,7 +300,7 @@ non-empty format string typically modifi The general form of a standard format specifier is: .. productionlist:: sf

+The '_' option signals the use of an underscore for a thousands +separator for floating point presentation types and for integer +presentation type 'd'. For integer presentation types 'b', +'o', 'x', and 'X', underscores will be inserted every 4 +digits. For other presentation types, specifying this option is an +error. + +.. versionchanged:: 3.6

width is a decimal integer defining the minimum field width. If not specified, then the field width will be determined by the content.

--- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -621,6 +621,8 @@ class LongTest(unittest.TestCase): def test__format__(self): self.assertEqual(format(123456789, 'd'), '123456789') self.assertEqual(format(123456789, 'd'), '123456789')

# sign and aligning are interdependent self.assertEqual(format(1, "-"), '1') @@ -649,8 +651,25 @@ class LongTest(unittest.TestCase): self.assertEqual(format(int('be', 16), "X"), "BE") self.assertEqual(format(-int('be', 16), "x"), "-be") self.assertEqual(format(-int('be', 16), "X"), "-BE")

# octal

+

@@ -661,12 +680,21 @@ class LongTest(unittest.TestCase): self.assertEqual(format(-1234, " b"), "-10011010010") self.assertEqual(format(1234, "+b"), "+10011010010") self.assertEqual(format(-1234, "+b"), "-10011010010")

# make sure these are errors self.assertRaises(ValueError, format, 3, "1.3") # precision disallowed

+ # ensure that only int and float type specifiers work 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)]):

--- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ What's New in Python 3.6.0 beta 1 Core and Builtins ----------------- +- Issue #27080: Implement formatting support for PEP 515. Initial patch

--- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -32,14 +32,20 @@ invalid_comma_type(Py_UCS4 presentation_ { if (presentation_type > 32 && presentation_type < 128) PyErr_Format(PyExc_ValueError,

} +static void +invalid_comma_and_underscore() +{

+} + /* get_integer consumes 0 or more decimal digit characters from an input string, updates result with the corresponding positive @@ -108,6 +114,12 @@ is_sign_element(Py_UCS4 c) } } +/ Locale type codes. LT_NO_LOCALE must be zero. / +#define LT_NO_LOCALE 0 +#define LT_DEFAULT_LOCALE 1 +#define LT_UNDERSCORE_LOCALE 2 +#define LT_UNDER_FOUR_LOCALE 3 +#define LT_CURRENT_LOCALE 4 typedef struct { Py_UCS4 fill_char; @@ -223,9 +235,22 @@ parse_internal_render_format_spec(PyObje / Comma signifies add thousands separators */ if (end-pos && READ_spec(pos) == ',') {

/* Parse field precision / if (end-pos && READ_spec(pos) == '.') { @@ -275,6 +300,16 @@ parse_internal_render_format_spec(PyObje case '\0': / These are allowed. See PEP 378.*/ break;

@@ -351,11 +386,6 @@ fill_padding(_PyUnicodeWriter writer, /********** common routines for numeric formatting / /***************************************************/ -/* Locale type codes. / -#define LT_CURRENT_LOCALE 0 -#define LT_DEFAULT_LOCALE 1 -#define LT_NO_LOCALE 2 - / Locale info needed for formatting integers and the part of floats before and including the decimal. Note that locales only support 8-bit chars, not unicode. / @@ -667,8 +697,8 @@ static const char no_grouping[1] = {CHAR / Find the decimal point character(s?), thousands_separator(s?), and grouping description, either for the current locale if type is

@@ -952,9 +988,7 @@ format_long_internal(PyObject value, co / Determine the grouping, separator, and decimal point, if any. */ if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :

@@ -1099,9 +1133,7 @@ format_float_internal(PyObject value, / Determine the grouping, separator, and decimal point, if any. */ if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :

@@ -1277,9 +1309,7 @@ format_complex_internal(PyObject value, / Determine the grouping, separator, and decimal point, if any. */ if (get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :