[pypy-commit] pypy py3.6: support for '_' format modifiert for formatting strings
cfbolz
pypy.commits at gmail.com
Sun May 27 15:45:46 EDT 2018
Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: py3.6
Changeset: r94693:846993741acb
Date: 2018-05-27 21:44 +0200
http://bitbucket.org/pypy/pypy/changeset/846993741acb/
Log: support for '_' format modifiert for formatting strings
diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py
--- a/pypy/objspace/std/newformat.py
+++ b/pypy/objspace/std/newformat.py
@@ -455,7 +455,7 @@
self._align = default_align
self._alternate = False
self._sign = "\0"
- self._thousands_sep = False
+ self._thousands_sep = "\0"
self._precision = -1
the_type = default_type
spec = self.spec
@@ -488,8 +488,17 @@
i += 1
self._width, i = _parse_int(self.space, spec, i, length)
if length != i and spec[i] == ",":
- self._thousands_sep = True
+ self._thousands_sep = ","
i += 1
+ if length != i and spec[i] == "_":
+ if self._thousands_sep != "\0":
+ raise oefmt(
+ space.w_ValueError, "Cannot specify both ',' and '_'.")
+ self._thousands_sep = "_"
+ i += 1
+ if length != i and spec[i] == ",":
+ raise oefmt(
+ space.w_ValueError, "Cannot specify both ',' and '_'.")
if length != i and spec[i] == ".":
i += 1
self._precision, i = _parse_int(self.space, spec, i, length)
@@ -509,7 +518,7 @@
the_type = presentation_type
i += 1
self._type = the_type
- if self._thousands_sep:
+ if self._thousands_sep != "\0":
tp = self._type
if (tp == "d" or
tp == "e" or
@@ -522,8 +531,15 @@
tp == "\0"):
# ok
pass
+ elif self._thousands_sep == "_" and (
+ tp == "b" or
+ tp == "o" or
+ tp == "x" or
+ tp == "X"):
+ pass # ok
else:
- raise oefmt(space.w_ValueError, "invalid type with ','")
+ raise oefmt(space.w_ValueError,
+ "invalid type with ',' or '_'")
return False
def _calc_padding(self, string, length):
@@ -601,10 +617,13 @@
def _get_locale(self, tp):
if tp == "n":
dec, thousands, grouping = rlocale.numeric_formatting()
- elif self._thousands_sep:
+ elif self._thousands_sep != "\0":
+ thousands = self._thousands_sep
dec = "."
- thousands = ","
grouping = "\3"
+ if tp in "boxX":
+ assert self._thousands_sep == "_"
+ grouping = "\4"
else:
dec = "."
thousands = ""
diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py
--- a/pypy/objspace/std/test/test_newformat.py
+++ b/pypy/objspace/std/test/test_newformat.py
@@ -246,12 +246,18 @@
def test_invalid(self):
raises(ValueError, format, self.i(8), "s")
raises(ValueError, format, self.i(8), ".3")
+ raises(ValueError, format, self.i(3), '_,')
+ raises(ValueError, format, self.i(3), ',_')
+ raises(ValueError, format, self.i(3), '_,d')
+ raises(ValueError, format, self.i(3), ',_d')
+
def test_c(self):
a = self.i(ord("a"))
assert format(a, "c") == "a"
raises(ValueError, format, a, "-c")
raises(ValueError, format, a, ",c")
+ raises(ValueError, format, a, "_c")
raises(ValueError, format, a, "#c")
assert format(a, "3c") == " a"
assert format(a, "<3c") == "a "
@@ -262,6 +268,8 @@
def test_binary(self):
assert format(self.i(2), "b") == "10"
assert format(self.i(2), "#b") == "0b10"
+ assert format(12345, '_b') == '11_0000_0011_1001'
+ raises(ValueError, format, self.i(1234567890), ',b')
def test_octal(self):
assert format(self.i(8), "o") == "10"
@@ -270,6 +278,8 @@
assert format(self.i(-8), "#o") == "-0o10"
assert format(self.i(8), "+o") == "+10"
assert format(self.i(8), "+#o") == "+0o10"
+ raises(ValueError, format, self.i(1234567890), ',o')
+ assert format(self.i(1234567890), '_o'), '111_4540_1322'
def test_hex(self):
assert format(self.i(16), "x") == "10"
@@ -278,6 +288,10 @@
assert format(self.i(10), "#x") == "0xa"
assert format(self.i(10), "X") == "A"
assert format(self.i(10), "#X") == "0XA"
+ raises(ValueError, format, 1234567890, ',x')
+ assert format(1234567890, '_x') == '4996_02d2'
+ assert format(1234567890, '_X') == '4996_02D2'
+
def test_padding(self):
assert format(self.i(6), "3") == " 6"
@@ -310,6 +324,14 @@
assert format(self.i(1234), "0=10,") == "00,001,234"
assert format(self.i(1234), "010,") == "00,001,234"
+ def test_thousands_separator_underscore(self):
+ assert format(self.i(123), "_") == "123"
+ assert format(self.i(12345), "_") == "12_345"
+ assert format(self.i(123456789), "_") == "123_456_789"
+ assert format(self.i(12345), "7_") == " 12_345"
+ assert format(self.i(12345), "<7_") == "12_345 "
+ assert format(self.i(1234), "0=10_") == "00_001_234"
+ assert format(self.i(1234), "010_") == "00_001_234"
class AppTestIntFormatting(BaseIntegralFormattingTest):
def setup_class(cls):
@@ -342,6 +364,9 @@
def test_digit_separator(self):
assert format(-1234., "012,f") == "-1,234.000000"
+ def test_digit_separator_underscore(self):
+ assert format(-1234., "012_f") == "-1_234.000000"
+
def test_locale(self):
import locale
for name in ['en_US.UTF8', 'en_US', 'en']:
More information about the pypy-commit
mailing list