Author: Maciej Fijalkowski <fij...@gmail.com> Branch: Changeset: r63055:1f9677f6bba1 Date: 2013-04-05 14:13 +0200 http://bitbucket.org/pypy/pypy/changeset/1f9677f6bba1/
Log: merge diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -29,6 +29,7 @@ import string import sys import weakref +import array from threading import _get_ident as _thread_get_ident try: from __pypy__ import newlist_hint @@ -218,7 +219,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); @@ -958,7 +959,11 @@ 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)) + # make a copy of the data into an array, in order to get + # a read-write buffer in the end, and one that own the + # memory for a more predictable length of time than 'blob' + copy = array.array("c", _ffi.buffer(blob, blob_len)) + val = _BLOB_TYPE(copy) row.append(val) return tuple(row) 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/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/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,15 @@ 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') 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