[pypy-commit] pypy stdlib-2.7.8: Initial implementation of operator._compare_digest
alex_gaynor
noreply at buildbot.pypy.org
Thu Aug 21 03:19:33 CEST 2014
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: stdlib-2.7.8
Changeset: r72945:6c4fc35d1793
Date: 2014-08-20 18:19 -0700
http://bitbucket.org/pypy/pypy/changeset/6c4fc35d1793/
Log: Initial implementation of operator._compare_digest
diff --git a/pypy/module/operator/__init__.py b/pypy/module/operator/__init__.py
--- a/pypy/module/operator/__init__.py
+++ b/pypy/module/operator/__init__.py
@@ -38,7 +38,9 @@
'ilshift', 'imod', 'imul', 'ior', 'ipow', 'irepeat',
'irshift', 'isub', 'itruediv', 'ixor', '_length_hint']
- interpleveldefs = {}
+ interpleveldefs = {
+ '_compare_digest': 'interp_operator.compare_digest',
+ }
for name in interp_names:
interpleveldefs[name] = 'interp_operator.%s' % name
diff --git a/pypy/module/operator/interp_operator.py b/pypy/module/operator/interp_operator.py
--- a/pypy/module/operator/interp_operator.py
+++ b/pypy/module/operator/interp_operator.py
@@ -1,6 +1,9 @@
-from pypy.interpreter.error import OperationError
+from rpython.rlib.objectmodel import specialize
+
+from pypy.interpreter.error import OperationError, oefmt
from pypy.interpreter.gateway import unwrap_spec
+
def index(space, w_a):
return space.index(w_a)
@@ -70,7 +73,7 @@
def invert(space, w_obj,):
'invert(a) -- Same as ~a.'
- return space.invert(w_obj)
+ return space.invert(w_obj)
def isCallable(space, w_obj):
'isCallable(a) -- Same as callable(a).'
@@ -96,7 +99,7 @@
def lshift(space, w_a, w_b):
'lshift(a, b) -- Same as a << b.'
- return space.lshift(w_a, w_b)
+ return space.lshift(w_a, w_b)
def lt(space, w_a, w_b):
'lt(a, b) -- Same as a<b.'
@@ -112,7 +115,7 @@
def ne(space, w_a, w_b):
'ne(a, b) -- Same as a!=b.'
- return space.ne(w_a, w_b)
+ return space.ne(w_a, w_b)
def neg(space, w_obj,):
'neg(a) -- Same as -a.'
@@ -128,7 +131,7 @@
def pos(space, w_obj,):
'pos(a) -- Same as +a.'
- return space.pos(w_obj)
+ return space.pos(w_obj)
def pow(space, w_a, w_b):
'pow(a, b) -- Same as a**b.'
@@ -138,7 +141,7 @@
def rshift(space, w_a, w_b):
'rshift(a, b) -- Same as a >> b.'
- return space.rshift(w_a, w_b)
+ return space.rshift(w_a, w_b)
# sequenceIncludes
@@ -150,7 +153,7 @@
def sub(space, w_a, w_b):
'sub(a, b) -- Same as a - b.'
- return space.sub(w_a, w_b)
+ return space.sub(w_a, w_b)
def truediv(space, w_a, w_b):
'truediv(a, b) -- Same as a / b when __future__.division is in effect.'
@@ -184,7 +187,7 @@
def ilshift(space, w_a, w_b):
'ilshift(a, b) -- Same as a <<= b.'
- return space.inplace_lshift(w_a, w_b)
+ return space.inplace_lshift(w_a, w_b)
def imod(space, w_a, w_b):
'imod(a, b) -- Same as a %= b.'
@@ -204,11 +207,11 @@
def irshift(space, w_a, w_b):
'irshift(a, b) -- Same as a >>= b.'
- return space.inplace_rshift(w_a, w_b)
+ return space.inplace_rshift(w_a, w_b)
def isub(space, w_a, w_b):
'isub(a, b) -- Same as a -= b.'
- return space.inplace_sub(w_a, w_b)
+ return space.inplace_sub(w_a, w_b)
def itruediv(space, w_a, w_b):
'itruediv(a, b) -- Same as a /= b when __future__.division is in effect.'
@@ -246,3 +249,33 @@
@unwrap_spec(default=int)
def _length_hint(space, w_iterable, default):
return space.wrap(space.length_hint(w_iterable, default))
+
+def compare_digest(space, w_a, w_b):
+ if (
+ space.isinstance_w(w_a, space.w_unicode) and
+ space.isinstance_w(w_b, space.w_unicode)
+ ):
+ return space.wrap(tscmp(space.unicode_w(w_a), space.unicode_w(w_b)))
+ if (
+ space.isinstance_w(w_a, space.w_unicode) or
+ space.isinstance_w(w_b, space.w_unicode)
+ ):
+ raise oefmt(
+ space.w_TypeError,
+ "unsupported operand types(s) or combination of types: '%N' and '%N'",
+ w_a,
+ w_b,
+ )
+ else:
+ return space.wrap(tscmp(space.bufferstr_w(w_a), space.bufferstr_w(w_b)))
+
+
+ at specialize.argtype(0, 1)
+def tscmp(a, b):
+ len_a = len(a)
+ len_b = len(b)
+ length = min(len(a), len(b))
+ res = len_a ^ len_b
+ for i in xrange(length):
+ res |= ord(a[i]) ^ ord(b[i])
+ return res == 0
diff --git a/pypy/module/operator/test/test_operator.py b/pypy/module/operator/test/test_operator.py
--- a/pypy/module/operator/test/test_operator.py
+++ b/pypy/module/operator/test/test_operator.py
@@ -15,7 +15,7 @@
assert a.get3("foobar") == "b"
assert a.getx(*(a,)) == 5
assert a.get3(obj="foobar") == "b"
-
+
def test_getter_multiple_gest(self):
import operator
@@ -197,3 +197,110 @@
assert operator.__index__(42) == 42
exc = raises(TypeError, operator.index, "abc")
assert str(exc.value) == "'str' object cannot be interpreted as an index"
+
+ def test_compare_digest(self):
+ import operator
+
+ # Testing input type exception handling
+ a, b = 100, 200
+ raises(TypeError, operator._compare_digest, a, b)
+ a, b = 100, b"foobar"
+ raises(TypeError, operator._compare_digest, a, b)
+ a, b = b"foobar", 200
+ raises(TypeError, operator._compare_digest, a, b)
+ a, b = u"foobar", b"foobar"
+ raises(TypeError, operator._compare_digest, a, b)
+ a, b = b"foobar", u"foobar"
+ raises(TypeError, operator._compare_digest, a, b)
+
+ # Testing bytes of different lengths
+ a, b = b"foobar", b"foo"
+ assert not operator._compare_digest(a, b)
+ a, b = b"\xde\xad\xbe\xef", b"\xde\xad"
+ assert not operator._compare_digest(a, b)
+
+ # Testing bytes of same lengths, different values
+ a, b = b"foobar", b"foobaz"
+ assert not operator._compare_digest(a, b)
+ a, b = b"\xde\xad\xbe\xef", b"\xab\xad\x1d\xea"
+ assert not operator._compare_digest(a, b)
+
+ # Testing bytes of same lengths, same values
+ a, b = b"foobar", b"foobar"
+ assert operator._compare_digest(a, b)
+ a, b = b"\xde\xad\xbe\xef", b"\xde\xad\xbe\xef"
+ assert operator._compare_digest(a, b)
+
+ # Testing bytearrays of same lengths, same values
+ a, b = bytearray(b"foobar"), bytearray(b"foobar")
+ assert operator._compare_digest(a, b)
+
+ # Testing bytearrays of diffeent lengths
+ a, b = bytearray(b"foobar"), bytearray(b"foo")
+ assert not operator._compare_digest(a, b)
+
+ # Testing bytearrays of same lengths, different values
+ a, b = bytearray(b"foobar"), bytearray(b"foobaz")
+ assert not operator._compare_digest(a, b)
+
+ # Testing byte and bytearray of same lengths, same values
+ a, b = bytearray(b"foobar"), b"foobar"
+ assert operator._compare_digest(a, b)
+ assert operator._compare_digest(b, a)
+
+ # Testing byte bytearray of diffeent lengths
+ a, b = bytearray(b"foobar"), b"foo"
+ assert not operator._compare_digest(a, b)
+ assert not operator._compare_digest(b, a)
+
+ # Testing byte and bytearray of same lengths, different values
+ a, b = bytearray(b"foobar"), b"foobaz"
+ assert not operator._compare_digest(a, b)
+ assert not operator._compare_digest(b, a)
+
+ # Testing str of same lengths
+ a, b = "foobar", "foobar"
+ assert operator._compare_digest(a, b)
+
+ # Testing str of diffeent lengths
+ a, b = "foo", "foobar"
+ assert not operator._compare_digest(a, b)
+
+ # Testing bytes of same lengths, different values
+ a, b = "foobar", "foobaz"
+ assert not operator._compare_digest(a, b)
+
+ # Testing error cases
+ a, b = u"foobar", b"foobar"
+ raises(TypeError, operator._compare_digest, a, b)
+ a, b = b"foobar", u"foobar"
+ raises(TypeError, operator._compare_digest, a, b)
+ a, b = b"foobar", 1
+ raises(TypeError, operator._compare_digest, a, b)
+ a, b = 100, 200
+ raises(TypeError, operator._compare_digest, a, b)
+ a, b = "fooä", "fooä"
+ assert operator._compare_digest(a, b)
+
+ # subclasses are supported by ignore __eq__
+ class mystr(str):
+ def __eq__(self, other):
+ return False
+
+ a, b = mystr("foobar"), mystr("foobar")
+ assert operator._compare_digest(a, b)
+ a, b = mystr("foobar"), "foobar"
+ assert operator._compare_digest(a, b)
+ a, b = mystr("foobar"), mystr("foobaz")
+ assert not operator._compare_digest(a, b)
+
+ class mybytes(bytes):
+ def __eq__(self, other):
+ return False
+
+ a, b = mybytes(b"foobar"), mybytes(b"foobar")
+ assert operator._compare_digest(a, b)
+ a, b = mybytes(b"foobar"), b"foobar"
+ assert operator._compare_digest(a, b)
+ a, b = mybytes(b"foobar"), mybytes(b"foobaz")
+ assert not operator._compare_digest(a, b)
More information about the pypy-commit
mailing list