Author: Hakan Ardo <ha...@debian.org> Branch: Changeset: r53083:49afda04d4ce Date: 2012-03-01 21:44 +0100 http://bitbucket.org/pypy/pypy/changeset/49afda04d4ce/
Log: hg merge diff --git a/pypy/interpreter/test/test_typedef.py b/pypy/interpreter/test/test_typedef.py --- a/pypy/interpreter/test/test_typedef.py +++ b/pypy/interpreter/test/test_typedef.py @@ -304,6 +304,42 @@ assert_method(w_o1, "c", True) assert_method(w_o2, "c", False) + def test_total_ordering(self): + class W_SomeType(Wrappable): + def __init__(self, space, x): + self.space = space + self.x = x + + def descr__lt(self, w_other): + assert isinstance(w_other, W_SomeType) + return self.space.wrap(self.x < w_other.x) + + def descr__eq(self, w_other): + assert isinstance(w_other, W_SomeType) + return self.space.wrap(self.x == w_other.x) + + W_SomeType.typedef = typedef.TypeDef( + 'some_type', + __total_ordering__ = 'auto', + __lt__ = interp2app(W_SomeType.descr__lt), + __eq__ = interp2app(W_SomeType.descr__eq), + ) + space = self.space + w_b = space.wrap(W_SomeType(space, 2)) + w_c = space.wrap(W_SomeType(space, 2)) + w_a = space.wrap(W_SomeType(space, 1)) + # explicitly defined + assert space.is_true(space.lt(w_a, w_b)) + assert not space.is_true(space.eq(w_a, w_b)) + assert space.is_true(space.eq(w_b, w_c)) + # automatically defined + assert space.is_true(space.le(w_a, w_b)) + assert space.is_true(space.le(w_b, w_c)) + assert space.is_true(space.gt(w_b, w_a)) + assert space.is_true(space.ge(w_b, w_a)) + assert space.is_true(space.ge(w_b, w_c)) + assert space.is_true(space.ne(w_a, w_b)) + assert not space.is_true(space.ne(w_b, w_c)) class AppTestTypeDef: diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -12,7 +12,7 @@ from pypy.rlib.jit import promote class TypeDef: - def __init__(self, __name, __base=None, **rawdict): + def __init__(self, __name, __base=None, __total_ordering__=None, **rawdict): "NOT_RPYTHON: initialization-time only" self.name = __name if __base is None: @@ -34,6 +34,9 @@ # xxx used by faking self.fakedcpytype = None self.add_entries(**rawdict) + assert __total_ordering__ in (None, 'auto'), "Unknown value for __total_ordering" + if __total_ordering__ == 'auto': + self.auto_total_ordering() def add_entries(self, **rawdict): # xxx fix the names of the methods to match what app-level expects @@ -41,7 +44,15 @@ if isinstance(value, (interp2app, GetSetProperty)): value.name = key self.rawdict.update(rawdict) - + + def auto_total_ordering(self): + assert '__lt__' in self.rawdict, "__total_ordering='auto' requires __lt__" + assert '__eq__' in self.rawdict, "__total_ordering='auto' requires __eq__" + self.add_entries(__le__ = auto__le__, + __gt__ = auto__gt__, + __ge__ = auto__ge__, + __ne__ = auto__ne__) + def _freeze_(self): # hint for the annotator: track individual constant instances of TypeDef return True @@ -50,6 +61,26 @@ return "<%s name=%r>" % (self.__class__.__name__, self.name) +# generic special cmp methods defined on top of __lt__ and __eq__, used by +# automatic total ordering + +@interp2app +def auto__le__(space, w_self, w_other): + return space.not_(space.lt(w_other, w_self)) + +@interp2app +def auto__gt__(space, w_self, w_other): + return space.lt(w_other, w_self) + +@interp2app +def auto__ge__(space, w_self, w_other): + return space.not_(space.lt(w_self, w_other)) + +@interp2app +def auto__ne__(space, w_self, w_other): + return space.not_(space.eq(w_self, w_other)) + + # ____________________________________________________________ # Hash support diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -266,6 +266,38 @@ res = self.cpu.get_latest_value_int(0) assert res == 20 + def test_compile_big_bridge_out_of_small_loop(self): + i0 = BoxInt() + faildescr1 = BasicFailDescr(1) + looptoken = JitCellToken() + operations = [ + ResOperation(rop.GUARD_FALSE, [i0], None, descr=faildescr1), + ResOperation(rop.FINISH, [], None, descr=BasicFailDescr(2)), + ] + inputargs = [i0] + operations[0].setfailargs([i0]) + self.cpu.compile_loop(inputargs, operations, looptoken) + + i1list = [BoxInt() for i in range(1000)] + bridge = [] + iprev = i0 + for i1 in i1list: + bridge.append(ResOperation(rop.INT_ADD, [iprev, ConstInt(1)], i1)) + iprev = i1 + bridge.append(ResOperation(rop.GUARD_FALSE, [i0], None, + descr=BasicFailDescr(3))) + bridge.append(ResOperation(rop.FINISH, [], None, + descr=BasicFailDescr(4))) + bridge[-2].setfailargs(i1list) + + self.cpu.compile_bridge(faildescr1, [i0], bridge, looptoken) + + fail = self.cpu.execute_token(looptoken, 1) + assert fail.identifier == 3 + for i in range(1000): + res = self.cpu.get_latest_value_int(i) + assert res == 2 + i + def test_get_latest_value_count(self): i0 = BoxInt() i1 = BoxInt() diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -326,8 +326,11 @@ try: space.call_method(w_iobase, 'flush') except OperationError, e: - # if it's an IOError, ignore it - if not e.match(space, space.w_IOError): + # if it's an IOError or ValueError, ignore it (ValueError is + # raised if by chance we are trying to flush a file which has + # already been closed) + if not (e.match(space, space.w_IOError) or + e.match(space, space.w_ValueError)): raise diff --git a/pypy/module/_io/test/test_fileio.py b/pypy/module/_io/test/test_fileio.py --- a/pypy/module/_io/test/test_fileio.py +++ b/pypy/module/_io/test/test_fileio.py @@ -178,7 +178,7 @@ space.finish() assert tmpfile.read() == '42' -def test_flush_at_exit_IOError(): +def test_flush_at_exit_IOError_and_ValueError(): from pypy import conftest from pypy.tool.option import make_config, make_objspace @@ -190,7 +190,12 @@ def flush(self): raise IOError + class MyStream2(io.IOBase): + def flush(self): + raise ValueError + s = MyStream() + s2 = MyStream2() import sys; sys._keepalivesomewhereobscure = s """) space.finish() # the IOError has been ignored diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -583,14 +583,32 @@ raise OperationError(space.w_ValueError, space.wrap(msg)) # Compare methods - def cmp__Array_ANY(space, self, other): + def _cmp_impl(space, self, other, space_fn): if isinstance(other, W_ArrayBase): w_lst1 = array_tolist__Array(space, self) w_lst2 = space.call_method(other, 'tolist') - return space.cmp(w_lst1, w_lst2) + return space_fn(w_lst1, w_lst2) else: return space.w_NotImplemented + def eq__Array_ANY(space, self, other): + return _cmp_impl(space, self, other, space.eq) + + def ne__Array_ANY(space, self, other): + return _cmp_impl(space, self, other, space.ne) + + def lt__Array_ANY(space, self, other): + return _cmp_impl(space, self, other, space.lt) + + def le__Array_ANY(space, self, other): + return _cmp_impl(space, self, other, space.le) + + def gt__Array_ANY(space, self, other): + return _cmp_impl(space, self, other, space.gt) + + def ge__Array_ANY(space, self, other): + return _cmp_impl(space, self, other, space.ge) + # Misc methods def buffer__Array(space, self): diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -536,12 +536,6 @@ assert (a >= c) is False assert (c >= a) is True - assert cmp(a, a) == 0 - assert cmp(a, b) == 0 - assert cmp(a, c) < 0 - assert cmp(b, a) == 0 - assert cmp(c, a) > 0 - def test_reduce(self): import pickle a = self.array('i', [1, 2, 3]) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit