Author: Antonio Cuni <anto.c...@gmail.com> Branch: py3k Changeset: r53063:f9a6a7baf321 Date: 2012-03-01 16:42 +0100 http://bitbucket.org/pypy/pypy/changeset/f9a6a7baf321/
Log: hg merge default 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,27 @@ 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.or_(space.lt(w_self, w_other), + space.eq(w_self, w_other)) + +@interp2app +def auto__gt__(space, w_self, w_other): + return space.not_(space.le(w_self, w_other)) + +@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/x86/test/test_gc_integration.py b/pypy/jit/backend/x86/test/test_gc_integration.py --- a/pypy/jit/backend/x86/test/test_gc_integration.py +++ b/pypy/jit/backend/x86/test/test_gc_integration.py @@ -184,6 +184,8 @@ self.addrs[1] = self.addrs[0] + 64 self.calls = [] def malloc_slowpath(size): + if self.gcrootmap is not None: # hook + self.gcrootmap.hook_malloc_slowpath() self.calls.append(size) # reset the nursery nadr = rffi.cast(lltype.Signed, self.nursery) @@ -257,3 +259,218 @@ assert gc_ll_descr.addrs[0] == nurs_adr + 24 # this should call slow path once assert gc_ll_descr.calls == [24] + + def test_save_regs_around_malloc(self): + S1 = lltype.GcStruct('S1') + S2 = lltype.GcStruct('S2', ('s0', lltype.Ptr(S1)), + ('s1', lltype.Ptr(S1)), + ('s2', lltype.Ptr(S1)), + ('s3', lltype.Ptr(S1)), + ('s4', lltype.Ptr(S1)), + ('s5', lltype.Ptr(S1)), + ('s6', lltype.Ptr(S1)), + ('s7', lltype.Ptr(S1)), + ('s8', lltype.Ptr(S1)), + ('s9', lltype.Ptr(S1)), + ('s10', lltype.Ptr(S1)), + ('s11', lltype.Ptr(S1)), + ('s12', lltype.Ptr(S1)), + ('s13', lltype.Ptr(S1)), + ('s14', lltype.Ptr(S1)), + ('s15', lltype.Ptr(S1))) + cpu = self.cpu + self.namespace = self.namespace.copy() + for i in range(16): + self.namespace['ds%i' % i] = cpu.fielddescrof(S2, 's%d' % i) + ops = ''' + [p0] + p1 = getfield_gc(p0, descr=ds0) + p2 = getfield_gc(p0, descr=ds1) + p3 = getfield_gc(p0, descr=ds2) + p4 = getfield_gc(p0, descr=ds3) + p5 = getfield_gc(p0, descr=ds4) + p6 = getfield_gc(p0, descr=ds5) + p7 = getfield_gc(p0, descr=ds6) + p8 = getfield_gc(p0, descr=ds7) + p9 = getfield_gc(p0, descr=ds8) + p10 = getfield_gc(p0, descr=ds9) + p11 = getfield_gc(p0, descr=ds10) + p12 = getfield_gc(p0, descr=ds11) + p13 = getfield_gc(p0, descr=ds12) + p14 = getfield_gc(p0, descr=ds13) + p15 = getfield_gc(p0, descr=ds14) + p16 = getfield_gc(p0, descr=ds15) + # + # now all registers are in use + p17 = call_malloc_nursery(40) + p18 = call_malloc_nursery(40) # overflow + # + finish(p1, p2, p3, p4, p5, p6, p7, p8, \ + p9, p10, p11, p12, p13, p14, p15, p16) + ''' + s2 = lltype.malloc(S2) + for i in range(16): + setattr(s2, 's%d' % i, lltype.malloc(S1)) + s2ref = lltype.cast_opaque_ptr(llmemory.GCREF, s2) + # + self.interpret(ops, [s2ref]) + gc_ll_descr = cpu.gc_ll_descr + gc_ll_descr.check_nothing_in_nursery() + assert gc_ll_descr.calls == [40] + # check the returned pointers + for i in range(16): + s1ref = self.cpu.get_latest_value_ref(i) + s1 = lltype.cast_opaque_ptr(lltype.Ptr(S1), s1ref) + assert s1 == getattr(s2, 's%d' % i) + + +class MockShadowStackRootMap(MockGcRootMap): + is_shadow_stack = True + MARKER_FRAME = 88 # this marker follows the frame addr + S1 = lltype.GcStruct('S1') + + def __init__(self): + self.addrs = lltype.malloc(rffi.CArray(lltype.Signed), 20, + flavor='raw') + # root_stack_top + self.addrs[0] = rffi.cast(lltype.Signed, self.addrs) + 3*WORD + # random stuff + self.addrs[1] = 123456 + self.addrs[2] = 654321 + self.check_initial_and_final_state() + self.callshapes = {} + self.should_see = [] + + def check_initial_and_final_state(self): + assert self.addrs[0] == rffi.cast(lltype.Signed, self.addrs) + 3*WORD + assert self.addrs[1] == 123456 + assert self.addrs[2] == 654321 + + def get_root_stack_top_addr(self): + return rffi.cast(lltype.Signed, self.addrs) + + def compress_callshape(self, shape, datablockwrapper): + assert shape[0] == 'shape' + return ['compressed'] + shape[1:] + + def write_callshape(self, mark, force_index): + assert mark[0] == 'compressed' + assert force_index not in self.callshapes + assert force_index == 42 + len(self.callshapes) + self.callshapes[force_index] = mark + + def hook_malloc_slowpath(self): + num_entries = self.addrs[0] - rffi.cast(lltype.Signed, self.addrs) + assert num_entries == 5*WORD # 3 initially, plus 2 by the asm frame + assert self.addrs[1] == 123456 # unchanged + assert self.addrs[2] == 654321 # unchanged + frame_addr = self.addrs[3] # pushed by the asm frame + assert self.addrs[4] == self.MARKER_FRAME # pushed by the asm frame + # + from pypy.jit.backend.x86.arch import FORCE_INDEX_OFS + addr = rffi.cast(rffi.CArrayPtr(lltype.Signed), + frame_addr + FORCE_INDEX_OFS) + force_index = addr[0] + assert force_index == 43 # in this test: the 2nd call_malloc_nursery + # + # The callshapes[43] saved above should list addresses both in the + # COPY_AREA and in the "normal" stack, where all the 16 values p1-p16 + # of test_save_regs_at_correct_place should have been stored. Here + # we replace them with new addresses, to emulate a moving GC. + shape = self.callshapes[force_index] + assert len(shape[1:]) == len(self.should_see) + new_objects = [None] * len(self.should_see) + for ofs in shape[1:]: + assert isinstance(ofs, int) # not a register at all here + addr = rffi.cast(rffi.CArrayPtr(lltype.Signed), frame_addr + ofs) + contains = addr[0] + for j in range(len(self.should_see)): + obj = self.should_see[j] + if contains == rffi.cast(lltype.Signed, obj): + assert new_objects[j] is None # duplicate? + break + else: + assert 0 # the value read from the stack looks random? + new_objects[j] = lltype.malloc(self.S1) + addr[0] = rffi.cast(lltype.Signed, new_objects[j]) + self.should_see[:] = new_objects + + +class TestMallocShadowStack(BaseTestRegalloc): + + def setup_method(self, method): + cpu = CPU(None, None) + cpu.gc_ll_descr = GCDescrFastpathMalloc() + cpu.gc_ll_descr.gcrootmap = MockShadowStackRootMap() + cpu.setup_once() + for i in range(42): + cpu.reserve_some_free_fail_descr_number() + self.cpu = cpu + + def test_save_regs_at_correct_place(self): + cpu = self.cpu + gc_ll_descr = cpu.gc_ll_descr + S1 = gc_ll_descr.gcrootmap.S1 + S2 = lltype.GcStruct('S2', ('s0', lltype.Ptr(S1)), + ('s1', lltype.Ptr(S1)), + ('s2', lltype.Ptr(S1)), + ('s3', lltype.Ptr(S1)), + ('s4', lltype.Ptr(S1)), + ('s5', lltype.Ptr(S1)), + ('s6', lltype.Ptr(S1)), + ('s7', lltype.Ptr(S1)), + ('s8', lltype.Ptr(S1)), + ('s9', lltype.Ptr(S1)), + ('s10', lltype.Ptr(S1)), + ('s11', lltype.Ptr(S1)), + ('s12', lltype.Ptr(S1)), + ('s13', lltype.Ptr(S1)), + ('s14', lltype.Ptr(S1)), + ('s15', lltype.Ptr(S1))) + self.namespace = self.namespace.copy() + for i in range(16): + self.namespace['ds%i' % i] = cpu.fielddescrof(S2, 's%d' % i) + ops = ''' + [p0] + p1 = getfield_gc(p0, descr=ds0) + p2 = getfield_gc(p0, descr=ds1) + p3 = getfield_gc(p0, descr=ds2) + p4 = getfield_gc(p0, descr=ds3) + p5 = getfield_gc(p0, descr=ds4) + p6 = getfield_gc(p0, descr=ds5) + p7 = getfield_gc(p0, descr=ds6) + p8 = getfield_gc(p0, descr=ds7) + p9 = getfield_gc(p0, descr=ds8) + p10 = getfield_gc(p0, descr=ds9) + p11 = getfield_gc(p0, descr=ds10) + p12 = getfield_gc(p0, descr=ds11) + p13 = getfield_gc(p0, descr=ds12) + p14 = getfield_gc(p0, descr=ds13) + p15 = getfield_gc(p0, descr=ds14) + p16 = getfield_gc(p0, descr=ds15) + # + # now all registers are in use + p17 = call_malloc_nursery(40) + p18 = call_malloc_nursery(40) # overflow + # + finish(p1, p2, p3, p4, p5, p6, p7, p8, \ + p9, p10, p11, p12, p13, p14, p15, p16) + ''' + s2 = lltype.malloc(S2) + for i in range(16): + s1 = lltype.malloc(S1) + setattr(s2, 's%d' % i, s1) + gc_ll_descr.gcrootmap.should_see.append(s1) + s2ref = lltype.cast_opaque_ptr(llmemory.GCREF, s2) + # + self.interpret(ops, [s2ref]) + gc_ll_descr.check_nothing_in_nursery() + assert gc_ll_descr.calls == [40] + gc_ll_descr.gcrootmap.check_initial_and_final_state() + # check the returned pointers + for i in range(16): + s1ref = self.cpu.get_latest_value_ref(i) + s1 = lltype.cast_opaque_ptr(lltype.Ptr(S1), s1ref) + for j in range(16): + assert s1 != getattr(s2, 's%d' % j) + assert s1 == gc_ll_descr.gcrootmap.should_see[i] diff --git a/pypy/jit/metainterp/optimizeopt/test/test_multilabel.py b/pypy/jit/metainterp/optimizeopt/test/test_multilabel.py --- a/pypy/jit/metainterp/optimizeopt/test/test_multilabel.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_multilabel.py @@ -398,48 +398,38 @@ with raises(InvalidLoop): self.optimize_loop(ops, ops) - def test_maybe_issue1045_related(self): + def test_issue1045(self): ops = """ - [p8] - p54 = getfield_gc(p8, descr=valuedescr) - mark_opaque_ptr(p54) - i55 = getfield_gc(p54, descr=nextdescr) - p57 = new_with_vtable(ConstClass(node_vtable)) - setfield_gc(p57, i55, descr=otherdescr) - p69 = new_with_vtable(ConstClass(node_vtable)) - setfield_gc(p69, i55, descr=otherdescr) - i71 = int_eq(i55, -9223372036854775808) - guard_false(i71) [] - i73 = int_mod(i55, 2) - i75 = int_rshift(i73, 63) - i76 = int_and(2, i75) - i77 = int_add(i73, i76) - p79 = new_with_vtable(ConstClass(node_vtable)) - setfield_gc(p79, i77, descr=otherdescr) - i81 = int_eq(i77, 1) - guard_false(i81) [] - i0 = int_ge(i55, 1) - guard_true(i0) [] - label(p57) - jump(p57) - """ - expected = """ - [p8] - p54 = getfield_gc(p8, descr=valuedescr) - i55 = getfield_gc(p54, descr=nextdescr) - i71 = int_eq(i55, -9223372036854775808) - guard_false(i71) [] + [i55] i73 = int_mod(i55, 2) i75 = int_rshift(i73, 63) i76 = int_and(2, i75) i77 = int_add(i73, i76) i81 = int_eq(i77, 1) - guard_false(i81) [] i0 = int_ge(i55, 1) guard_true(i0) [] label(i55) + i3 = int_mod(i55, 2) + i5 = int_rshift(i3, 63) + i6 = int_and(2, i5) + i7 = int_add(i3, i6) + i8 = int_eq(i7, 1) + escape(i8) jump(i55) """ + expected = """ + [i55] + i73 = int_mod(i55, 2) + i75 = int_rshift(i73, 63) + i76 = int_and(2, i75) + i77 = int_add(i73, i76) + i81 = int_eq(i77, 1) + i0 = int_ge(i55, 1) + guard_true(i0) [] + label(i55, i81) + escape(i81) + jump(i55, i81) + """ self.optimize_loop(ops, expected) class OptRenameStrlen(Optimization): @@ -467,7 +457,7 @@ metainterp_sd = FakeMetaInterpStaticData(self.cpu) optimize_unroll(metainterp_sd, loop, [OptRenameStrlen(), OptPure()], True) - def test_optimizer_renaming_boxes(self): + def test_optimizer_renaming_boxes1(self): ops = """ [p1] i1 = strlen(p1) diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -260,7 +260,7 @@ if op and op.result: preamble_value = exported_state.exported_values[op.result] value = self.optimizer.getvalue(op.result) - if not value.is_virtual(): + if not value.is_virtual() and not value.is_constant(): imp = ValueImporter(self, preamble_value, op) self.optimizer.importable_values[value] = imp newvalue = self.optimizer.getvalue(op.result) @@ -268,7 +268,9 @@ # note that emitting here SAME_AS should not happen, but # in case it does, we would prefer to be suboptimal in asm # to a fatal RPython exception. - if newresult is not op.result and not newvalue.is_constant(): + if newresult is not op.result and \ + not self.short_boxes.has_producer(newresult) and \ + not newvalue.is_constant(): op = ResOperation(rop.SAME_AS, [op.result], newresult) self.optimizer._newoperations.append(op) if self.optimizer.loop.logops: diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -2349,7 +2349,7 @@ # warmstate.py. virtualizable_box = self.virtualizable_boxes[-1] virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box) - assert not vinfo.gettoken(virtualizable) + assert not vinfo.is_token_nonnull_gcref(virtualizable) # fill the virtualizable with the local boxes self.synchronize_virtualizable() # diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py --- a/pypy/jit/metainterp/resume.py +++ b/pypy/jit/metainterp/resume.py @@ -1101,14 +1101,14 @@ virtualizable = self.decode_ref(numb.nums[index]) if self.resume_after_guard_not_forced == 1: # in the middle of handle_async_forcing() - assert vinfo.gettoken(virtualizable) - vinfo.settoken(virtualizable, vinfo.TOKEN_NONE) + assert vinfo.is_token_nonnull_gcref(virtualizable) + vinfo.reset_token_gcref(virtualizable) else: # just jumped away from assembler (case 4 in the comment in # virtualizable.py) into tracing (case 2); check that vable_token # is and stays 0. Note the call to reset_vable_token() in # warmstate.py. - assert not vinfo.gettoken(virtualizable) + assert not vinfo.is_token_nonnull_gcref(virtualizable) return vinfo.write_from_resume_data_partial(virtualizable, self, numb) def load_value_of_type(self, TYPE, tagged): diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py --- a/pypy/jit/metainterp/test/test_ajit.py +++ b/pypy/jit/metainterp/test/test_ajit.py @@ -144,7 +144,7 @@ 'int_mul': 1, 'guard_true': 2, 'int_sub': 2}) - def test_loop_invariant_mul_ovf(self): + def test_loop_invariant_mul_ovf1(self): myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x']) def f(x, y): res = 0 @@ -235,6 +235,65 @@ 'guard_true': 4, 'int_sub': 4, 'jump': 3, 'int_mul': 3, 'int_add': 4}) + def test_loop_invariant_mul_ovf2(self): + myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x']) + def f(x, y): + res = 0 + while y > 0: + myjitdriver.can_enter_jit(x=x, y=y, res=res) + myjitdriver.jit_merge_point(x=x, y=y, res=res) + b = y * 2 + try: + res += ovfcheck(x * x) + b + except OverflowError: + res += 1 + y -= 1 + return res + res = self.meta_interp(f, [sys.maxint, 7]) + assert res == f(sys.maxint, 7) + self.check_trace_count(1) + res = self.meta_interp(f, [6, 7]) + assert res == 308 + + def test_loop_invariant_mul_bridge_ovf1(self): + myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x1', 'x2']) + def f(x1, x2, y): + res = 0 + while y > 0: + myjitdriver.can_enter_jit(x1=x1, x2=x2, y=y, res=res) + myjitdriver.jit_merge_point(x1=x1, x2=x2, y=y, res=res) + try: + res += ovfcheck(x1 * x1) + except OverflowError: + res += 1 + if y<32 and (y>>2)&1==0: + x1, x2 = x2, x1 + y -= 1 + return res + res = self.meta_interp(f, [6, sys.maxint, 48]) + assert res == f(6, sys.maxint, 48) + + def test_loop_invariant_mul_bridge_ovf2(self): + myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x1', 'x2', 'n']) + def f(x1, x2, n, y): + res = 0 + while y > 0: + myjitdriver.can_enter_jit(x1=x1, x2=x2, y=y, res=res, n=n) + myjitdriver.jit_merge_point(x1=x1, x2=x2, y=y, res=res, n=n) + try: + res += ovfcheck(x1 * x1) + except OverflowError: + res += 1 + y -= 1 + if y&4 == 0: + x1, x2 = x2, x1 + return res + res = self.meta_interp(f, [sys.maxint, 6, 32, 48]) + assert res == f(sys.maxint, 6, 32, 48) + res = self.meta_interp(f, [6, sys.maxint, 32, 48]) + assert res == f(6, sys.maxint, 32, 48) + + def test_loop_invariant_intbox(self): myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x']) class I: diff --git a/pypy/jit/metainterp/virtualizable.py b/pypy/jit/metainterp/virtualizable.py --- a/pypy/jit/metainterp/virtualizable.py +++ b/pypy/jit/metainterp/virtualizable.py @@ -262,15 +262,15 @@ force_now._dont_inline_ = True self.force_now = force_now - def gettoken(virtualizable): + def is_token_nonnull_gcref(virtualizable): virtualizable = cast_gcref_to_vtype(virtualizable) - return virtualizable.vable_token - self.gettoken = gettoken + return bool(virtualizable.vable_token) + self.is_token_nonnull_gcref = is_token_nonnull_gcref - def settoken(virtualizable, token): + def reset_token_gcref(virtualizable): virtualizable = cast_gcref_to_vtype(virtualizable) - virtualizable.vable_token = token - self.settoken = settoken + virtualizable.vable_token = VirtualizableInfo.TOKEN_NONE + self.reset_token_gcref = reset_token_gcref def _freeze_(self): return True 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 @@ -330,8 +330,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/test_lib_pypy/test_collections.py b/pypy/module/test_lib_pypy/test_collections.py --- a/pypy/module/test_lib_pypy/test_collections.py +++ b/pypy/module/test_lib_pypy/test_collections.py @@ -6,7 +6,7 @@ from pypy.conftest import gettestobjspace -class AppTestcStringIO: +class AppTestCollections: def test_copy(self): import _collections def f(): _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit