[pypy-commit] pypy py3.5: special-case 'bytes([single_integer])' or 'bytes((single_int, ))'
arigo
pypy.commits at gmail.com
Wed Nov 30 09:23:21 EST 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r88763:5aa3b36e215f
Date: 2016-11-30 14:39 +0100
http://bitbucket.org/pypy/pypy/changeset/5aa3b36e215f/
Log: special-case 'bytes([single_integer])' or 'bytes((single_int,))'
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
@@ -1,6 +1,6 @@
"""The builtin bytes implementation"""
-from rpython.rlib.jit import we_are_jitted
+from rpython.rlib import jit
from rpython.rlib.objectmodel import (
compute_hash, compute_unique_id, import_from_mixin, newlist_hint,
resizelist_hint, HASH_ALGORITHM)
@@ -529,10 +529,22 @@
@unwrap_spec(encoding='str_or_None', errors='str_or_None')
def descr_new(space, w_stringtype, w_source=None, encoding=None,
errors=None):
- if (w_source and space.is_w(space.type(w_source), space.w_bytes) and
- space.is_w(w_stringtype, space.w_bytes) and encoding is None
- and errors is None):
- return w_source
+ if (w_source and space.is_w(w_stringtype, space.w_bytes)
+ and encoding is None and errors is None):
+ # special-case 'bytes(byte_object)'
+ w_srctype = space.type(w_source)
+ if w_srctype is space.w_bytes:
+ return w_source
+ # special-case 'bytes([single_integer])' or 'bytes((single_int,))'
+ # for JITted performance only, when we clearly see the
+ # length of the list/tuple being constant and equal to 1
+ if w_srctype is space.w_list or w_srctype is space.w_tuple:
+ length = space.len_w(w_source)
+ if jit.isconstant(length) and length == 1:
+ w_item = space.getitem(w_source, space.wrap(0))
+ value = getbytevalue(space, w_item)
+ return W_BytesObject(value)
+ #
value = newbytesdata_w(space, w_source, encoding, errors)
w_obj = space.allocate_instance(W_BytesObject, w_stringtype)
W_BytesObject.__init__(w_obj, value)
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
@@ -89,6 +89,13 @@
assert self.space.listview_bytes(w_bytes) == None
assert self.space.listview_int(w_bytes) == [97, 98, 99, 100]
+ def test_constructor_single_char(self, monkeypatch):
+ from rpython.rlib import jit
+ monkeypatch.setattr(jit, 'isconstant', lambda x: True)
+ space = self.space
+ w_res = space.call_function(space.w_bytes, space.wrap([42]))
+ assert space.str_w(w_res) == '*'
+
class AppTestBytesObject:
def test_constructor(self):
@@ -97,6 +104,23 @@
assert bytes(b'abc') == b'abc'
assert bytes('abc', 'ascii') == b'abc'
assert bytes(set(b'foo')) in (b'fo', b'of')
+ assert bytes([]) == b''
+ assert bytes([42]) == b'*'
+ assert bytes([0xFC]) == b'\xFC'
+ assert bytes([42, 0xCC]) == b'*\xCC'
+
+ def test_constructor_list_of_objs(self):
+ class X:
+ def __index__(self):
+ return 42
+ class Y:
+ def __int__(self):
+ return 42
+ for obj in [42, X()]:
+ assert bytes([obj]) == b'*'
+ assert bytes([obj, obj, obj]) == b'***'
+ raises(TypeError, bytes, [Y()])
+ raises(TypeError, bytes, [Y(), Y()])
def test_fromhex(self):
assert bytes.fromhex("abcd") == b'\xab\xcd'
More information about the pypy-commit
mailing list