[pypy-commit] pypy py3.5-byteformat: add __mod__ to W_BytesObject, use mod_format to format the bytes object
plan_rich
pypy.commits at gmail.com
Wed Aug 31 02:59:06 EDT 2016
Author: Richard Plangger <planrichi at gmail.com>
Branch: py3.5-byteformat
Changeset: r86762:e551d8bfa0da
Date: 2016-08-31 08:58 +0200
http://bitbucket.org/pypy/pypy/changeset/e551d8bfa0da/
Log: add __mod__ to W_BytesObject, use mod_format to format the bytes
object
diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py
--- a/pypy/objspace/std/bytesobject.py
+++ b/pypy/objspace/std/bytesobject.py
@@ -14,6 +14,7 @@
from pypy.interpreter.typedef import TypeDef
from pypy.objspace.std.stringmethods import StringMethods
from pypy.objspace.std.util import IDTAG_SPECIAL, IDTAG_SHIFT
+from pypy.objspace.std.formatting import mod_format, FORMAT_BYTES
class W_AbstractBytesObject(W_Root):
@@ -394,6 +395,12 @@
of the specified width. The string S is never truncated.
"""
+ def descr_mod(self, space, w_values):
+ """S % values -> string
+
+ Format bytes objects
+ """
+
class W_BytesObject(W_AbstractBytesObject):
import_from_mixin(StringMethods)
_immutable_fields_ = ['_value']
@@ -663,6 +670,9 @@
from pypy.objspace.std.bytearrayobject import _array_to_hexstring
return _array_to_hexstring(space, StringBuffer(self._value))
+ def descr_mod(self, space, w_values):
+ return mod_format(space, self, w_values, fmt_type=FORMAT_BYTES)
+
@staticmethod
def _iter_getitem_result(self, space, index):
assert isinstance(self, W_BytesObject)
@@ -803,6 +813,8 @@
__mul__ = interpindirect2app(W_AbstractBytesObject.descr_mul),
__rmul__ = interpindirect2app(W_AbstractBytesObject.descr_rmul),
+ __mod__ = interpindirect2app(W_AbstractBytesObject.descr_mod),
+
__getitem__ = interpindirect2app(W_AbstractBytesObject.descr_getitem),
capitalize = interpindirect2app(W_AbstractBytesObject.descr_capitalize),
diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py
--- a/pypy/objspace/std/formatting.py
+++ b/pypy/objspace/std/formatting.py
@@ -494,9 +494,14 @@
[_name[-1] for _name in dir(StringFormatter)
if len(_name) == 5 and _name.startswith('fmt_')])
-def format(space, w_fmt, values_w, w_valuedict, do_unicode):
+FORMAT_STR = 0
+FORMAT_UNICODE = 1
+FORMAT_BYTES = 2
+FORMAT_BYTEARRAY = 3
+
+def format(space, w_fmt, values_w, w_valuedict, fmt_type):
"Entry point"
- if not do_unicode:
+ if fmt_type != FORMAT_UNICODE:
fmt = space.str_w(w_fmt)
formatter = StringFormatter(space, fmt, values_w, w_valuedict)
try:
@@ -505,25 +510,29 @@
# fall through to the unicode case
pass
else:
+ if fmt_type == FORMAT_BYTES:
+ return space.newbytes(result)
+ elif fmt_type == FORMAT_BYTEARRAY:
+ return space.newbytearray(result)
return space.wrap(result)
fmt = space.unicode_w(w_fmt)
formatter = UnicodeFormatter(space, fmt, values_w, w_valuedict)
result = formatter.format()
return space.wrap(result)
-def mod_format(space, w_format, w_values, do_unicode=False):
+def mod_format(space, w_format, w_values, fmt_type=FORMAT_STR):
if space.isinstance_w(w_values, space.w_tuple):
values_w = space.fixedview(w_values)
- return format(space, w_format, values_w, None, do_unicode)
+ return format(space, w_format, values_w, None, fmt_type)
else:
# we check directly for dict to avoid obscure checking
# in simplest case
if space.isinstance_w(w_values, space.w_dict) or \
(space.lookup(w_values, '__getitem__') and
not space.isinstance_w(w_values, space.w_unicode)):
- return format(space, w_format, [w_values], w_values, do_unicode)
+ return format(space, w_format, [w_values], w_values, fmt_type)
else:
- return format(space, w_format, [w_values], None, do_unicode)
+ return format(space, w_format, [w_values], None, fmt_type)
# ____________________________________________________________
# Formatting helpers
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -346,6 +346,9 @@
def newbytes(self, s):
return W_BytesObject(s)
+ def newbytearray(self, l):
+ return W_BytearrayObject(l)
+
def newunicode(self, uni):
return W_UnicodeObject(uni)
diff --git a/pypy/objspace/std/test/test_bytesobject.py b/pypy/objspace/std/test/test_bytesobject.py
--- a/pypy/objspace/std/test/test_bytesobject.py
+++ b/pypy/objspace/std/test/test_bytesobject.py
@@ -97,10 +97,6 @@
assert bytes('abc', 'ascii') == b'abc'
assert bytes(set(b'foo')) in (b'fo', b'of')
- def test_format(self):
- import operator
- raises(TypeError, operator.mod, b"%s", (1,))
-
def test_fromhex(self):
assert bytes.fromhex("abcd") == b'\xab\xcd'
assert b''.fromhex("abcd") == b'\xab\xcd'
@@ -877,3 +873,11 @@
"73616e746120636c617573"
assert bytes(64).hex() == "00"*64
+ def test_format(self):
+ assert eval("b'a%db' % 2") == eval("b'a2b'")
+ assert eval("b'00%.2f'").__mod__((0.01234)) == eval("b'000.01'")
+ assert eval("b'%04X' % 10") == eval("b'000A'")
+ assert eval("b'%c' % 48") == eval("b'0'")
+ assert eval("b'%c' % b'a'") == eval("b'a'")
+ assert eval("b'%b' % b'abc'") == eval("b'abc'")
+
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -15,7 +15,7 @@
from pypy.interpreter.typedef import TypeDef
from pypy.module.unicodedata import unicodedb
from pypy.objspace.std import newformat
-from pypy.objspace.std.formatting import mod_format
+from pypy.objspace.std.formatting import mod_format, FORMAT_UNICODE
from pypy.objspace.std.stringmethods import StringMethods
from pypy.objspace.std.util import IDTAG_SPECIAL, IDTAG_SHIFT
@@ -392,7 +392,7 @@
self)
def descr_mod(self, space, w_values):
- return mod_format(space, self, w_values, do_unicode=True)
+ return mod_format(space, self, w_values, fmt_type=FORMAT_UNICODE)
def descr_translate(self, space, w_table):
selfvalue = self._value
More information about the pypy-commit
mailing list