Author: Philip Jenvey <pjen...@underboss.org> Branch: py3k Changeset: r64693:699f19dc7cde Date: 2013-05-31 13:29 -0700 http://bitbucket.org/pypy/pypy/changeset/699f19dc7cde/
Log: merge default diff --git a/lib-python/2.7/socket.py b/lib-python/2.7/socket.py --- a/lib-python/2.7/socket.py +++ b/lib-python/2.7/socket.py @@ -96,6 +96,7 @@ _realsocket = socket +_type = type # WSA error codes if sys.platform.lower().startswith("win"): @@ -173,31 +174,37 @@ __doc__ = _realsocket.__doc__ + __slots__ = ["_sock", "__weakref__"] + def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None): if _sock is None: _sock = _realsocket(family, type, proto) + elif _type(_sock) is _realsocket: + _sock._reuse() + # PyPy note about refcounting: implemented with _reuse()/_drop() + # on the class '_socket.socket'. Python 3 did it differently + # with a reference counter on this class 'socket._socketobject' + # instead, but it is a less compatible change (breaks eventlet). self._sock = _sock - self._io_refs = 0 - self._closed = False def send(self, data, flags=0): - return self._sock.send(data, flags=flags) + return self._sock.send(data, flags) send.__doc__ = _realsocket.send.__doc__ def recv(self, buffersize, flags=0): - return self._sock.recv(buffersize, flags=flags) + return self._sock.recv(buffersize, flags) recv.__doc__ = _realsocket.recv.__doc__ def recv_into(self, buffer, nbytes=0, flags=0): - return self._sock.recv_into(buffer, nbytes=nbytes, flags=flags) + return self._sock.recv_into(buffer, nbytes, flags) recv_into.__doc__ = _realsocket.recv_into.__doc__ def recvfrom(self, buffersize, flags=0): - return self._sock.recvfrom(buffersize, flags=flags) + return self._sock.recvfrom(buffersize, flags) recvfrom.__doc__ = _realsocket.recvfrom.__doc__ def recvfrom_into(self, buffer, nbytes=0, flags=0): - return self._sock.recvfrom_into(buffer, nbytes=nbytes, flags=flags) + return self._sock.recvfrom_into(buffer, nbytes, flags) recvfrom_into.__doc__ = _realsocket.recvfrom_into.__doc__ def sendto(self, data, param2, param3=None): @@ -208,13 +215,17 @@ sendto.__doc__ = _realsocket.sendto.__doc__ def close(self): - # This function should not reference any globals. See issue #808164. + s = self._sock + if type(s) is _realsocket: + s._drop() self._sock = _closedsocket() close.__doc__ = _realsocket.close.__doc__ def accept(self): sock, addr = self._sock.accept() - return _socketobject(_sock=sock), addr + sockobj = _socketobject(_sock=sock) + sock._drop() # already a copy in the _socketobject() + return sockobj, addr accept.__doc__ = _realsocket.accept.__doc__ def dup(self): @@ -228,24 +239,7 @@ Return a regular file object corresponding to the socket. The mode and bufsize arguments are as for the built-in open() function.""" - self._io_refs += 1 - return _fileobject(self, mode, bufsize) - - def _decref_socketios(self): - if self._io_refs > 0: - self._io_refs -= 1 - if self._closed: - self.close() - - def _real_close(self): - # This function should not reference any globals. See issue #808164. - self._sock.close() - - def close(self): - # This function should not reference any globals. See issue #808164. - self._closed = True - if self._io_refs <= 0: - self._real_close() + return _fileobject(self._sock, mode, bufsize) family = property(lambda self: self._sock.family, doc="the socket family") type = property(lambda self: self._sock.type, doc="the socket type") @@ -286,6 +280,8 @@ "_close"] def __init__(self, sock, mode='rb', bufsize=-1, close=False): + if type(sock) is _realsocket: + sock._reuse() self._sock = sock self.mode = mode # Not actually used in this version if bufsize < 0: @@ -320,16 +316,11 @@ if self._sock: self.flush() finally: - if self._sock: - if self._close: - self._sock.close() - else: - try: - self._sock._decref_socketios() - except AttributeError: - pass # bah, someone built a _fileobject manually - # with some unexpected replacement of the - # _socketobject class + s = self._sock + if type(s) is _realsocket: + s._drop() + if self._close: + self._sock.close() self._sock = None def __del__(self): diff --git a/lib_pypy/greenlet.egg-info b/lib_pypy/greenlet.egg-info new file mode 100644 --- /dev/null +++ b/lib_pypy/greenlet.egg-info @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: greenlet +Version: 0.4.0 +Summary: Lightweight in-process concurrent programming +Home-page: https://github.com/python-greenlet/greenlet +Author: Ralf Schmitt (for CPython), PyPy team +Author-email: pypy-...@python.org +License: MIT License +Description: UNKNOWN +Platform: UNKNOWN diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -32,13 +32,12 @@ "rctime" , "select", "zipimport", "_lsprof", "crypt", "signal", "_rawffi", "termios", "zlib", "bz2", "struct", "_hashlib", "_md5", "_minimal_curses", - "thread", "itertools", "pyexpat", "_ssl", "array", + "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array", "binascii", "_multiprocessing", '_warnings', "_collections", "_multibytecodec", "_ffi", "_continuation", "_csv", "_cffi_backend", "_posixsubprocess", # "cppyy", "micronumpy", ] -# disabled until problems are fixed )) translation_modules = default_modules.copy() diff --git a/pypy/doc/rffi.rst b/pypy/doc/rffi.rst --- a/pypy/doc/rffi.rst +++ b/pypy/doc/rffi.rst @@ -5,7 +5,7 @@ Purpose ------- -This document describes an FFI for RPython language, concentrating +This document describes an FFI for the RPython language, concentrating on low-level backends like C. It describes how to declare and call low-level (C) functions from RPython level. @@ -50,7 +50,7 @@ ------ In rffi_ there are various declared types for C-structures, like CCHARP -(char*), SIZE_T (size_t) and others. refer to file for details. +(char*), SIZE_T (size_t) and others. Refer to file for details. Instances of non-primitive types must be alloced by hand, with call to lltype.malloc, and freed by lltype.free both with keyword argument flavor='raw'. There are several helpers like string -> char* diff --git a/pypy/module/_ffi/test/test_funcptr.py b/pypy/module/_ffi/test/test_funcptr.py --- a/pypy/module/_ffi/test/test_funcptr.py +++ b/pypy/module/_ffi/test/test_funcptr.py @@ -46,6 +46,7 @@ libm = CDLL(libm_name) pow = libm.getpointer('pow', [], types.void) pow_addr = rffi.cast(rffi.LONG, pow.funcsym) + cls._libm = libm # otherwise it gets unloaded - argh! cls.w_pow_addr = space.wrap(pow_addr) class AppTestFFI(BaseAppTestFFI): diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -25,7 +25,7 @@ from pypy.objspace.std.sliceobject import W_SliceObject from pypy.module.__builtin__.descriptor import W_Property from pypy.module.__builtin__.interp_memoryview import W_MemoryView -from rpython.rlib.entrypoint import entrypoint +from rpython.rlib.entrypoint import entrypoint_lowlevel from rpython.rlib.rposix import is_valid_fd, validate_fd from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.objectmodel import specialize @@ -545,38 +545,37 @@ def make_wrapper(space, callable): "NOT_RPYTHON" names = callable.api_func.argnames - argtypes = callable.api_func.argtypes - is_wrapped_list = [name.startswith("w_") for name in names] + argtypes_enum_ui = unrolling_iterable(enumerate(zip(callable.api_func.argtypes, + [name.startswith("w_") for name in names]))) fatal_value = callable.api_func.restype._defl() - lines = [] - for i, (argtype, is_wrapped) in enumerate(zip(argtypes, is_wrapped_list)): - if is_PyObject(argtype) and is_wrapped: - new_lines = [ - 'if %(arg)s:', - ' %(arg)s = from_ref(space, rffi.cast(PyObject, %(arg)s))', - 'else:', - ' %(arg)s = None', - ] - for j in range(len(new_lines)): - new_lines[j] = new_lines[j] % {'arg': 'arg%d' % i} - lines += new_lines - middle = '\n '.join(lines) - arg_spec = ", ".join(["arg%d" % i for i in range(len(argtypes))]) - - source = py.code.Source(""" - def wrapper(%(args)s): + @specialize.ll() + def wrapper(*args): from pypy.module.cpyext.pyobject import make_ref, from_ref from pypy.module.cpyext.pyobject import Reference + # we hope that malloc removal removes the newtuple() that is + # inserted exactly here by the varargs specializer + rffi.stackcounter.stacks_counter += 1 + llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py retval = fatal_value boxed_args = () try: if not we_are_translated() and DEBUG_WRAPPER: print >>sys.stderr, callable, + assert len(args) == len(callable.api_func.argtypes) + for i, (typ, is_wrapped) in argtypes_enum_ui: + arg = args[i] + if is_PyObject(typ) and is_wrapped: + if arg: + arg_conv = from_ref(space, rffi.cast(PyObject, arg)) + else: + arg_conv = None + else: + arg_conv = arg + boxed_args += (arg_conv, ) state = space.fromcache(State) - %(middle)s try: - result = callable(space, %(args)s) + result = callable(space, *boxed_args) if not we_are_translated() and DEBUG_WRAPPER: print >>sys.stderr, " DONE" except OperationError, e: @@ -598,8 +597,8 @@ if failed: error_value = callable.api_func.error_value if error_value is CANNOT_FAIL: - raise SystemError("The function '%%s' was not supposed to fail" - %% (callable.__name__,)) + raise SystemError("The function '%s' was not supposed to fail" + % (callable.__name__,)) retval = error_value elif is_PyObject(callable.api_func.restype): @@ -626,13 +625,8 @@ else: print str(e) pypy_debug_catch_fatal_exception() + rffi.stackcounter.stacks_counter -= 1 return retval - """ % {"middle": middle, "args": arg_spec}) - d = {} - d.update(locals()) - d.update(globals()) - exec source.compile() in d - wrapper = d['wrapper'] callable._always_inline_ = 'try' wrapper.__name__ = "wrapper for %r" % (callable, ) return wrapper @@ -1027,7 +1021,7 @@ export_struct(name, struct) for name, func in FUNCTIONS.iteritems(): - deco = entrypoint("cpyext", func.argtypes, name) + deco = entrypoint_lowlevel("cpyext", func.argtypes, name, relax=True) deco(func.get_wrapper(space)) setup_init_functions(eci, translating=True) diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py --- a/pypy/module/cpyext/slotdefs.py +++ b/pypy/module/cpyext/slotdefs.py @@ -342,7 +342,7 @@ return @cpython_api([PyObject, PyObject, PyObject], rffi.INT_real, - error=-1, external=False) + error=-1, external=True) # XXX should not be exported @func_renamer("cpyext_tp_setattro_%s" % (typedef.name,)) def slot_tp_setattro(space, w_self, w_name, w_value): if w_value is not None: diff --git a/pypy/module/micronumpy/test/test_scalar.py b/pypy/module/micronumpy/test/test_scalar.py --- a/pypy/module/micronumpy/test/test_scalar.py +++ b/pypy/module/micronumpy/test/test_scalar.py @@ -21,3 +21,7 @@ a = zeros(3) assert loads(dumps(sum(a))) == sum(a) + + def setup_class(cls): + import py + py.test.xfail("FIXME: dtype('int32') == dtype('int32') fails") diff --git a/pypy/module/pypyjit/test_pypy_c/model.py b/pypy/module/pypyjit/test_pypy_c/model.py --- a/pypy/module/pypyjit/test_pypy_c/model.py +++ b/pypy/module/pypyjit/test_pypy_c/model.py @@ -184,7 +184,7 @@ def match_by_id(self, id, expected_src, **kwds): ops = list(self.ops_by_id(id, **kwds)) - matcher = OpMatcher(ops) + matcher = OpMatcher(ops, id) return matcher.match(expected_src) class PartialTraceWithIds(TraceWithIds): @@ -260,8 +260,9 @@ class OpMatcher(object): - def __init__(self, ops): + def __init__(self, ops, id=None): self.ops = ops + self.id = id self.src = '\n'.join(map(str, ops)) self.alpha_map = {} @@ -495,6 +496,7 @@ print '@' * 40 print "Loops don't match" print "=================" + print 'loop id = %r' % (self.id,) print e.args print e.msg print diff --git a/pypy/module/pypyjit/test_pypy_c/test_bug.py b/pypy/module/pypyjit/test_pypy_c/test_bug.py --- a/pypy/module/pypyjit/test_pypy_c/test_bug.py +++ b/pypy/module/pypyjit/test_pypy_c/test_bug.py @@ -6,6 +6,11 @@ def test_bug1(): if not sys.platform.startswith('linux'): py.test.skip("linux-only test") + if '__pypy__' not in sys.builtin_module_names: + try: + import cffi + except ImportError, e: + py.test.skip(str(e)) cmdline = ['taskset', '-c', '0', sys.executable, os.path.join(localdir, 'bug1.py')] diff --git a/pypy/module/pypyjit/test_pypy_c/test_call.py b/pypy/module/pypyjit/test_pypy_c/test_call.py --- a/pypy/module/pypyjit/test_pypy_c/test_call.py +++ b/pypy/module/pypyjit/test_pypy_c/test_call.py @@ -254,17 +254,22 @@ return c # s = 0 - for i in range(x): + i = 0 + while i < x: l = [i, x, 2] s += g(*l) # ID: g1 s += h(*l) # ID: h1 s += g(i, x, 2) # ID: g2 a = 0 - for i in range(x): + i += 1 + i = 0 + while i < x: l = [x, 2] + g(*l) s += g(i, *l) # ID: g3 s += h(i, *l) # ID: h2 a = 0 + i += 1 return s # log = self.run(main, [1000]) @@ -339,6 +344,7 @@ loop, = log.loops_by_filename(self.filepath) # the int strategy is used here assert loop.match_by_id('append', """ + guard_not_invalidated? i13 = getfield_gc(p8, descr=<FieldS list.length .*>) i15 = int_add(i13, 1) # Will be killed by the backend @@ -486,6 +492,7 @@ assert loop.match(""" i2 = int_lt(i0, i1) guard_true(i2, descr=...) + guard_not_invalidated? i3 = force_token() i4 = int_add(i0, 1) --TICK-- @@ -585,7 +592,7 @@ """, [1000]) loop, = log.loops_by_id('call') assert loop.match_by_id('call', ''' - guard_not_invalidated(descr=...) + guard_not_invalidated? i1 = force_token() ''') diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py b/pypy/module/pypyjit/test_pypy_c/test_containers.py --- a/pypy/module/pypyjit/test_pypy_c/test_containers.py +++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py @@ -13,6 +13,7 @@ a = A() a.x = 1 for s in sys.modules.keys() * 1000: + d.get(s) # force pending setfields etc. inc = a.x # ID: look d[s] = d.get(s, 0) + inc return sum(d.values()) @@ -21,8 +22,7 @@ assert log.result % 1000 == 0 loop, = log.loops_by_filename(self.filepath) ops = loop.ops_by_id('look') - assert log.opnames(ops) == ['setfield_gc', - 'guard_not_invalidated'] + assert log.opnames(ops) == [] def test_identitydict(self): def fn(n): diff --git a/pypy/module/pypyjit/test_pypy_c/test_min_max.py b/pypy/module/pypyjit/test_pypy_c/test_min_max.py --- a/pypy/module/pypyjit/test_pypy_c/test_min_max.py +++ b/pypy/module/pypyjit/test_pypy_c/test_min_max.py @@ -49,17 +49,20 @@ label(..., descr=...) ... label(..., descr=...) + guard_not_invalidated? i17 = int_ge(i11, i7) guard_false(i17, descr=...) p18 = getarrayitem_gc(p5, i11, descr=...) i19 = int_add(i11, 1) setfield_gc(p2, i19, descr=...) - guard_class(p18, ConstClass(W_IntObject), descr=...) + guard_nonnull_class(p18, ConstClass(W_IntObject), descr=...) i20 = getfield_gc_pure(p18, descr=...) i21 = int_gt(i20, i14) guard_true(i21, descr=...) jump(..., descr=...) ''') + # XXX could be "guard_class(p18)" instead; we lost somewhere + # the information that it cannot be null. def test_iter_max(self): def main(): diff --git a/pypy/module/pypyjit/test_pypy_c/test_misc.py b/pypy/module/pypyjit/test_pypy_c/test_misc.py --- a/pypy/module/pypyjit/test_pypy_c/test_misc.py +++ b/pypy/module/pypyjit/test_pypy_c/test_misc.py @@ -177,6 +177,7 @@ assert log.result == 1000 * 999 / 2 loop, = log.loops_by_filename(self.filepath) assert loop.match(""" + guard_not_invalidated? i16 = int_ge(i11, i12) guard_false(i16, descr=...) i17 = int_mul(i11, i14) @@ -184,7 +185,7 @@ i20 = int_add(i11, 1) i21 = force_token() setfield_gc(p4, i20, descr=<.* .*W_AbstractSeqIterObject.inst_index .*>) - guard_not_invalidated(descr=...) + guard_not_invalidated? i23 = int_lt(i18, 0) guard_false(i23, descr=...) i25 = int_ge(i18, i9) @@ -234,6 +235,7 @@ assert log.result == 1000000 loop, = log.loops_by_filename(self.filepath) assert loop.match(""" + guard_not_invalidated? i14 = getfield_gc(p12, descr=<FieldS list.length .*>) i16 = uint_ge(i12, i14) guard_false(i16, descr=...) @@ -242,7 +244,7 @@ i19 = int_add(i12, 1) setfield_gc(p9, i19, descr=<FieldS .*W_AbstractSeqIterObject.inst_index .*>) guard_nonnull_class(p17, ..., descr=...) - guard_not_invalidated(descr=...) + guard_not_invalidated? i21 = getfield_gc(p17, descr=<FieldS .*W_Array.*.inst_len .*>) i23 = int_lt(0, i21) guard_true(i23, descr=...) diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py b/pypy/module/pypyjit/test_pypy_c/test_string.py --- a/pypy/module/pypyjit/test_pypy_c/test_string.py +++ b/pypy/module/pypyjit/test_pypy_c/test_string.py @@ -157,7 +157,7 @@ copystrcontent(p9, p21, 0, i25, i10) i33 = int_lt(i30, 23) guard_true(i33, descr=...) - p35 = call(ConstClass(ll_shrink_array__rpy_stringPtr_Signed), p21, i30, descr=<Callr . ri EF=4>) + p35 = call(ConstClass(ll_shrink_array__rpy_stringPtr_Signed), p21, i30, descr=<Callr . ri EF=4 OS=3>) guard_no_exception(descr=...) i37 = strlen(p35) i38 = int_add_ovf(i5, i37) @@ -190,7 +190,7 @@ assert len(loops) == 1 for loop in loops: loop.match_by_id('getattr',''' - guard_not_invalidated(descr=...) + guard_not_invalidated? i32 = strlen(p31) i34 = int_add(5, i32) p35 = newstr(i34) diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py b/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py --- a/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py +++ b/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py @@ -98,10 +98,10 @@ s = ffi.new("struct s1 *") setattr(s, name, value) assert getattr(s, name) == value - raw1 = bytes(ffi.buffer(s)) + raw1 = ffi.buffer(s)[:] if lib is not None: t = lib.try_with_value(fnames.index(name), value) - raw2 = bytes(ffi.buffer(t, len(raw1))) + raw2 = ffi.buffer(t, len(raw1))[:] assert raw1 == raw2 def test_bitfield_basic(self): diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py --- a/rpython/annotator/description.py +++ b/rpython/annotator/description.py @@ -215,8 +215,9 @@ if len(self._cache) != 1: raise NoStandardGraph(self) [graph] = self._cache.values() + relax_sig_check = getattr(self.pyobj, "relax_sig_check", False) if (graph.signature != self.signature or - graph.defaults != self.defaults): + graph.defaults != self.defaults) and not relax_sig_check: raise NoStandardGraph(self) return graph diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -3542,6 +3542,16 @@ s = a.build_types(f, [int]) assert s.knowntype is int + def test_relax(self): + def f(*args): + return args[0] + args[1] + f.relax_sig_check = True + def g(x): + return f(x, x - x) + a = self.RPythonAnnotator() + s = a.build_types(g, [int]) + assert a.bookkeeper.getdesc(f).getuniquegraph() + def test_cannot_raise_ll_exception(self): from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr # diff --git a/rpython/rlib/entrypoint.py b/rpython/rlib/entrypoint.py --- a/rpython/rlib/entrypoint.py +++ b/rpython/rlib/entrypoint.py @@ -5,13 +5,33 @@ from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rlib.objectmodel import we_are_translated + +def entrypoint_lowlevel(key, argtypes, c_name=None, relax=False): + """ Note: entrypoint should call llop.gc_stack_bottom on it's own. + That's necessary for making it work with asmgcc and hence JIT + + If in doubt, use entrypoint(). + + if key == 'main' than it's included by default + """ + from rpython.translator.tool.cbuild import ExternalCompilationInfo + + def deco(func): + secondary_entrypoints.setdefault(key, []).append((func, argtypes)) + if c_name is not None: + func.c_name = c_name + if relax: + func.relax_sig_check = True + func._compilation_info = ExternalCompilationInfo( + export_symbols=[c_name or func.func_name]) + return func + return deco + + pypy_debug_catch_fatal_exception = rffi.llexternal('pypy_debug_catch_fatal_exception', [], lltype.Void) def entrypoint(key, argtypes, c_name=None): - """ Note: entrypoint should call llop.gc_stack_bottom on it's own. - That's necessary for making it work with asmgcc and hence JIT - - if key == 'main' than it's included by default + """if key == 'main' than it's included by default """ from rpython.translator.tool.cbuild import ExternalCompilationInfo diff --git a/rpython/rlib/rStringIO.py b/rpython/rlib/rStringIO.py --- a/rpython/rlib/rStringIO.py +++ b/rpython/rlib/rStringIO.py @@ -101,7 +101,11 @@ self.__pos = endp def seek(self, position, mode=0): - if mode == 1: + if mode == 0: + if position == self.getsize(): + self.__pos = AT_END + return + elif mode == 1: if self.__pos == AT_END: self.__pos = self.getsize() position += self.__pos @@ -163,14 +167,24 @@ return ''.join(self.__bigbuffer[p:i]) def truncate(self, size): + """Warning, this gets us slightly strange behavior from the + point of view of a traditional Unix file, but consistent with + Python 2.7's cStringIO module: it will not enlarge the file, + and it will always seek to the (new) end of the file.""" assert size >= 0 - if self.__bigbuffer is None or size > len(self.__bigbuffer): - self.__copy_into_bigbuffer() + if size == 0: + self.__bigbuffer = None + self.__strings = None else: - # we can drop all extra strings - if self.__strings is not None: - self.__strings = None - if size < len(self.__bigbuffer): - del self.__bigbuffer[size:] - if len(self.__bigbuffer) == 0: - self.__bigbuffer = None + if self.__bigbuffer is None or size > len(self.__bigbuffer): + self.__copy_into_bigbuffer() + else: + # we can drop all extra strings + if self.__strings is not None: + self.__strings = None + if size < len(self.__bigbuffer): + del self.__bigbuffer[size:] + if len(self.__bigbuffer) == 0: + self.__bigbuffer = None + # it always has the effect of seeking at the new end + self.__pos = AT_END diff --git a/rpython/rlib/test/test_rStringIO.py b/rpython/rlib/test/test_rStringIO.py --- a/rpython/rlib/test/test_rStringIO.py +++ b/rpython/rlib/test/test_rStringIO.py @@ -96,7 +96,15 @@ f.truncate(20) assert f.getvalue() == '' assert f.tell() == 0 - f.write('\x00' * 20) + f.write('\x00' * 25) + f.seek(12) + f.truncate(20) + assert f.getvalue() == '\x00' * 20 + assert f.tell() == 20 + f.write('more') + f.truncate(20) + assert f.getvalue() == '\x00' * 20 + assert f.tell() == 20 f.write('hello') f.write(' world') f.truncate(30) @@ -109,6 +117,13 @@ assert f.getvalue() == '\x00' * 3 assert f.tell() == 3 +def test_truncate_end(): + f = RStringIO() + f.write("abc") + f.seek(0) + f.truncate(0) + assert f.getvalue() == "" + def test_bug(): f = RStringIO() f.write('0') diff --git a/rpython/rlib/test/test_rlocale.py b/rpython/rlib/test/test_rlocale.py --- a/rpython/rlib/test/test_rlocale.py +++ b/rpython/rlib/test/test_rlocale.py @@ -20,8 +20,8 @@ def test_setlocale_worked(self): assert u"Ą".isupper() - raises(LocaleError, setlocale, LC_ALL, "bla bla bla") - raises(LocaleError, setlocale, 1234455, None) + py.test.raises(LocaleError, setlocale, LC_ALL, "bla bla bla") + py.test.raises(LocaleError, setlocale, 1234455, None) def test_lower_upper(self): assert isupper(ord("A")) diff --git a/rpython/translator/c/test/test_genc.py b/rpython/translator/c/test/test_genc.py --- a/rpython/translator/c/test/test_genc.py +++ b/rpython/translator/c/test/test_genc.py @@ -522,8 +522,9 @@ f = getattr(self, "_f", None) if f is not None: return f - f = lambda arg: self.func(arg) + f = lambda *args: self.func(*args) f.c_name = self.name + f.relax_sig_check = True f.__name__ = "WRAP%s" % (self.name, ) self._f = f return f _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit