Author: Philip Jenvey <pjen...@underboss.org> Branch: py3k Changeset: r68672:60112abc6c12 Date: 2014-01-14 13:36 -0800 http://bitbucket.org/pypy/pypy/changeset/60112abc6c12/
Log: merge default diff --git a/lib-python/2.7/test/test_ssl.py b/lib-python/2.7/test/test_ssl.py --- a/lib-python/2.7/test/test_ssl.py +++ b/lib-python/2.7/test/test_ssl.py @@ -993,7 +993,7 @@ try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True) try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True) + try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False) try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False) diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -107,7 +107,7 @@ RegrTest('test_asynchat.py', usemodules='select fcntl'), RegrTest('test_asyncore.py', usemodules='select fcntl'), RegrTest('test_atexit.py', core=True), - RegrTest('test_audioop.py', skip="unsupported extension module"), + RegrTest('test_audioop.py', skip="incomplete module"), RegrTest('test_augassign.py', core=True), RegrTest('test_base64.py', usemodules='struct'), RegrTest('test_bigaddrspace.py'), diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py --- a/lib_pypy/_ctypes/array.py +++ b/lib_pypy/_ctypes/array.py @@ -21,10 +21,13 @@ # we don't want to have buffers here if len(val) > self._length_: raise ValueError("%r too long" % (val,)) - for i in range(len(val)): - self[i] = val[i] + if isinstance(val, str): + _rawffi.rawstring2charp(self._buffer.buffer, val) + else: + for i in range(len(val)): + self[i] = val[i] if len(val) < self._length_: - self[len(val)] = b'\x00' + self._buffer[len(val)] = b'\x00' res.value = property(getvalue, setvalue) def getraw(self): @@ -34,8 +37,7 @@ def setraw(self, buffer): if len(buffer) > self._length_: raise ValueError("%r too long" % (buffer,)) - for i in range(len(buffer)): - self[i] = buffer[i] + _rawffi.rawstring2charp(self._buffer.buffer, buffer) res.raw = property(getraw, setraw) elif subletter == 'u': def getvalue(self): @@ -46,10 +48,14 @@ # we don't want to have buffers here if len(val) > self._length_: raise ValueError("%r too long" % (val,)) + if isinstance(val, str): + target = self._buffer + else: + target = self for i in range(len(val)): - self[i] = val[i] + target[i] = val[i] if len(val) < self._length_: - self[len(val)] = '\x00' + target[len(val)] = '\x00' res.value = property(getvalue, setvalue) res._ffishape = (ffiarray, res._length_) diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -330,6 +330,14 @@ # SQLite version information sqlite_version = str(_ffi.string(_lib.sqlite3_libversion()).decode('ascii')) +_STMT_TYPE_UPDATE = 0 +_STMT_TYPE_DELETE = 1 +_STMT_TYPE_INSERT = 2 +_STMT_TYPE_REPLACE = 3 +_STMT_TYPE_OTHER = 4 +_STMT_TYPE_SELECT = 5 +_STMT_TYPE_INVALID = 6 + class Error(StandardError): pass @@ -1004,13 +1012,18 @@ self.__statement = self.__connection._statement_cache.get(sql) if self.__connection._isolation_level is not None: - if self.__statement._type in ("UPDATE", "DELETE", "INSERT", "REPLACE"): + if self.__statement._type in ( + _STMT_TYPE_UPDATE, + _STMT_TYPE_DELETE, + _STMT_TYPE_INSERT, + _STMT_TYPE_REPLACE + ): if not self.__connection._in_transaction: self.__connection._begin() - elif self.__statement._type == "OTHER": + elif self.__statement._type == _STMT_TYPE_OTHER: if self.__connection._in_transaction: self.__connection.commit() - elif self.__statement._type == "SELECT": + elif self.__statement._type == _STMT_TYPE_SELECT: if multiple: raise ProgrammingError("You cannot execute SELECT " "statements in executemany().") @@ -1033,12 +1046,17 @@ self.__statement._reset() raise self.__connection._get_exception(ret) - if self.__statement._type in ("UPDATE", "DELETE", "INSERT", "REPLACE"): + if self.__statement._type in ( + _STMT_TYPE_UPDATE, + _STMT_TYPE_DELETE, + _STMT_TYPE_INSERT, + _STMT_TYPE_REPLACE + ): if self.__rowcount == -1: self.__rowcount = 0 self.__rowcount += _lib.sqlite3_changes(self.__connection._db) - if not multiple and self.__statement._type == "INSERT": + if not multiple and self.__statement._type == _STMT_TYPE_INSERT: self.__lastrowid = _lib.sqlite3_last_insert_rowid(self.__connection._db) else: self.__lastrowid = None @@ -1188,11 +1206,19 @@ first_word = sql.lstrip().split(" ")[0].upper() if first_word == "": - self._type = "INVALID" - elif first_word in ("SELECT", "INSERT", "UPDATE", "DELETE", "REPLACE"): - self._type = first_word + self._type = _STMT_TYPE_INVALID + elif first_word == "SELECT": + self._type = _STMT_TYPE_SELECT + elif first_word == "INSERT": + self._type = _STMT_TYPE_INSERT + elif first_word == "UPDATE": + self._type = _STMT_TYPE_UPDATE + elif first_word == "DELETE": + self._type = _STMT_TYPE_DELETE + elif first_word == "REPLACE": + self._type = _STMT_TYPE_REPLACE else: - self._type = "OTHER" + self._type = _STMT_TYPE_OTHER if isinstance(sql, unicode): sql = sql.encode('utf-8') @@ -1205,7 +1231,7 @@ if ret == _lib.SQLITE_OK and not self._statement: # an empty statement, work around that, as it's the least trouble - self._type = "SELECT" + self._type = _STMT_TYPE_SELECT c_sql = _ffi.new("char[]", b"select 42") ret = _lib.sqlite3_prepare_v2(self.__con._db, c_sql, -1, statement_star, next_char) @@ -1324,7 +1350,12 @@ raise ValueError("parameters are of unsupported type") def _get_description(self): - if self._type in ("INSERT", "UPDATE", "DELETE", "REPLACE"): + if self._type in ( + _STMT_TYPE_INSERT, + _STMT_TYPE_UPDATE, + _STMT_TYPE_DELETE, + _STMT_TYPE_REPLACE + ): return None desc = [] for i in xrange(_lib.sqlite3_column_count(self._statement)): diff --git a/lib_pypy/audioop.py b/lib_pypy/audioop.py new file mode 100644 --- /dev/null +++ b/lib_pypy/audioop.py @@ -0,0 +1,29 @@ + +import struct + + +class error(Exception): + pass + + +def _check_size(size): + if size != 1 and size != 2 and size != 4: + raise error("Size should be 1, 2 or 4") + + +def _check_params(length, size): + _check_size(size) + if length % size != 0: + raise error("not a whole number of frames") + + +def getsample(cp, size, i): + _check_params(len(cp), size) + if not (0 <= i < len(cp) / size): + raise error("Index out of range") + if size == 1: + return struct.unpack_from("B", buffer(cp)[i:])[0] + elif size == 2: + return struct.unpack_from("H", buffer(cp)[i * 2:])[0] + elif size == 4: + return struct.unpack_from("I", buffer(cp)[i * 4:])[0] diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -5,7 +5,7 @@ from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr -from rpython.rlib import objectmodel, rgc +from rpython.rlib import rgc from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rtyper.lltypesystem import lltype, rffi from rpython.tool.sourcetools import func_with_new_name diff --git a/pypy/module/_rawffi/__init__.py b/pypy/module/_rawffi/__init__.py --- a/pypy/module/_rawffi/__init__.py +++ b/pypy/module/_rawffi/__init__.py @@ -19,6 +19,7 @@ 'wcharp2unicode' : 'interp_rawffi.wcharp2unicode', 'charp2rawstring' : 'interp_rawffi.charp2rawstring', 'wcharp2rawunicode' : 'interp_rawffi.wcharp2rawunicode', + 'rawstring2charp' : 'interp_rawffi.rawstring2charp', 'CallbackPtr' : 'callback.W_CallbackPtr', '_num_of_allocated_objects' : 'tracker.num_of_allocated_objects', 'get_libc' : 'interp_rawffi.get_libc', diff --git a/pypy/module/_rawffi/array.py b/pypy/module/_rawffi/array.py --- a/pypy/module/_rawffi/array.py +++ b/pypy/module/_rawffi/array.py @@ -15,6 +15,7 @@ from pypy.module._rawffi.interp_rawffi import unpack_shape_with_length from pypy.module._rawffi.interp_rawffi import read_ptr, write_ptr from rpython.rlib.rarithmetic import r_uint +from rpython.rlib import rgc class W_Array(W_DataShape): @@ -220,6 +221,7 @@ def __init__(self, space, shape, length): W_ArrayInstance.__init__(self, space, shape, length, 0) + @rgc.must_be_light_finalizer def __del__(self): if self.ll_buffer: self._free() diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py --- a/pypy/module/_rawffi/interp_rawffi.py +++ b/pypy/module/_rawffi/interp_rawffi.py @@ -589,6 +589,13 @@ s = rffi.wcharpsize2unicode(rffi.cast(rffi.CWCHARP, address), maxlength) return space.wrap(s) +@unwrap_spec(address=r_uint, newcontent=str) +def rawstring2charp(space, address, newcontent): + from rpython.rtyper.annlowlevel import llstr + from rpython.rtyper.lltypesystem.rstr import copy_string_to_raw + array = rffi.cast(rffi.CCHARP, address) + copy_string_to_raw(llstr(newcontent), array, 0, len(newcontent)) + if _MS_WINDOWS: @unwrap_spec(code=int) def FormatError(space, code): diff --git a/pypy/module/_rawffi/structure.py b/pypy/module/_rawffi/structure.py --- a/pypy/module/_rawffi/structure.py +++ b/pypy/module/_rawffi/structure.py @@ -16,7 +16,7 @@ from pypy.module._rawffi.interp_rawffi import unroll_letters_for_numbers from pypy.module._rawffi.interp_rawffi import size_alignment from pypy.module._rawffi.interp_rawffi import read_ptr, write_ptr -from rpython.rlib import clibffi +from rpython.rlib import clibffi, rgc from rpython.rlib.rarithmetic import intmask, signedtype, widen from rpython.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong @@ -226,6 +226,7 @@ fieldtypes) return self.ffi_struct.ffistruct + @rgc.must_be_light_finalizer def __del__(self): if self.ffi_struct: lltype.free(self.ffi_struct, flavor='raw') @@ -380,6 +381,7 @@ def __init__(self, space, shape): W_StructureInstance.__init__(self, space, shape, 0) + @rgc.must_be_light_finalizer def __del__(self): if self.ll_buffer: self._free() diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py --- a/pypy/module/_rawffi/test/test__rawffi.py +++ b/pypy/module/_rawffi/test/test__rawffi.py @@ -324,6 +324,14 @@ assert res == 'xx' a.free() + def test_rawstring2charp(self): + import _rawffi + A = _rawffi.Array('c') + a = A(10, 'x'*10) + _rawffi.rawstring2charp(a.buffer, "foobar") + assert ''.join([a[i] for i in range(10)]) == "foobarxxxx" + a.free() + def test_raw_callable(self): import _rawffi lib = _rawffi.CDLL(self.lib_name) diff --git a/pypy/module/_rawffi/test/test_tracker.py b/pypy/module/_rawffi/test/test_tracker.py --- a/pypy/module/_rawffi/test/test_tracker.py +++ b/pypy/module/_rawffi/test/test_tracker.py @@ -1,9 +1,21 @@ +import py +from pypy.conftest import option from pypy.module._rawffi.tracker import Tracker + class AppTestTracker: spaceconfig = dict(usemodules=['_rawffi', 'struct']) def setup_class(cls): + # + # detect if we're running on PyPy with DO_TRACING not compiled in + if option.runappdirect: + try: + import _rawffi + _rawffi._num_of_allocated_objects() + except (ImportError, RuntimeError), e: + py.test.skip(str(e)) + # Tracker.DO_TRACING = True def test_array(self): diff --git a/pypy/module/_rawffi/tracker.py b/pypy/module/_rawffi/tracker.py --- a/pypy/module/_rawffi/tracker.py +++ b/pypy/module/_rawffi/tracker.py @@ -2,9 +2,11 @@ """ The file that keeps track about freed/kept-alive objects allocated by _rawffi. Used for debugging ctypes """ +from pypy.interpreter.error import OperationError + class Tracker(object): - DO_TRACING = True + DO_TRACING = False # make sure this stays False by default! def __init__(self): self.alloced = {} @@ -20,6 +22,9 @@ tracker = Tracker() def num_of_allocated_objects(space): + if not tracker.DO_TRACING: + raise OperationError(space.w_RuntimeError, + space.wrap("DO_TRACING not enabled in this PyPy")) return space.wrap(len(tracker.alloced)) def print_alloced_objects(space): diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py --- a/pypy/module/_ssl/interp_ssl.py +++ b/pypy/module/_ssl/interp_ssl.py @@ -859,7 +859,7 @@ libssl_SSL_set_fd(ss.ssl, sock_fd) # set the socket for SSL # The ACCEPT_MOVING_WRITE_BUFFER flag is necessary because the address # of a str object may be changed by the garbage collector. - libssl_SSL_set_mode(ss.ssl, + libssl_SSL_set_mode(ss.ssl, SSL_MODE_AUTO_RETRY | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) if server_hostname: diff --git a/pypy/module/_weakref/interp__weakref.py b/pypy/module/_weakref/interp__weakref.py --- a/pypy/module/_weakref/interp__weakref.py +++ b/pypy/module/_weakref/interp__weakref.py @@ -52,6 +52,7 @@ # weakref callbacks are not invoked eagerly here. They are # invoked by self.__del__() anyway. + @jit.dont_look_inside def get_or_make_weakref(self, w_subtype, w_obj): space = self.space w_weakreftype = space.gettypeobject(W_Weakref.typedef) @@ -70,6 +71,7 @@ self.append_wref_to(w_ref) return w_ref + @jit.dont_look_inside def get_or_make_proxy(self, w_obj): space = self.space if self.cached_proxy is not None: @@ -122,6 +124,7 @@ W_WeakrefBase.activate_callback, 'weakref callback of ') + @jit.dont_look_inside def make_weakref_with_callback(self, w_subtype, w_obj, w_callable): space = self.space w_ref = space.allocate_instance(W_Weakref, w_subtype) @@ -129,6 +132,7 @@ self.append_wref_to(w_ref) return w_ref + @jit.dont_look_inside def make_proxy_with_callback(self, w_obj, w_callable): space = self.space if space.is_true(space.callable(w_obj)): @@ -239,15 +243,16 @@ w_obj.setweakref(space, lifeline) return lifeline -@jit.dont_look_inside + def get_or_make_weakref(space, w_subtype, w_obj): return getlifeline(space, w_obj).get_or_make_weakref(w_subtype, w_obj) -@jit.dont_look_inside + def make_weakref_with_callback(space, w_subtype, w_obj, w_callable): lifeline = getlifelinewithcallbacks(space, w_obj) return lifeline.make_weakref_with_callback(w_subtype, w_obj, w_callable) + def descr__new__weakref(space, w_subtype, w_obj, w_callable=None, __args__=None): if __args__.arguments_w: @@ -312,15 +317,16 @@ w_obj = force(space, self) return space.call_args(w_obj, __args__) -@jit.dont_look_inside + def get_or_make_proxy(space, w_obj): return getlifeline(space, w_obj).get_or_make_proxy(w_obj) -@jit.dont_look_inside + def make_proxy_with_callback(space, w_obj, w_callable): lifeline = getlifelinewithcallbacks(space, w_obj) return lifeline.make_proxy_with_callback(w_obj, w_callable) + def proxy(space, w_obj, w_callable=None): """Create a proxy object that weakly references 'obj'. 'callback', if given, is called with the proxy as an argument when 'obj' 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 @@ -20,7 +20,10 @@ assert math.isnan(np.complex_(None)) for c in ['i', 'I', 'l', 'L', 'q', 'Q']: assert np.dtype(c).type().dtype.char == c - assert np.dtype('L').type(sys.maxint + 42) == sys.maxint + 42 + for c in ['l', 'q']: + assert np.dtype(c).type(sys.maxint) == sys.maxint + for c in ['L', 'Q']: + assert np.dtype(c).type(sys.maxint + 42) == sys.maxint + 42 def test_builtin(self): import numpy as np diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -586,7 +586,8 @@ BoxType = interp_boxes.W_Int64Box format_code = "q" - _coerce = func_with_new_name(_int64_coerce, '_coerce') + if LONG_BIT == 32: + _coerce = func_with_new_name(_int64_coerce, '_coerce') def _uint64_coerce(self, space, w_item): try: @@ -613,16 +614,25 @@ BoxType = interp_boxes.W_LongBox format_code = "l" - if LONG_BIT == 64: - _coerce = func_with_new_name(_int64_coerce, '_coerce') +def _ulong_coerce(self, space, w_item): + try: + return self._base_coerce(space, w_item) + except OperationError, e: + if not e.match(space, space.w_OverflowError): + raise + bigint = space.bigint_w(w_item) + try: + value = bigint.touint() + except OverflowError: + raise OperationError(space.w_OverflowError, space.w_None) + return self.box(value) class ULong(BaseType, Integer): T = rffi.ULONG BoxType = interp_boxes.W_ULongBox format_code = "L" - if LONG_BIT == 64: - _coerce = func_with_new_name(_uint64_coerce, '_coerce') + _coerce = func_with_new_name(_ulong_coerce, '_coerce') class Float(Primitive): _mixin_ = True diff --git a/pypy/module/pypyjit/test_pypy_c/test_weakref.py b/pypy/module/pypyjit/test_pypy_c/test_weakref.py new file mode 100644 --- /dev/null +++ b/pypy/module/pypyjit/test_pypy_c/test_weakref.py @@ -0,0 +1,46 @@ +from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC + + +class TestThread(BaseTestPyPyC): + def test_make_ref_with_callback(self): + log = self.run(""" + import weakref + + class Dummy(object): + pass + + def noop(obj): + pass + + def main(n): + obj = Dummy() + for i in xrange(n): + weakref.ref(obj, noop) + """, [500]) + loop, = log.loops_by_filename(self.filepath) + assert loop.match(""" + i58 = getfield_gc(p18, descr=<FieldS pypy.module.__builtin__.functional.W_XRangeIterator.inst_current .>) + i59 = getfield_gc(p18, descr=<FieldS pypy.module.__builtin__.functional.W_XRangeStepOneIterator.inst_stop \d+>) + i60 = int_lt(i58, i59) + guard_true(i60, descr=...) + i61 = int_add(i58, 1) + p62 = getfield_gc(ConstPtr(ptr37), descr=<FieldP pypy.objspace.std.dictmultiobject.W_DictMultiObject.inst_strategy \d+>) + setfield_gc(p18, i61, descr=<FieldS pypy.module.__builtin__.functional.W_XRangeIterator.inst_current 8>) + guard_value(p62, ConstPtr(ptr39), descr=...) + guard_not_invalidated(descr=...) + p64 = getfield_gc(ConstPtr(ptr40), descr=<FieldP pypy.objspace.std.dictmultiobject.W_DictMultiObject.inst_strategy \d+>) + guard_value(p64, ConstPtr(ptr42), descr=...) + p65 = getfield_gc(p14, descr=<FieldP pypy.objspace.std.mapdict.W_ObjectObjectSize5.inst_map 48>) + guard_value(p65, ConstPtr(ptr45), descr=...) + p66 = getfield_gc(p14, descr=<FieldP pypy.objspace.std.mapdict.W_ObjectObjectSize5.inst__value0 \d+>) + guard_nonnull_class(p66, ..., descr=...) + p67 = force_token() + setfield_gc(p0, p67, descr=<FieldP pypy.interpreter.pyframe.PyFrame.vable_token \d+>) + p68 = call_may_force(ConstClass(WeakrefLifelineWithCallbacks.make_weakref_with_callback), p66, ConstPtr(ptr50), p14, ConstPtr(ptr51), descr=<Callr 8 rrrr EF=6>) + guard_not_forced(descr=...) + guard_no_exception(descr=...) + guard_nonnull_class(p68, ..., descr=...) + guard_not_invalidated(descr=...) + --TICK-- + jump(..., descr=...) + """) diff --git a/pypy/module/test_lib_pypy/ctypes_tests/support.py b/pypy/module/test_lib_pypy/ctypes_tests/support.py --- a/pypy/module/test_lib_pypy/ctypes_tests/support.py +++ b/pypy/module/test_lib_pypy/ctypes_tests/support.py @@ -31,8 +31,10 @@ import gc for _ in range(4): gc.collect() - cls.old_num = _rawffi._num_of_allocated_objects() - + try: + cls.old_num = _rawffi._num_of_allocated_objects() + except RuntimeError: + pass def teardown_class(cls): if sys.pypy_translation_info['translation.gc'] == 'boehm': diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py --- a/pypy/module/zipimport/interp_zipimport.py +++ b/pypy/module/zipimport/interp_zipimport.py @@ -5,8 +5,10 @@ from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.module import Module from pypy.module.imp import importing +from pypy.module.zlib.interp_zlib import zlib_error from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.rzipfile import RZipFile, BadZipfile +from rpython.rlib.rzlib import RZlibError import os import stat @@ -252,6 +254,10 @@ buf = self.zip_file.read(fname) except (KeyError, OSError, BadZipfile): pass + except RZlibError, e: + # in this case, CPython raises the direct exception coming + # from the zlib module: let's to the same + raise zlib_error(space, e.msg) else: if is_package: pkgpath = (self.filename + os.path.sep + @@ -282,6 +288,10 @@ return space.wrapbytes(data) except (KeyError, OSError, BadZipfile): raise OperationError(space.w_IOError, space.wrap("Error reading file")) + except RZlibError, e: + # in this case, CPython raises the direct exception coming + # from the zlib module: let's to the same + raise zlib_error(space, e.msg) @unwrap_spec(fullname='str0') def get_code(self, space, fullname): @@ -384,6 +394,11 @@ except (BadZipfile, OSError): raise operationerrfmt(get_error(space), "%s seems not to be a zipfile", filename) + except RZlibError, e: + # in this case, CPython raises the direct exception coming + # from the zlib module: let's to the same + raise zlib_error(space, e.msg) + prefix = name[len(filename):] if prefix.startswith(os.path.sep) or prefix.startswith(ZIPSEP): prefix = prefix[1:] diff --git a/pypy/module/zipimport/test/bad.zip b/pypy/module/zipimport/test/bad.zip new file mode 100644 index 0000000000000000000000000000000000000000..1d326a869a409a04dc46475bf157cb6f5bdb0664 GIT binary patch [cut] diff --git a/pypy/module/zipimport/test/test_zipimport_deflated.py b/pypy/module/zipimport/test/test_zipimport_deflated.py --- a/pypy/module/zipimport/test/test_zipimport_deflated.py +++ b/pypy/module/zipimport/test/test_zipimport_deflated.py @@ -3,6 +3,7 @@ from zipfile import ZIP_DEFLATED from pypy.module.zipimport.test.test_zipimport import AppTestZipimport as Base +BAD_ZIP = str(py.path.local(__file__).dirpath('bad.zip')) class AppTestZipimportDeflated(Base): compression = ZIP_DEFLATED @@ -16,3 +17,10 @@ except ImportError: py.test.skip("zlib not available, cannot test compressed zipfiles") cls.make_class() + cls.w_BAD_ZIP = cls.space.wrap(BAD_ZIP) + + def test_zlib_error(self): + import zipimport + import zlib + z = zipimport.zipimporter(self.BAD_ZIP) + raises(zlib.error, "z.load_module('mymod')") diff --git a/pypy/tool/gdb_pypy.py b/pypy/tool/gdb_pypy.py --- a/pypy/tool/gdb_pypy.py +++ b/pypy/tool/gdb_pypy.py @@ -38,9 +38,9 @@ if len(names) == 1: return val[names[0]] elif len(names) == 0: - raise KeyError, "cannot find field *%s" % suffix + raise KeyError("cannot find field *%s" % suffix) else: - raise KeyError, "too many matching fields: %s" % ', '.join(names) + raise KeyError("too many matching fields: %s" % ', '.join(names)) def lookup(val, suffix): """ @@ -76,10 +76,14 @@ def invoke(self, arg, from_tty): # some magic code to automatically reload the python file while developing from pypy.tool import gdb_pypy - reload(gdb_pypy) + try: + reload(gdb_pypy) + except: + import imp + imp.reload(gdb_pypy) gdb_pypy.RPyType.prog2typeids = self.prog2typeids # persist the cache self.__class__ = gdb_pypy.RPyType - print self.do_invoke(arg, from_tty) + print (self.do_invoke(arg, from_tty).decode('latin-1')) def do_invoke(self, arg, from_tty): try: @@ -88,7 +92,7 @@ obj = self.gdb.parse_and_eval(arg) hdr = lookup(obj, '_gcheader') tid = hdr['h_tid'] - if sys.maxint < 2**32: + if sys.maxsize < 2**32: offset = tid & 0xFFFF # 32bit else: offset = tid & 0xFFFFFFFF # 64bit @@ -147,13 +151,13 @@ if linenum in self.line2offset: return self.line2offset[linenum] line = self.lines[linenum] - member, descr = map(str.strip, line.split(None, 1)) - if sys.maxint < 2**32: + member, descr = [x.strip() for x in line.split(None, 1)] + if sys.maxsize < 2**32: TIDT = "int*" else: TIDT = "char*" expr = ("((%s)(&pypy_g_typeinfo.%s)) - (%s)&pypy_g_typeinfo" - % (TIDT, member, TIDT)) + % (TIDT, member.decode("latin-1"), TIDT)) offset = int(self.gdb.parse_and_eval(expr)) self.line2offset[linenum] = offset self.offset2descr[offset] = descr @@ -164,7 +168,7 @@ # binary search through the lines, asking gdb to parse stuff lazily if offset in self.offset2descr: return self.offset2descr[offset] - if not (0 < offset < sys.maxint): + if not (0 < offset < sys.maxsize): return None linerange = (0, len(self.lines)) while linerange[0] < linerange[1]: diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py --- a/rpython/config/translationoption.py +++ b/rpython/config/translationoption.py @@ -363,6 +363,10 @@ # if we have specified strange inconsistent settings. config.translation.gc = config.translation.gc + # disallow asmgcc on OS/X + if config.translation.gcrootfinder == "asmgcc": + assert sys.platform != "darwin" + # ---------------------------------------------------------------- def set_platform(config): diff --git a/rpython/jit/metainterp/heapcache.py b/rpython/jit/metainterp/heapcache.py --- a/rpython/jit/metainterp/heapcache.py +++ b/rpython/jit/metainterp/heapcache.py @@ -159,17 +159,17 @@ descr, ) elif cache is not None: - if argboxes[2] in self.new_boxes: - try: - idx_cache = cache[dststart + i] - except KeyError: - pass - else: + try: + idx_cache = cache[dststart + i] + except KeyError: + pass + else: + if argboxes[2] in self.new_boxes: for frombox in idx_cache.keys(): if not self.is_unescaped(frombox): del idx_cache[frombox] - else: - cache[dststart + i].clear() + else: + idx_cache.clear() return elif ( argboxes[2] in self.new_boxes and diff --git a/rpython/jit/metainterp/optimizeopt/earlyforce.py b/rpython/jit/metainterp/optimizeopt/earlyforce.py --- a/rpython/jit/metainterp/optimizeopt/earlyforce.py +++ b/rpython/jit/metainterp/optimizeopt/earlyforce.py @@ -28,8 +28,5 @@ value.force_box(self) self.emit_operation(op) - def new(self): - return OptEarlyForce() - def setup(self): self.optimizer.optearlyforce = self diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py --- a/rpython/jit/metainterp/optimizeopt/heap.py +++ b/rpython/jit/metainterp/optimizeopt/heap.py @@ -184,9 +184,6 @@ self.postponed_op = None self.next_optimization.propagate_forward(postponed_op) - def new(self): - return OptHeap() - def produce_potential_short_preamble_ops(self, sb): descrkeys = self.cached_fields.keys() if not we_are_translated(): diff --git a/rpython/jit/metainterp/optimizeopt/intbounds.py b/rpython/jit/metainterp/optimizeopt/intbounds.py --- a/rpython/jit/metainterp/optimizeopt/intbounds.py +++ b/rpython/jit/metainterp/optimizeopt/intbounds.py @@ -13,9 +13,6 @@ """Keeps track of the bounds placed on integers by guards and remove redundant guards""" - def new(self): - return OptIntBounds() - def propagate_forward(self, op): dispatch_opt(self, op) diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py --- a/rpython/jit/metainterp/optimizeopt/optimizer.py +++ b/rpython/jit/metainterp/optimizeopt/optimizer.py @@ -323,10 +323,6 @@ def force_at_end_of_preamble(self): pass - # It is too late to force stuff here, it must be done in force_at_end_of_preamble - def new(self): - raise NotImplementedError - # Called after last operation has been propagated to flush out any posponed ops def flush(self): pass @@ -390,16 +386,6 @@ for o in self.optimizations: o.flush() - def new(self): - new = Optimizer(self.metainterp_sd, self.loop) - return self._new(new) - - def _new(self, new): - optimizations = [o.new() for o in self.optimizations] - new.set_optimizations(optimizations) - new.quasi_immutable_deps = self.quasi_immutable_deps - return new - def produce_potential_short_preamble_ops(self, sb): for opt in self.optimizations: opt.produce_potential_short_preamble_ops(sb) diff --git a/rpython/jit/metainterp/optimizeopt/pure.py b/rpython/jit/metainterp/optimizeopt/pure.py --- a/rpython/jit/metainterp/optimizeopt/pure.py +++ b/rpython/jit/metainterp/optimizeopt/pure.py @@ -85,10 +85,6 @@ def flush(self): assert self.postponed_op is None - def new(self): - assert self.postponed_op is None - return OptPure() - def setup(self): self.optimizer.optpure = self diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py --- a/rpython/jit/metainterp/optimizeopt/rewrite.py +++ b/rpython/jit/metainterp/optimizeopt/rewrite.py @@ -20,9 +20,6 @@ self.loop_invariant_results = {} self.loop_invariant_producer = {} - def new(self): - return OptRewrite() - def produce_potential_short_preamble_ops(self, sb): for op in self.loop_invariant_producer.values(): sb.add_potential(op) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -5031,6 +5031,19 @@ """ self.optimize_strunicode_loop(ops, expected) + def test_copy_long_string_to_virtual(self): + ops = """ + [] + p0 = newstr(20) + copystrcontent(s"aaaaaaaaaaaaaaaaaaaa", p0, 0, 0, 20) + jump(p0) + """ + expected = """ + [] + jump(s"aaaaaaaaaaaaaaaaaaaa") + """ + self.optimize_strunicode_loop(ops, expected) + def test_ptr_eq_str_constant(self): ops = """ [] diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py --- a/rpython/jit/metainterp/optimizeopt/unroll.py +++ b/rpython/jit/metainterp/optimizeopt/unroll.py @@ -41,10 +41,6 @@ self.emitted_guards += 1 # FIXME: can we use counter in self._emit_operation? self._emit_operation(op) - def new(self): - new = UnrollableOptimizer(self.metainterp_sd, self.loop) - return self._new(new) - class UnrollOptimizer(Optimization): """Unroll the loop into two iterations. The first one will diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py b/rpython/jit/metainterp/optimizeopt/virtualize.py --- a/rpython/jit/metainterp/optimizeopt/virtualize.py +++ b/rpython/jit/metainterp/optimizeopt/virtualize.py @@ -497,9 +497,6 @@ _last_guard_not_forced_2 = None - def new(self): - return OptVirtualize() - def make_virtual(self, known_class, box, source_op=None): vvalue = VirtualValue(self.optimizer.cpu, known_class, box, source_op) self.make_equal_to(box, vvalue) diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py b/rpython/jit/metainterp/optimizeopt/vstring.py --- a/rpython/jit/metainterp/optimizeopt/vstring.py +++ b/rpython/jit/metainterp/optimizeopt/vstring.py @@ -388,8 +388,6 @@ class OptString(optimizer.Optimization): "Handling of strings and unicodes." - def new(self): - return OptString() def make_vstring_plain(self, box, source_op, mode): vvalue = VStringPlainValue(box, source_op, mode) @@ -520,7 +518,7 @@ elif ((src.is_virtual() or src.is_constant()) and srcstart.is_constant() and dststart.is_constant() and length.is_constant() and - (length.force_box(self).getint() < 20 or (src.is_virtual() and dst_virtual))): + (length.force_box(self).getint() < 20 or ((src.is_virtual() or src.is_constant()) and dst_virtual))): src_start = srcstart.force_box(self).getint() dst_start = dststart.force_box(self).getint() actual_length = length.force_box(self).getint() diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py --- a/rpython/memory/gc/incminimark.py +++ b/rpython/memory/gc/incminimark.py @@ -864,7 +864,10 @@ self.next_major_collection_threshold = self.max_heap_size def raw_malloc_memory_pressure(self, sizehint): - self.next_major_collection_threshold -= sizehint + # Decrement by 'sizehint' plus a very little bit extra. This + # is needed e.g. for _rawffi, which may allocate a lot of tiny + # arrays. + self.next_major_collection_threshold -= (sizehint + 2 * WORD) if self.next_major_collection_threshold < 0: # cannot trigger a full collection now, but we can ensure # that one will occur very soon diff --git a/rpython/rlib/runicode.py b/rpython/rlib/runicode.py --- a/rpython/rlib/runicode.py +++ b/rpython/rlib/runicode.py @@ -988,6 +988,8 @@ return result.build(), pos +# Specialize on the errorhandler when it's a constant +@specialize.arg_or_var(3) def unicode_encode_ucs1_helper(p, size, errors, errorhandler=None, limit=256): if errorhandler is None: @@ -1152,8 +1154,10 @@ builder.append(res) return pos +# Specialize on the errorhandler when it's a constant +@specialize.arg_or_var(4) def str_decode_unicode_escape(s, size, errors, final=False, - errorhandler=False, + errorhandler=None, unicodedata_handler=None): if errorhandler is None: errorhandler = default_unicode_error_decode diff --git a/rpython/rtyper/lltypesystem/rstr.py b/rpython/rtyper/lltypesystem/rstr.py --- a/rpython/rtyper/lltypesystem/rstr.py +++ b/rpython/rtyper/lltypesystem/rstr.py @@ -624,6 +624,7 @@ i += 1 return count + @signature(types.any(), types.any(), types.int(), types.int(), returns=types.int()) def ll_find(s1, s2, start, end): if start < 0: start = 0 @@ -638,6 +639,7 @@ return LLHelpers.ll_search(s1, s2, start, end, FAST_FIND) + @signature(types.any(), types.any(), types.int(), types.int(), returns=types.int()) def ll_rfind(s1, s2, start, end): if start < 0: start = 0 diff --git a/rpython/translator/c/gcc/test/test_trackgcroot.py b/rpython/translator/c/gcc/test/test_trackgcroot.py --- a/rpython/translator/c/gcc/test/test_trackgcroot.py +++ b/rpython/translator/c/gcc/test/test_trackgcroot.py @@ -127,6 +127,8 @@ def check_computegcmaptable(format, path): if format == 'msvc': r_globallabel = re.compile(r"([\w]+)::") + elif format == 'darwin' or format == 'darwin64': + py.test.skip("disabled on OS/X's terribly old gcc") else: r_globallabel = re.compile(r"([\w]+)=[.]+") print diff --git a/rpython/translator/c/gcc/trackgcroot.py b/rpython/translator/c/gcc/trackgcroot.py --- a/rpython/translator/c/gcc/trackgcroot.py +++ b/rpython/translator/c/gcc/trackgcroot.py @@ -31,7 +31,7 @@ cls.r_binaryinsn = re.compile(r"\t[a-z]\w*\s+(?P<source>"+cls.OPERAND+"),\s*(?P<target>"+cls.OPERAND+")\s*$") cls.r_jump = re.compile(r"\tj\w+\s+"+cls.LABEL+"\s*" + cls.COMMENT + "$") - cls.r_jmp_switch = re.compile(r"\tjmp\t[*]"+cls.LABEL+"[(]") + cls.r_jmp_switch = re.compile(r"\tjmp\t[*]") cls.r_jmp_source = re.compile(r"\d*[(](%[\w]+)[,)]") def __init__(self, funcname, lines, filetag=0): @@ -697,10 +697,22 @@ tablelabels = [] match = self.r_jmp_switch.match(line) if match: - # this is a jmp *Label(%index), used for table-based switches. - # Assume that the table is just a list of lines looking like - # .long LABEL or .long 0, ending in a .text or .section .text.hot. - tablelabels.append(match.group(1)) + # this is a jmp *Label(%index) or jmp *%addr, used for + # table-based switches. Assume that the table is coming + # after a .section .rodata and a label, and is a list of + # lines looking like .long LABEL or .long 0 or .long L2-L1, + # ending in a .text or .section .text.hot. + lineno = self.currentlineno + 1 + if '.section' not in self.lines[lineno]: + pass # bah, probably a tail-optimized indirect call... + else: + assert '.rodata' in self.lines[lineno] + lineno += 1 + while '.align' in self.lines[lineno]: + lineno += 1 + match = self.r_label.match(self.lines[lineno]) + assert match, repr(self.lines[lineno]) + tablelabels.append(match.group(1)) elif self.r_unaryinsn_star.match(line): # maybe a jmp similar to the above, but stored in a # registry: diff --git a/rpython/translator/unsimplify.py b/rpython/translator/unsimplify.py --- a/rpython/translator/unsimplify.py +++ b/rpython/translator/unsimplify.py @@ -132,11 +132,6 @@ block.exitswitch = None return link -def split_block_at_start(annotator, block): - # split before the first op, preserve order and inputargs - # in the second block! - return split_block(annotator, block, 0, _forcelink=block.inputargs) - def call_initial_function(translator, initial_func, annhelper=None): """Before the program starts, call 'initial_func()'.""" from rpython.annotator import model as annmodel _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit