Author: Wim Lavrijsen <wlavrij...@lbl.gov> Branch: reflex-support Changeset: r63072:607168b3bbc0 Date: 2013-04-05 15:18 -0700 http://bitbucket.org/pypy/pypy/changeset/607168b3bbc0/
Log: merge default into branch diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -48,13 +48,7 @@ from cffi import FFI as _FFI -if '__pypy__' not in sys.builtin_module_names: - from cffi.backend_ctypes import CTypesBackend - backend = CTypesBackend() -else: - backend = None - -_ffi = _FFI(backend=backend) +_ffi = _FFI() _ffi.cdef(""" #define SQLITE_OK ... @@ -224,7 +218,7 @@ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); -void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_blob(sqlite3_context*, const char*, int, void(*)(void*)); void sqlite3_result_double(sqlite3_context*, double); void sqlite3_result_error(sqlite3_context*, const char*, int); void sqlite3_result_error16(sqlite3_context*, const void*, int); @@ -257,7 +251,7 @@ def _has_load_extension(): """Only available since 3.3.6""" - unverified_ffi = _FFI(backend=backend) + unverified_ffi = _FFI() unverified_ffi.cdef(""" typedef ... sqlite3; int sqlite3_enable_load_extension(sqlite3 *db, int onoff); @@ -858,7 +852,7 @@ self._reset = False self.__locked = False self.__closed = False - self.__description = None + self.__lastrowid = None self.__rowcount = -1 con._check_thread() @@ -964,7 +958,7 @@ elif typ == _lib.SQLITE_BLOB: blob = _lib.sqlite3_column_blob(self.__statement._statement, i) blob_len = _lib.sqlite3_column_bytes(self.__statement._statement, i) - val = _BLOB_TYPE(_ffi.buffer(blob, blob_len)) + val = _BLOB_TYPE(_ffi.buffer(blob, blob_len)[:]) row.append(val) return tuple(row) @@ -978,20 +972,24 @@ try: if not isinstance(sql, basestring): raise ValueError("operation parameter must be str or unicode") - self.__description = None + try: + del self.__description + except AttributeError: + pass self.__rowcount = -1 self.__statement = self.__connection._statement_cache.get(sql) if self.__connection._isolation_level is not None: - if self.__statement._kind == Statement._DDL: + if self.__statement._type in ("UPDATE", "DELETE", "INSERT", "REPLACE"): + if not self.__connection._in_transaction: + self.__connection._begin() + elif self.__statement._type == "OTHER": if self.__connection._in_transaction: self.__connection.commit() - elif self.__statement._kind == Statement._DML: - if not self.__connection._in_transaction: - self.__connection._begin() - - if multiple and self.__statement._kind != Statement._DML: - raise ProgrammingError("executemany is only for DML statements") + elif self.__statement._type == "SELECT": + if multiple: + raise ProgrammingError("You cannot execute SELECT " + "statements in executemany().") for params in many_params: self.__statement._set_params(params) @@ -1002,17 +1000,26 @@ self.__statement._reset() raise self.__connection._get_exception(ret) - if self.__statement._kind == Statement._DML: + if ret == _lib.SQLITE_ROW: + if multiple: + raise ProgrammingError("executemany() can only execute DML statements.") + self.__build_row_cast_map() + self.__next_row = self.__fetch_one_row() + elif ret == _lib.SQLITE_DONE and not multiple: self.__statement._reset() - if ret == _lib.SQLITE_ROW: - self.__build_row_cast_map() - self.__next_row = self.__fetch_one_row() - - if self.__statement._kind == Statement._DML: + if self.__statement._type in ("UPDATE", "DELETE", "INSERT", "REPLACE"): if self.__rowcount == -1: self.__rowcount = 0 self.__rowcount += _lib.sqlite3_changes(self.__connection._db) + + if not multiple and self.__statement._type == "INSERT": + self.__lastrowid = _lib.sqlite3_last_insert_rowid(self.__connection._db) + else: + self.__lastrowid = None + + if multiple: + self.__statement._reset() finally: self.__connection._in_transaction = \ not _lib.sqlite3_get_autocommit(self.__connection._db) @@ -1081,7 +1088,6 @@ next_row = self.__next_row except AttributeError: self.__statement._reset() - self.__statement = None raise StopIteration del self.__next_row @@ -1125,13 +1131,15 @@ rowcount = property(__get_rowcount) def __get_description(self): - if self.__description is None: + try: + return self.__description + except AttributeError: self.__description = self.__statement._get_description() - return self.__description + return self.__description description = property(__get_description) def __get_lastrowid(self): - return _lib.sqlite3_last_insert_rowid(self.__connection._db) + return self.__lastrowid lastrowid = property(__get_lastrowid) def setinputsizes(self, *args): @@ -1142,8 +1150,6 @@ class Statement(object): - _DML, _DQL, _DDL = range(3) - _statement = None def __init__(self, connection, sql): @@ -1154,13 +1160,14 @@ if not isinstance(sql, basestring): raise Warning("SQL is of wrong type. Must be string or unicode.") - first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() - if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): - self._kind = Statement._DML - elif first_word in ("SELECT", "PRAGMA"): - self._kind = Statement._DQL + + 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 else: - self._kind = Statement._DDL + self._type = "OTHER" if isinstance(sql, unicode): sql = sql.encode('utf-8') @@ -1173,11 +1180,12 @@ if ret == _lib.SQLITE_OK and not self._statement: # an empty statement, work around that, as it's the least trouble + self._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) self._statement = statement_star[0] - self._kind = Statement._DQL + if ret != _lib.SQLITE_OK: raise self.__con._get_exception(ret) @@ -1288,7 +1296,7 @@ raise ValueError("parameters are of unsupported type") def _get_description(self): - if self._kind == Statement._DML: + if self._type in ("INSERT", "UPDATE", "DELETE", "REPLACE"): return None desc = [] for i in xrange(_lib.sqlite3_column_count(self._statement)): @@ -1393,7 +1401,7 @@ elif typ == _lib.SQLITE_BLOB: blob = _lib.sqlite3_value_blob(params[i]) blob_len = _lib.sqlite3_value_bytes(params[i]) - val = _BLOB_TYPE(_ffi.buffer(blob, blob_len)) + val = _BLOB_TYPE(_ffi.buffer(blob, blob_len)[:]) else: raise NotImplementedError _params.append(val) diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -25,6 +25,7 @@ line = '' return '%s%s' % (line, self.args[0]) + class FFI(object): r''' The main top-level class that you instantiate once, or once per module. @@ -220,7 +221,7 @@ it as a string or unicode string. If 'cdata' is an enum, returns the value of the enumerator as a - string, or '#NUMBER' if the value is out of range. + string, or 'NUMBER' if the value is out of range. """ return self._backend.string(cdata, maxlen) diff --git a/pypy/doc/getting-started-python.rst b/pypy/doc/getting-started-python.rst --- a/pypy/doc/getting-started-python.rst +++ b/pypy/doc/getting-started-python.rst @@ -46,14 +46,14 @@ 2. Install build-time dependencies. On a Debian box these are:: [user@debian-box ~]$ sudo apt-get install \ - gcc make python-dev libffi-dev pkg-config \ + gcc make python-dev libffi-dev lib-sqlite3-dev pkg-config \ libz-dev libbz2-dev libncurses-dev libexpat1-dev \ libssl-dev libgc-dev python-sphinx python-greenlet On a Fedora-16 box these are:: [user@fedora-or-rh-box ~]$ sudo yum install \ - gcc make python-devel libffi-devel pkgconfig \ + gcc make python-devel libffi-devel lib-sqlite3-devel pkgconfig \ zlib-devel bzip2-devel ncurses-devel expat-devel \ openssl-devel gc-devel python-sphinx python-greenlet @@ -62,6 +62,7 @@ * ``pkg-config`` (to help us locate libffi files) * ``libz-dev`` (for the optional ``zlib`` module) * ``libbz2-dev`` (for the optional ``bz2`` module) + * ``libsqlite3-dev`` (for the optional ``sqlite3`` module via cffi) * ``libncurses-dev`` (for the optional ``_minimal_curses`` module) * ``libexpat1-dev`` (for the optional ``pyexpat`` module) * ``libssl-dev`` (for the optional ``_ssl`` module) diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -15,7 +15,7 @@ * `FAQ`_: some frequently asked questions. -* `Release 2.0 beta 1`_: the latest official release +* `Release 2.0 beta 2`_: the latest official release * `PyPy Blog`_: news and status info about PyPy @@ -75,7 +75,7 @@ .. _`Getting Started`: getting-started.html .. _`Papers`: extradoc.html .. _`Videos`: video-index.html -.. _`Release 2.0 beta 1`: http://pypy.org/download.html +.. _`Release 2.0 beta 2`: http://pypy.org/download.html .. _`speed.pypy.org`: http://speed.pypy.org .. _`RPython toolchain`: translation.html .. _`potential project ideas`: project-ideas.html diff --git a/pypy/doc/release-2.0.0-beta2.rst b/pypy/doc/release-2.0.0-beta2.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-2.0.0-beta2.rst @@ -0,0 +1,84 @@ +=============== +PyPy 2.0 beta 2 +=============== + +We're pleased to announce the 2.0 beta 2 release of PyPy. This is a major +release of PyPy and we're getting very close to 2.0 final, however it includes +quite a few new features that require further testing. Please test and report +issues, so we can have a rock-solid 2.0 final. It also includes a performance +regression of about 5% compared to 2.0 beta 1 that we hope to fix before +2.0 final. The ARM support is not working yet and we're working hard to +make it happen before the 2.0 final. The new major features are: + +* JIT now supports stackless features, that is greenlets and stacklets. This + means that JIT can now optimize the code that switches the context. It enables + running `eventlet`_ and `gevent`_ on PyPy (although gevent requires some + special support that's not quite finished, read below). + +* This is the first PyPy release that includes `cffi`_ as a core library. + Version 0.6 comes included in the PyPy library. cffi has seen a lot of + adoption among library authors and we believe it's the best way to wrap + C libaries. You can see examples of cffi usage in `_curses.py`_ and + `_sqlite3.py`_ in the PyPy source code. + +You can download the PyPy 2.0 beta 2 release here: + + http://pypy.org/download.html + +What is PyPy? +============= + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7.3. It's fast (`pypy 2.0 beta 2 and cpython 2.7.3`_ +performance comparison) due to its integrated tracing JIT compiler. + +This release supports x86 machines running Linux 32/64, Mac OS X 64 or +Windows 32. It also supports ARM machines running Linux, however this is +disabled for the beta 2 release. +Windows 64 work is still stalling, we would welcome a volunteer +to handle that. + +.. _`pypy 2.0 beta 2 and cpython 2.7.3`: http://bit.ly/USXqpP + +How to use PyPy? +================ + +We suggest using PyPy from a `virtualenv`_. Once you have a virtualenv +installed, you can follow instructions from `pypy documentation`_ on how +to proceed. This document also covers other `installation schemes`_. + +.. _`pypy documentation`: http://doc.pypy.org/en/latest/getting-started.html#installing-using-virtualenv +.. _`virtualenv`: http://www.virtualenv.org/en/latest/ +.. _`installation schemes`: http://doc.pypy.org/en/latest/getting-started.html#installing-pypy + +Highlights +========== + +* ``cffi`` is officially supported by PyPy. It comes included in the standard + library, just use ``import cffi`` + +* stackless support - `eventlet`_ just works and `gevent`_ requires `pypycore`_ + and `pypy-hacks`_ branch of gevent (which mostly disables cython-based + modules) + +* callbacks from C are now much faster. pyexpat is about 3x faster, cffi + callbacks around the same + +* ``__length_hint__`` is implemented (PEP 424) + +* a lot of numpy improvements + +Improvements since 1.9 +====================== + +* `JIT hooks`_ are now a powerful tool to introspect the JITting process that + PyPy performs + +* various performance improvements compared to 1.9 and 2.0 beta 1 + +* operations on ``long`` objects are now as fast as in CPython (from + roughly 2x slower) + +* we now have special strategies for ``dict``/``set``/``list`` which contain + unicode strings, which means that now such collections will be both faster + and more compact. diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst --- a/pypy/doc/windows.rst +++ b/pypy/doc/windows.rst @@ -111,6 +111,18 @@ cd bzip2-1.0.5 nmake -f makefile.msc +The sqlite3 database library +~~~~~~~~~~~~~~~~~~~~ + +Download http://www.sqlite.org/2013/sqlite-amalgamation-3071601.zip and extract +it into a directory under the base directory. Also get +http://www.sqlite.org/2013/sqlite-dll-win32-x86-3071601.zip and extract the dll +into the bin directory, and the sqlite3.def into the sources directory. +Now build the import library so cffi can use the header and dll:: + lib /DEF:sqlite3.def" /OUT:sqlite3.lib" + copy sqlite3.lib path\to\libs + + The expat XML parser ~~~~~~~~~~~~~~~~~~~~ diff --git a/pypy/module/cpyext/include/patchlevel.h b/pypy/module/cpyext/include/patchlevel.h --- a/pypy/module/cpyext/include/patchlevel.h +++ b/pypy/module/cpyext/include/patchlevel.h @@ -29,7 +29,7 @@ #define PY_VERSION "2.7.3" /* PyPy version as a string */ -#define PYPY_VERSION "2.0.0-beta1" +#define PYPY_VERSION "2.0.0-beta2" /* Subversion Revision number of this file (not of the repository). * Empty since Mercurial migration. */ diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py --- a/pypy/module/pyexpat/interp_pyexpat.py +++ b/pypy/module/pyexpat/interp_pyexpat.py @@ -305,14 +305,15 @@ w_result = space.call_function(handler, %(wargs)s) %(post_code)s except OperationError, e: - parser._exc_info = e + if not parser._exc_info: # don't override an existing exception + parser._exc_info = e XML_StopParser(parser.itself, XML_FALSE) return %(result_error)s return %(result_converter)s callback = %(name)s_callback """ % locals()) - exec str(src) + exec src.compile() c_name = 'XML_Set' + name callback_type = lltype.Ptr(lltype.FuncType( @@ -335,7 +336,8 @@ try: parser.UnknownEncodingHandler(space, name, info) except OperationError, e: - parser._exc_info = e + if parser._exc_info: + parser._exc_info = e XML_StopParser(parser.itself, XML_FALSE) result = 0 else: diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py --- a/pypy/module/pyexpat/test/test_parser.py +++ b/pypy/module/pyexpat/test/test_parser.py @@ -167,3 +167,46 @@ p = pyexpat.ParserCreate() p.ParseFile(fake_reader) assert fake_reader.read_count == 4 + +class AppTestPyexpat2: + spaceconfig = dict(usemodules=['pyexpat', 'itertools', '_socket', + 'rctime', 'struct', 'binascii']) + + def test_django_bug(self): + xml_str = '<?xml version="1.0" standalone="no"?><!DOCTYPE example SYSTEM "http://example.com/example.dtd"><root/>' + + from xml.dom import pulldom + from xml.sax import handler + from xml.sax.expatreader import ExpatParser as _ExpatParser + from StringIO import StringIO + + class DefusedExpatParser(_ExpatParser): + def start_doctype_decl(self, name, sysid, pubid, has_internal_subset): + raise DTDForbidden(name, sysid, pubid) + + def external_entity_ref_handler(self, context, base, sysid, pubid): + raise ExternalReferenceForbidden(context, base, sysid, pubid) + + def reset(self): + _ExpatParser.reset(self) + parser = self._parser + parser.StartDoctypeDeclHandler = self.start_doctype_decl + parser.ExternalEntityRefHandler = self.external_entity_ref_handler + + + class DTDForbidden(ValueError): + pass + + + class ExternalReferenceForbidden(ValueError): + pass + + stream = pulldom.parse(StringIO(xml_str), DefusedExpatParser()) + + try: + for event, node in stream: + print event, node + except DTDForbidden: + pass + else: + raise Exception("should raise DTDForbidden") diff --git a/pypy/module/sys/version.py b/pypy/module/sys/version.py --- a/pypy/module/sys/version.py +++ b/pypy/module/sys/version.py @@ -11,7 +11,7 @@ #XXX # sync CPYTHON_VERSION with patchlevel.h, package.py CPYTHON_API_VERSION = 1013 #XXX # sync with include/modsupport.h -PYPY_VERSION = (2, 0, 0, "beta", 1) #XXX # sync patchlevel.h +PYPY_VERSION = (2, 0, 0, "beta", 2) #XXX # sync patchlevel.h if platform.name == 'msvc': COMPILER_INFO = 'MSC v.%d 32 bit' % (platform.version * 10 + 600) diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_module/setup.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_module/setup.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_module/setup.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_module/setup.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py from distutils.core import setup import snip_basic_verify diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_module/snip_basic_verify.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_module/snip_basic_verify.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_module/snip_basic_verify.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_module/snip_basic_verify.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py from cffi import FFI import sys diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_1/setup.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_1/setup.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_1/setup.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_1/setup.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py from distutils.core import setup import snip_basic_verify1 diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_1/snip_basic_verify1/__init__.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_1/snip_basic_verify1/__init__.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_1/snip_basic_verify1/__init__.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_1/snip_basic_verify1/__init__.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py from cffi import FFI import sys diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_2/setup.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_2/setup.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_2/setup.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_2/setup.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py from distutils.core import setup import snip_basic_verify2 diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_2/snip_basic_verify2/__init__.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_2/snip_basic_verify2/__init__.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_2/snip_basic_verify2/__init__.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/distutils_package_2/snip_basic_verify2/__init__.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py from cffi import FFI import sys diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/infrastructure/setup.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/infrastructure/setup.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/infrastructure/setup.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/infrastructure/setup.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py from distutils.core import setup diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/infrastructure/snip_infrastructure/__init__.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/infrastructure/snip_infrastructure/__init__.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/infrastructure/snip_infrastructure/__init__.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/infrastructure/snip_infrastructure/__init__.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py def func(): return 42 diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_module/setup.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_module/setup.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_module/setup.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_module/setup.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py from setuptools import setup import snip_setuptools_verify diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_module/snip_setuptools_verify.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_module/snip_setuptools_verify.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_module/snip_setuptools_verify.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_module/snip_setuptools_verify.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py from cffi import FFI import sys diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_1/setup.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_1/setup.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_1/setup.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_1/setup.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py from setuptools import setup import snip_setuptools_verify1 diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_1/snip_setuptools_verify1/__init__.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_1/snip_setuptools_verify1/__init__.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_1/snip_setuptools_verify1/__init__.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_1/snip_setuptools_verify1/__init__.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py from cffi import FFI import sys diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_2/setup.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_2/setup.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_2/setup.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_2/setup.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py from setuptools import setup import snip_setuptools_verify2 diff --git a/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_2/snip_setuptools_verify2/__init__.py b/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_2/snip_setuptools_verify2/__init__.py --- a/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_2/snip_setuptools_verify2/__init__.py +++ b/pypy/module/test_lib_pypy/cffi_tests/snippets/setuptools_package_2/snip_setuptools_verify2/__init__.py @@ -1,3 +1,4 @@ +# Generated by pypy/tool/import_cffi.py from cffi import FFI import sys diff --git a/pypy/module/test_lib_pypy/test_sqlite3.py b/pypy/module/test_lib_pypy/test_sqlite3.py --- a/pypy/module/test_lib_pypy/test_sqlite3.py +++ b/pypy/module/test_lib_pypy/test_sqlite3.py @@ -198,3 +198,28 @@ con = _sqlite3.connect(':memory:') con.row_factory = 42 con.execute('select 1') + +def test_returning_blob_must_own_memory(): + import gc + con = _sqlite3.connect(":memory:") + con.create_function("returnblob", 0, lambda: buffer("blob")) + cur = con.cursor() + cur.execute("select returnblob()") + val = cur.fetchone()[0] + for i in range(5): + gc.collect() + got = (val[0], val[1], val[2], val[3]) + assert got == ('b', 'l', 'o', 'b') + +def test_description_after_fetchall(): + con = _sqlite3.connect(":memory:") + cur = con.cursor() + cur.execute("select 42").fetchall() + assert cur.description is not None + +def test_executemany_lastrowid(): + con = _sqlite3.connect(':memory:') + cur = con.cursor() + cur.execute("create table test(a)") + cur.executemany("insert into test values (?)", [[1], [2], [3]]) + assert cur.lastrowid is None diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py --- a/pypy/tool/release/package.py +++ b/pypy/tool/release/package.py @@ -43,6 +43,7 @@ def fix_permissions(basedir): if sys.platform != 'win32': os.system("chmod -R a+rX %s" % basedir) + os.system("chmod -R g-w %s" % basedir) def package(basedir, name='pypy-nightly', rename_pypy_c='pypy', copy_to_dir = None, override_pypy_c = None, nostrip=False): diff --git a/pypy/tool/test/test_tab.py b/pypy/tool/test/test_tab.py --- a/pypy/tool/test/test_tab.py +++ b/pypy/tool/test/test_tab.py @@ -5,7 +5,7 @@ import os from pypy.conftest import pypydir -ROOT = pypydir +ROOT = os.path.abspath(os.path.join(pypydir, '..')) EXCLUDE = {} diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -305,7 +305,7 @@ self._restore_exception(mc, exc0, exc1) mc.VPOP([vfpr.value for vfpr in r.caller_vfp_resp]) assert exc0 is not None - assert exc1 is not None + assert exc1 is not None mc.POP([gpr.value for gpr in r.caller_resp] + [exc0.value, exc1.value]) # @@ -526,9 +526,7 @@ self.gen_shadowstack_header(gcrootmap) def gen_shadowstack_header(self, gcrootmap): - # we need to put two words into the shadowstack: the MARKER_FRAME - # and the address of the frame (fp, actually) - # lr = rst addr + # lr = shadow stack top addr # ip = *lr rst = gcrootmap.get_root_stack_top_addr() self.mc.gen_load_int(r.lr.value, rst) @@ -1062,8 +1060,7 @@ self.mc.PUSH([helper.value], cond=cond) self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=helper) if save_helper: - self.mc.POP([helper.value], cond=cond) - + self.mc.POP([helper.value], cond=cond) def _mov_imm_float_to_loc(self, prev_loc, loc, cond=c.AL): if loc.is_vfp_reg(): diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -628,12 +628,14 @@ bool(self._regalloc.vfprm.reg_bindings)) assert self.wb_slowpath[helper_num] != 0 # - if not is_frame and loc_base is not r.r0: + if loc_base is not r.r0: # push two registers to keep stack aligned mc.PUSH([r.r0.value, loc_base.value]) - remap_frame_layout(self, [loc_base], [r.r0], r.ip) + mc.MOV_rr(r.r0.value, loc_base.value) + if is_frame: + assert loc_base is r.fp mc.BL(self.wb_slowpath[helper_num]) - if not is_frame and loc_base is not r.r0: + if loc_base is not r.r0: mc.POP([r.r0.value, loc_base.value]) if card_marking: diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py --- a/rpython/jit/backend/arm/runner.py +++ b/rpython/jit/backend/arm/runner.py @@ -120,7 +120,7 @@ """ARM v7 uses hardfp ABI, requires vfp""" hf_abi = True backend_name = "armv7hf" - supports_floats = False + supports_floats = True supports_singlefloats = False @@ -129,5 +129,5 @@ hf_abi = True arch_version = 6 backend_name = "armv6hf" - supports_floats = False + supports_floats = True supports_singlefloats = False diff --git a/rpython/jit/backend/arm/test/test_calling_convention.py b/rpython/jit/backend/arm/test/test_calling_convention.py --- a/rpython/jit/backend/arm/test/test_calling_convention.py +++ b/rpython/jit/backend/arm/test/test_calling_convention.py @@ -72,7 +72,7 @@ callargs = [] def func(f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9): callargs.append(zip(range(12), - [f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9])) + [f0, f1, f2, f3, f4, f5, f6, i0, f7, i1, f8, f9])) return f0 + f1 + f2 + f3 + f4 + f5 + f6 + float(i0 + i1) + f7 + f8 + f9 F = lltype.Float I = lltype.Signed @@ -103,7 +103,7 @@ callargs = [] def func(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9): callargs.append(zip(range(10), - [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9])) + [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9])) return f0 + f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 F = lltype.Float FUNC = self.FuncType([F] * 10, F) @@ -125,7 +125,7 @@ callargs = [] def func(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9): callargs.append(zip(range(10), - [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9])) + [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9])) return f0 + f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 I = lltype.Signed diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -256,7 +256,9 @@ if self.cpu.IS_64_BIT: assert frame.jf_gcmap[idx] == (1<<29) | (1 << 30) else: - assert frame.jf_gcmap[idx] == (1<<24) | (1 << 23) + assert frame.jf_gcmap[idx] + exp_idx = self.cpu.JITFRAME_FIXED_SIZE - 32 * idx + 1 # +1 from i0 + assert frame.jf_gcmap[idx] == (1 << (exp_idx + 1)) | (1 << exp_idx) self.cpu = self.getcpu(check) ops = ''' @@ -680,7 +682,7 @@ def f(frame, x): # all the gc pointers are alive p1 -> p7 (but not p0) - assert bin(frame.jf_gcmap[0]).count('1') == 7 + assert getmap(frame).count('1') == 7 # assert x == 1 return 2 @@ -713,7 +715,7 @@ def f(frame, arg, x): assert not arg assert frame.jf_gcmap[0] & 31 == 0 - assert bin(frame.jf_gcmap[0]).count('1') == 3 # p1, p2, p3, but + assert getmap(frame).count('1') == 3 # p1, p2, p3, but # not in registers frame.jf_descr = frame.jf_force_descr # make guard_not_forced fail assert x == 1 @@ -749,7 +751,8 @@ cpu.compile_loop(loop.inputargs, loop.operations, token) frame = lltype.cast_opaque_ptr(JITFRAMEPTR, cpu.execute_token(token, 1, a)) - assert bin(frame.jf_gcmap[0]).count('1') == 4 + + assert getmap(frame).count('1') == 4 def test_call_gcmap_no_guard(self): cpu = self.cpu @@ -757,7 +760,7 @@ def f(frame, arg, x): assert not arg assert frame.jf_gcmap[0] & 31 == 0 - assert bin(frame.jf_gcmap[0]).count('1') == 3 # p1, p2, p3 + assert getmap(frame).count('1') == 3 # p1, p2, p3 frame.jf_descr = frame.jf_force_descr # make guard_not_forced fail assert x == 1 return lltype.nullptr(llmemory.GCREF.TO) @@ -792,4 +795,5 @@ cpu.compile_loop(loop.inputargs, loop.operations, token) frame = lltype.cast_opaque_ptr(JITFRAMEPTR, cpu.execute_token(token, 1, a)) - assert bin(frame.jf_gcmap[0]).count('1') == 4 + assert getmap(frame).count('1') == 4 + diff --git a/rpython/jit/backend/test/calling_convention_test.py b/rpython/jit/backend/test/calling_convention_test.py --- a/rpython/jit/backend/test/calling_convention_test.py +++ b/rpython/jit/backend/test/calling_convention_test.py @@ -384,7 +384,7 @@ def test_call_aligned_explicit_check(self): if (not platform.machine().startswith('arm') and - sys.maxint == 2 ** 31 - 1): # XXX is still necessary on x86? + sys.maxint == 2 ** 31 - 1): # XXX is still necessary on x86? py.test.skip("libffi on 32bit is broken") cpu = self.cpu if not cpu.supports_floats: diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -58,10 +58,10 @@ self.assembler = Assembler386(self, self.translate_support_code) def build_regalloc(self): - ''' for tests''' - from rpython.jit.backend.x86.regalloc import RegAlloc - assert self.assembler is not None - return RegAlloc(self.assembler, False) + ''' for tests''' + from rpython.jit.backend.x86.regalloc import RegAlloc + assert self.assembler is not None + return RegAlloc(self.assembler, False) def setup_once(self): self.profile_agent.startup() diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py @@ -4282,9 +4282,9 @@ self.optimize_loop(ops, expected) def test_add_sub_ovf_second_operation_regular(self): - py.test.skip("Smalltalk would like this to pass") - # This situation occurs in Smalltalk because it uses 1-based indexing. - # The below code is equivalent to a loop over an array. + py.test.skip("Smalltalk would like this to pass") + # This situation occurs in Smalltalk because it uses 1-based indexing. + # The below code is equivalent to a loop over an array. ops = """ [i1] i2 = int_sub(i1, 1) @@ -7609,6 +7609,26 @@ """ self.optimize_loop(ops, ops) + def test_setarrayitem_followed_by_arraycopy_2(self): + ops = """ + [i1, i2] + p1 = new_array(i1, descr=arraydescr) + setarrayitem_gc(p1, 0, i2, descr=arraydescr) + p3 = new_array(5, descr=arraydescr) + call(0, p1, p3, 0, 1, 1, descr=arraycopydescr) + i4 = getarrayitem_gc(p3, 1, descr=arraydescr) + jump(i1, i4) + """ + expected = """ + [i1, i2] + p1 = new_array(i1, descr=arraydescr) + # operations are not all removed because this new_array() is var-sized + # unsure exactly which operations should be left, but right now it's + # really buggy + jump(i1, i2) + """ + self.optimize_loop(ops, expected) + def test_heap_cache_virtuals_forced_by_delayed_setfield(self): py.test.skip('not yet supoprted') ops = """ diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -80,7 +80,7 @@ def __del__(self): if self.addr_p: - lltype.free(self.addr_p, flavor='raw') + lltype.free(self.addr_p, flavor='raw', track_allocation=False) def setdata(self, addr, addrlen): # initialize self.addr and self.addrlen. 'addr' can be a different @@ -271,7 +271,8 @@ result = instantiate(INETAddress) # store the malloc'ed data into 'result' as soon as possible # to avoid leaks if an exception occurs inbetween - sin = lltype.malloc(_c.sockaddr_in, flavor='raw', zero=True) + sin = lltype.malloc(_c.sockaddr_in, flavor='raw', zero=True, + track_allocation=False) result.setdata(sin, sizeof(_c.sockaddr_in)) # PLAT sin_len rffi.setintfield(sin, 'c_sin_family', AF_INET) @@ -337,7 +338,8 @@ result = instantiate(INET6Address) # store the malloc'ed data into 'result' as soon as possible # to avoid leaks if an exception occurs inbetween - sin = lltype.malloc(_c.sockaddr_in6, flavor='raw', zero=True) + sin = lltype.malloc(_c.sockaddr_in6, flavor='raw', zero=True, + track_allocation=False) result.setdata(sin, sizeof(_c.sockaddr_in6)) rffi.setintfield(sin, 'c_sin6_family', AF_INET6) rffi.structcopy(sin.c_sin6_addr, in6_addr) @@ -360,7 +362,8 @@ maxlen = sizeof(struct) def __init__(self, path): - sun = lltype.malloc(_c.sockaddr_un, flavor='raw', zero=True) + sun = lltype.malloc(_c.sockaddr_un, flavor='raw', zero=True, + track_allocation=False) baseofs = offsetof(_c.sockaddr_un, 'c_sun_path') self.setdata(sun, baseofs + len(path)) rffi.setintfield(sun, 'c_sun_family', AF_UNIX) @@ -409,7 +412,8 @@ maxlen = minlen = sizeof(struct) def __init__(self, pid, groups): - addr = lltype.malloc(_c.sockaddr_nl, flavor='raw', zero=True) + addr = lltype.malloc(_c.sockaddr_nl, flavor='raw', zero=True, + track_allocation=False) self.setdata(addr, NETLINKAddress.maxlen) rffi.setintfield(addr, 'c_nl_family', AF_NETLINK) rffi.setintfield(addr, 'c_nl_pid', pid) @@ -444,7 +448,8 @@ raise RSocketError("address family mismatched") # copy into a new buffer the address that 'addrptr' points to addrlen = rffi.cast(lltype.Signed, addrlen) - buf = lltype.malloc(rffi.CCHARP.TO, addrlen, flavor='raw') + buf = lltype.malloc(rffi.CCHARP.TO, addrlen, flavor='raw', + track_allocation=False) src = rffi.cast(rffi.CCHARP, addrptr) for i in range(addrlen): buf[i] = src[i] @@ -456,7 +461,8 @@ result = instantiate(INETAddress) elif result.family != AF_INET: raise RSocketError("address family mismatched") - sin = lltype.malloc(_c.sockaddr_in, flavor='raw', zero=True) + sin = lltype.malloc(_c.sockaddr_in, flavor='raw', zero=True, + track_allocation=False) result.setdata(sin, sizeof(_c.sockaddr_in)) rffi.setintfield(sin, 'c_sin_family', AF_INET) # PLAT sin_len rffi.setintfield(sin.c_sin_addr, 'c_s_addr', s_addr) @@ -465,7 +471,8 @@ def make_null_address(family): klass = familyclass(family) result = instantiate(klass) - buf = lltype.malloc(rffi.CCHARP.TO, klass.maxlen, flavor='raw', zero=True) + buf = lltype.malloc(rffi.CCHARP.TO, klass.maxlen, flavor='raw', zero=True, + track_allocation=False) # Initialize the family to the correct value. Avoids surprizes on # Windows when calling a function that unexpectedly does not set # the output address (e.g. recvfrom() on a connected IPv4 socket). diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -934,10 +934,8 @@ if tp is lltype.SingleFloat: return 4 if tp is lltype.LongFloat: - if globals()['r_void*'].BITS == 32: - return 12 - else: - return 16 + import ctypes # :-/ + return ctypes.sizeof(ctypes.c_longdouble) assert isinstance(tp, lltype.Number) if tp is lltype.Signed: return LONG_BIT/8 _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit