Author: Carl Friedrich Bolz-Tereick <cfb...@gmx.de> Branch: py3.7 Changeset: r98528:54bf5e2f78e0 Date: 2020-01-14 13:15 +0100 http://bitbucket.org/pypy/pypy/changeset/54bf5e2f78e0/
Log: merge py3.6 diff --git a/extra_tests/cffi_tests/cffi0/backend_tests.py b/extra_tests/cffi_tests/cffi0/backend_tests.py --- a/extra_tests/cffi_tests/cffi0/backend_tests.py +++ b/extra_tests/cffi_tests/cffi0/backend_tests.py @@ -1242,7 +1242,7 @@ py.test.skip(str(e)) f.write(ffi.buffer(a, 1000 * ffi.sizeof("int"))) f.seek(0) - assert f.read() == array.array('i', range(1000)).tostring() + assert f.read() == arraytostring(array.array('i', range(1000))) f.seek(0) b = ffi.new("int[]", 1005) f.readinto(ffi.buffer(b, 1000 * ffi.sizeof("int"))) @@ -1261,7 +1261,7 @@ py.test.skip(str(e)) f.write(ffi.buffer(a, 1000 * ffi.sizeof("int"))) f.seek(0) - assert f.read() == array.array('i', range(1000)).tostring() + assert f.read() == arraytostring(array.array('i', range(1000))) f.seek(0) b = ffi.new("int[]", 1005) f.readinto(ffi.buffer(b, 1000 * ffi.sizeof("int"))) diff --git a/extra_tests/cffi_tests/cffi0/test_zdistutils.py b/extra_tests/cffi_tests/cffi0/test_zdistutils.py --- a/extra_tests/cffi_tests/cffi0/test_zdistutils.py +++ b/extra_tests/cffi_tests/cffi0/test_zdistutils.py @@ -90,7 +90,7 @@ csrc = '/*hi there %s!2*/\n#include <math.h>\n' % self v = Verifier(ffi, csrc, force_generic_engine=self.generic, libraries=[self.lib_m]) - basename = self.__class__.__name__ + 'test_compile_module' + basename = self.__class__.__name__[:10] + '_test_compile_module' v.modulefilename = filename = str(udir.join(basename + '.so')) v.compile_module() assert filename == v.modulefilename diff --git a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py --- a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py +++ b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py @@ -1221,7 +1221,7 @@ py.test.skip(str(e)) f.write(ffi.buffer(a, 1000 * ffi.sizeof("int"))) f.seek(0) - assert f.read() == array.array('i', range(1000)).tostring() + assert f.read() == arraytostring(array.array('i', range(1000))) f.seek(0) b = ffi.new("int[]", 1005) f.readinto(ffi.buffer(b, 1000 * ffi.sizeof("int"))) @@ -1239,7 +1239,7 @@ py.test.skip(str(e)) f.write(ffi.buffer(a, 1000 * ffi.sizeof("int"))) f.seek(0) - assert f.read() == array.array('i', range(1000)).tostring() + assert f.read() == arraytostring(array.array('i', range(1000))) f.seek(0) b = ffi.new("int[]", 1005) f.readinto(ffi.buffer(b, 1000 * ffi.sizeof("int"))) diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py --- a/extra_tests/cffi_tests/cffi1/test_recompiler.py +++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py @@ -27,13 +27,14 @@ def verify(ffi, module_name, source, *args, **kwds): no_cpp = kwds.pop('no_cpp', False) + ignore_warnings = kwds.pop('ignore_warnings', False) kwds.setdefault('undef_macros', ['NDEBUG']) module_name = '_CFFI_' + module_name ffi.set_source(module_name, source) if not os.environ.get('NO_CPP') and not no_cpp: # test the .cpp mode too kwds.setdefault('source_extension', '.cpp') source = 'extern "C" {\n%s\n}' % (source,) - elif sys.platform != 'win32': + elif sys.platform != 'win32' and not ignore_warnings: # add '-Werror' to the existing 'extra_compile_args' flags from extra_tests.cffi_tests.support import extra_compile_args kwds['extra_compile_args'] = (kwds.get('extra_compile_args', []) + @@ -137,7 +138,8 @@ import math ffi = FFI() ffi.cdef("float sin(double); double cos(double);") - lib = verify(ffi, 'test_math_sin', '#include <math.h>') + lib = verify(ffi, 'test_math_sin', '#include <math.h>', + ignore_warnings=True) assert lib.cos(1.43) == math.cos(1.43) def test_repr_lib(): @@ -646,7 +648,7 @@ ffi.cdef("sshort_t ff3(sshort_t);") lib = verify(ffi, "test_include_3", "typedef short sshort_t; //usually from a #include\n" - "sshort_t ff3(sshort_t x) { return x + 42; }") + "sshort_t ff3(sshort_t x) { return (sshort_t)(x + 42); }") assert lib.ff3(10) == 52 assert ffi.typeof(ffi.cast("sshort_t", 42)) is ffi.typeof("short") assert ffi1.typeof("sshort_t") is ffi.typeof("sshort_t") @@ -755,7 +757,7 @@ ffi = FFI() ffi.cdef(unicode("float sin(double); double cos(double);")) lib = verify(ffi, 'test_math_sin_unicode', unicode('#include <math.h>'), - libraries=[unicode(lib_m)]) + libraries=[unicode(lib_m)], ignore_warnings=True) assert lib.cos(1.43) == math.cos(1.43) def test_incomplete_struct_as_arg(): @@ -883,15 +885,20 @@ e5 = py.test.raises(TypeError, lib.foo2) e6 = py.test.raises(TypeError, lib.foo2, 42) e7 = py.test.raises(TypeError, lib.foo2, 45, 46, 47) - assert str(e1.value) == "foo0() takes no arguments (1 given)" - assert str(e2.value) == "foo0() takes no arguments (2 given)" - assert str(e3.value) == "foo1() takes exactly one argument (0 given)" - assert str(e4.value) == "foo1() takes exactly one argument (2 given)" - assert str(e5.value) in ["foo2 expected 2 arguments, got 0", + def st1(s): + s = str(s) + if s.startswith("_CFFI_test_unpack_args.CompiledLib."): + s = s[len("_CFFI_test_unpack_args.CompiledLib."):] + return s + assert st1(e1.value) == "foo0() takes no arguments (1 given)" + assert st1(e2.value) == "foo0() takes no arguments (2 given)" + assert st1(e3.value) == "foo1() takes exactly one argument (0 given)" + assert st1(e4.value) == "foo1() takes exactly one argument (2 given)" + assert st1(e5.value) in ["foo2 expected 2 arguments, got 0", "foo2() takes exactly 2 arguments (0 given)"] - assert str(e6.value) in ["foo2 expected 2 arguments, got 1", + assert st1(e6.value) in ["foo2 expected 2 arguments, got 1", "foo2() takes exactly 2 arguments (1 given)"] - assert str(e7.value) in ["foo2 expected 2 arguments, got 3", + assert st1(e7.value) in ["foo2 expected 2 arguments, got 3", "foo2() takes exactly 2 arguments (3 given)"] def test_address_of_function(): @@ -899,7 +906,7 @@ ffi.cdef("long myfunc(long x);") lib = verify(ffi, "test_addressof_function", """ char myfunc(char x) { return (char)(x + 42); } - """) + """, ignore_warnings=True) assert lib.myfunc(5) == 47 assert lib.myfunc(0xABC05) == 47 assert not isinstance(lib.myfunc, ffi.CData) @@ -1172,7 +1179,7 @@ lib = verify(ffi, 'test_some_float_invalid_3', """ typedef long double foo_t; foo_t neg(foo_t x) { return -x; } - """) + """, ignore_warnings=True) if ffi.sizeof("long double") == ffi.sizeof("double"): assert lib.neg(12.3) == -12.3 else: @@ -1846,7 +1853,7 @@ ffi = FFI() ffi.cdef("float f1(double);") lib = verify(ffi, 'test_introspect_function', """ - float f1(double x) { return x; } + float f1(double x) { return (float)x; } """) assert dir(lib) == ['f1'] FUNC = ffi.typeof(lib.f1) @@ -2151,7 +2158,8 @@ lib = verify(ffi, "test_call_with_nested_anonymous_struct", """ struct foo { int a; union { int b, c; }; }; struct foo f(void) { - struct foo s = { 40 }; + struct foo s; + s.a = 40; s.b = 200; return s; } diff --git a/extra_tests/cffi_tests/support.py b/extra_tests/cffi_tests/support.py --- a/extra_tests/cffi_tests/support.py +++ b/extra_tests/cffi_tests/support.py @@ -2,7 +2,7 @@ import sys, os if sys.version_info < (3,): - __all__ = ['u'] + __all__ = ['u', 'arraytostring'] class U(object): def __add__(self, other): @@ -13,12 +13,16 @@ assert u+'a\x00b' == eval(r"u'a\x00b'") assert u+'a\u1234b' == eval(r"u'a\u1234b'") assert u+'a\U00012345b' == eval(r"u'a\U00012345b'") + def arraytostring(a): + return a.tostring() else: - __all__ = ['u', 'unicode', 'long'] + __all__ = ['u', 'unicode', 'long', 'arraytostring'] u = "" unicode = str long = int + def arraytostring(a): + return a.tobytes() class StdErrCapture(object): diff --git a/extra_tests/test_sqlite3.py b/extra_tests/test_sqlite3.py --- a/extra_tests/test_sqlite3.py +++ b/extra_tests/test_sqlite3.py @@ -88,8 +88,7 @@ with pytest.raises(StopIteration): next(cur) - with pytest.raises(_sqlite3.ProgrammingError): - cur.executemany('select 1', []) + cur.executemany('select 1', []) with pytest.raises(StopIteration): next(cur) @@ -201,8 +200,8 @@ def test_explicit_begin(con): con.execute('BEGIN') - con.execute('BEGIN ') - con.execute('BEGIN') + with pytest.raises(_sqlite3.OperationalError): + con.execute('BEGIN ') con.commit() con.execute('BEGIN') con.commit() @@ -212,7 +211,6 @@ con.execute('select 1') def test_returning_blob_must_own_memory(con): - import gc con.create_function("returnblob", 0, lambda: memoryview(b"blob")) cur = con.execute("select returnblob()") val = cur.fetchone()[0] @@ -228,15 +226,15 @@ cur = con.cursor() cur.execute("create table test(a)") cur.executemany("insert into test values (?)", [[1], [2], [3]]) - assert cur.lastrowid is None + assert cur.lastrowid == 0 # issue 2682 cur.execute('''insert into test values (?) ''', (1, )) - assert cur.lastrowid is not None + assert cur.lastrowid cur.execute('''insert\t into test values (?) ''', (1, )) - assert cur.lastrowid is not None + assert cur.lastrowid def test_authorizer_bad_value(con): def authorizer_cb(action, arg1, arg2, dbname, source): @@ -312,3 +310,24 @@ gc.collect() gc.collect() assert SQLiteBackend.success + +def test_locked_table(con): + con.execute("CREATE TABLE foo(x)") + con.execute("INSERT INTO foo(x) VALUES (?)", [42]) + cur = con.execute("SELECT * FROM foo") # foo() is locked while cur is active + with pytest.raises(_sqlite3.OperationalError): + con.execute("DROP TABLE foo") + +def test_cursor_close(con): + con.execute("CREATE TABLE foo(x)") + con.execute("INSERT INTO foo(x) VALUES (?)", [42]) + cur = con.execute("SELECT * FROM foo") + cur.close() + con.execute("DROP TABLE foo") # no error + +def test_cursor_del(con): + con.execute("CREATE TABLE foo(x)") + con.execute("INSERT INTO foo(x) VALUES (?)", [42]) + con.execute("SELECT * FROM foo") + import gc; gc.collect() + con.execute("DROP TABLE foo") # no error diff --git a/lib-python/3/sqlite3/test/regression.py b/lib-python/3/sqlite3/test/regression.py --- a/lib-python/3/sqlite3/test/regression.py +++ b/lib-python/3/sqlite3/test/regression.py @@ -127,6 +127,7 @@ con.execute("create table foo(bar timestamp)") con.execute("insert into foo(bar) values (?)", (datetime.datetime.now(),)) con.execute(SELECT) + support.gc_collect() # PyPy change con.execute("drop table foo") con.execute("create table foo(bar integer)") con.execute("insert into foo(bar) values (5)") diff --git a/lib_pypy/_curses_build.py b/lib_pypy/_curses_build.py --- a/lib_pypy/_curses_build.py +++ b/lib_pypy/_curses_build.py @@ -6,9 +6,7 @@ static const int NCURSES_VERSION_MINOR; ''' -version = (0, 0) def find_library(options): - global version for library in options: ffi = FFI() ffi.cdef(version_str) @@ -17,7 +15,6 @@ ffi.compile() import _curses_cffi_check lib = _curses_cffi_check.lib - version = (lib.NCURSES_VERSION_MAJOR, lib.NCURSES_VERSION_MINOR) except VerificationError as e: e_last = e continue @@ -385,7 +382,7 @@ void _m_getsyx(int *yx); """) -if version > (5, 7): +if 'ncursesw' in libs: ffi.cdef(""" typedef int... wint_t; int wget_wch(WINDOW *, wint_t *); diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -233,7 +233,6 @@ self.text_factory = _unicode_text_factory self._detect_types = detect_types - self._in_transaction = False self.isolation_level = isolation_level self.__cursors = [] @@ -433,7 +432,7 @@ def _begin(self): statement_star = _ffi.new('sqlite3_stmt **') - ret = _lib.sqlite3_prepare_v2(self._db, self.__begin_statement, -1, + ret = _lib.sqlite3_prepare_v2(self._db, self._begin_statement, -1, statement_star, _ffi.NULL) try: if ret != _lib.SQLITE_OK: @@ -441,14 +440,13 @@ ret = _lib.sqlite3_step(statement_star[0]) if ret != _lib.SQLITE_DONE: raise self._get_exception(ret) - self._in_transaction = True finally: _lib.sqlite3_finalize(statement_star[0]) def commit(self): self._check_thread() self._check_closed() - if not self._in_transaction: + if not self.in_transaction: return # PyPy fix for non-refcounting semantics: since 2.7.13 (and in @@ -473,14 +471,13 @@ ret = _lib.sqlite3_step(statement_star[0]) if ret != _lib.SQLITE_DONE: raise self._get_exception(ret) - self._in_transaction = False finally: _lib.sqlite3_finalize(statement_star[0]) def rollback(self): self._check_thread() self._check_closed() - if not self._in_transaction: + if not self.in_transaction: return self.__do_all_statements(Statement._reset, True) @@ -494,7 +491,6 @@ ret = _lib.sqlite3_step(statement_star[0]) if ret != _lib.SQLITE_DONE: raise self._get_exception(ret) - self._in_transaction = False finally: _lib.sqlite3_finalize(statement_star[0]) @@ -687,10 +683,10 @@ self.__func_cache[callable] = trace_callback _lib.sqlite3_trace(self._db, trace_callback, _ffi.NULL) - if sys.version_info[0] >= 3: - def __get_in_transaction(self): - return self._in_transaction - in_transaction = property(__get_in_transaction) + @property + @_check_closed_wrap + def in_transaction(self): + return not _lib.sqlite3_get_autocommit(self._db) def __get_total_changes(self): self._check_closed() @@ -710,7 +706,7 @@ stmt = str("BEGIN " + val).upper() if stmt not in BEGIN_STATMENTS: raise ValueError("invalid value for isolation_level") - self.__begin_statement = stmt.encode('utf-8') + self._begin_statement = stmt.encode('utf-8') self._isolation_level = val isolation_level = property(__get_isolation_level, __set_isolation_level) @@ -745,6 +741,11 @@ self.__initialized = True + def __del__(self): + # Since statements are cached, they can outlive their parent cursor + if self.__statement: + self.__statement._reset() + def close(self): if not self.__initialized: raise ProgrammingError("Base Cursor.__init__ not called.") @@ -876,24 +877,13 @@ except AttributeError: pass self.__rowcount = -1 + if self.__statement: + self.__statement._reset() self.__statement = self.__connection._statement_cache.get(sql) - if self.__connection._isolation_level is not None: - 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 == _STMT_TYPE_OTHER: - if self.__connection._in_transaction: - self.__connection.commit() - elif self.__statement._type == _STMT_TYPE_SELECT: - if multiple: - raise ProgrammingError("You cannot execute SELECT " - "statements in executemany().") + if self.__connection._begin_statement and self.__statement._is_dml: + if _lib.sqlite3_get_autocommit(self.__connection._db): + self.__connection._begin() for params in many_params: self.__statement._set_params(params) @@ -911,6 +901,16 @@ self.__connection._reset_already_committed_statements() ret = _lib.sqlite3_step(self.__statement._statement) + if self.__statement._is_dml: + if self.__rowcount == -1: + self.__rowcount = 0 + self.__rowcount += _lib.sqlite3_changes(self.__connection._db) + else: + self.__rowcount = -1 + + if not multiple: + self.__lastrowid = _lib.sqlite3_last_insert_rowid(self.__connection._db) + if ret == _lib.SQLITE_ROW: if multiple: raise ProgrammingError("executemany() can only execute DML statements.") @@ -923,28 +923,9 @@ self.__statement._reset() raise self.__connection._get_exception(ret) - 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 in ( - # REPLACE is an alias for INSERT OR REPLACE - _STMT_TYPE_INSERT, _STMT_TYPE_REPLACE): - 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) self.__locked = False return self @@ -1086,38 +1067,19 @@ if '\0' in sql: raise ValueError("the query contains a null character") - - if sql: - first_word = sql.lstrip().split()[0].upper() - if first_word == '': - self._type = _STMT_TYPE_INVALID - if 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 = _STMT_TYPE_OTHER - else: - self._type = _STMT_TYPE_INVALID + to_check = sql.lstrip().upper() + self._valid = bool(to_check) + self._is_dml = to_check.startswith(('INSERT', 'UPDATE', 'DELETE', 'REPLACE')) - if isinstance(sql, unicode): - sql = sql.encode('utf-8') statement_star = _ffi.new('sqlite3_stmt **') next_char = _ffi.new('char **') - c_sql = _ffi.new("char[]", sql) + c_sql = _ffi.new("char[]", sql.encode('utf-8')) ret = _lib.sqlite3_prepare_v2(self.__con._db, c_sql, -1, statement_star, next_char) self._statement = statement_star[0] if ret == _lib.SQLITE_OK and not self._statement: # an empty statement, work around that, as it's the least trouble - 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) @@ -1238,12 +1200,7 @@ raise ValueError("parameters are of unsupported type") def _get_description(self): - if self._type in ( - _STMT_TYPE_INSERT, - _STMT_TYPE_UPDATE, - _STMT_TYPE_DELETE, - _STMT_TYPE_REPLACE - ): + if self._is_dml: return None desc = [] for i in xrange(_lib.sqlite3_column_count(self._statement)): diff --git a/lib_pypy/cffi/recompiler.py b/lib_pypy/cffi/recompiler.py --- a/lib_pypy/cffi/recompiler.py +++ b/lib_pypy/cffi/recompiler.py @@ -1216,7 +1216,8 @@ size_of_result = '(int)sizeof(%s)' % ( tp.result.get_c_name('', context),) prnt('static struct _cffi_externpy_s _cffi_externpy__%s =' % name) - prnt(' { "%s.%s", %s };' % (self.module_name, name, size_of_result)) + prnt(' { "%s.%s", %s, 0, 0 };' % ( + self.module_name, name, size_of_result)) prnt() # arguments = [] diff --git a/pypy/doc/whatsnew-pypy3-head.rst b/pypy/doc/whatsnew-pypy3-head.rst --- a/pypy/doc/whatsnew-pypy3-head.rst +++ b/pypy/doc/whatsnew-pypy3-head.rst @@ -8,3 +8,7 @@ .. branch: cpyext-speedup-tests-py36 Make cpyext test faster, especially on py3.6 + +.. branch: py3.6-sqlite + +Follow CPython's behaviour more closely in sqlite3 diff --git a/pypy/module/__builtin__/abstractinst.py b/pypy/module/__builtin__/abstractinst.py --- a/pypy/module/__builtin__/abstractinst.py +++ b/pypy/module/__builtin__/abstractinst.py @@ -202,6 +202,19 @@ return BaseObjSpace.exception_getclass(space, w_obj) def exception_issubclass_w(space, w_cls1, w_cls2): + if (space.type(w_cls1) is space.w_type and + space.type(w_cls2) is space.w_type): + return BaseObjSpace.exception_issubclass_w(space, w_cls1, w_cls2) + # + if (not exception_is_valid_class_w(space, w_cls2) or + not exception_is_valid_class_w(space, w_cls1)): + return False + # + # The rest is the rare slow case. Use the general logic of issubclass() + # (issue #3149). CPython 3.x doesn't do that (but there is a + # many-years issue report: https://bugs.python.org/issue12029), and + # there are probably tests, so we won't call abstract_issubclass_w() + # either in PyPy3. return BaseObjSpace.exception_issubclass_w(space, w_cls1, w_cls2) # ____________________________________________________________ diff --git a/pypy/module/__builtin__/test/test_abstractinst.py b/pypy/module/__builtin__/test/test_abstractinst.py --- a/pypy/module/__builtin__/test/test_abstractinst.py +++ b/pypy/module/__builtin__/test/test_abstractinst.py @@ -249,3 +249,25 @@ return False assert issubclass(42, M()) is False + + def test_exception_match_does_not_call_subclasscheck(self): + class Special(Exception): + class __metaclass__(type): + def __subclasscheck__(cls1, cls2): + return True + try: + raise ValueError + except ValueError: # Python 3.x behaviour + pass + + def test_exception_raising_does_not_call_subclasscheck(self): + # test skipped: unsure how to get a non-normalized exception + # from pure Python. + class Special(Exception): + class __metaclass__(type): + def __subclasscheck__(cls1, cls2): + return True + try: + skip("non-normalized exception") #raise Special, ValueError() + except Special: + pass diff --git a/pypy/module/cpyext/include/pyport.h b/pypy/module/cpyext/include/pyport.h --- a/pypy/module/cpyext/include/pyport.h +++ b/pypy/module/cpyext/include/pyport.h @@ -5,68 +5,34 @@ #include <stdint.h> #endif -/* typedefs for some C9X-defined synonyms for integral types. */ -#ifdef HAVE_LONG_LONG +/* long long is required. Ensure HAVE_LONG_LONG is defined for compatibility. */ +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG 1 +#endif #ifndef PY_LONG_LONG #define PY_LONG_LONG long long -#if defined(LLONG_MAX) /* If LLONG_MAX is defined in limits.h, use that. */ #define PY_LLONG_MIN LLONG_MIN #define PY_LLONG_MAX LLONG_MAX #define PY_ULLONG_MAX ULLONG_MAX -#elif defined(__LONG_LONG_MAX__) -/* Otherwise, if GCC has a builtin define, use that. */ -#define PY_LLONG_MAX __LONG_LONG_MAX__ -#define PY_LLONG_MIN (-PY_LLONG_MAX-1) -#define PY_ULLONG_MAX (__LONG_LONG_MAX__*2ULL + 1ULL) -#else -/* Otherwise, rely on two's complement. */ -#define PY_ULLONG_MAX (~0ULL) -#define PY_LLONG_MAX ((long long)(PY_ULLONG_MAX>>1)) -#define PY_LLONG_MIN (-PY_LLONG_MAX-1) -#endif /* LLONG_MAX */ -#endif -#endif /* HAVE_LONG_LONG */ - -/* Largest possible value of size_t. - SIZE_MAX is part of C99, so it might be defined on some - platforms. If it is not defined, (size_t)-1 is a portable - definition for C89, due to the way signed->unsigned - conversion is defined. */ -#ifdef SIZE_MAX -#define PY_SIZE_MAX SIZE_MAX -#else -#define PY_SIZE_MAX ((size_t)-1) #endif -/* CPython needs this for the c-extension datetime, which is pure python on PyPy - downstream packages assume it is here (Pandas for instance) */ -#include <time.h> +#define PY_UINT32_T uint32_t +#define PY_UINT64_T uint64_t + +/* Signed variants of the above */ +#define PY_INT32_T int32_t +#define PY_INT64_T int64_t + /* uintptr_t is the C9X name for an unsigned integral type such that a * legitimate void* can be cast to uintptr_t and then back to void* again * without loss of information. Similarly for intptr_t, wrt a signed * integral type. */ -#ifdef HAVE_UINTPTR_T -typedef uintptr_t Py_uintptr_t; -typedef intptr_t Py_intptr_t; +typedef uintptr_t Py_uintptr_t; +typedef intptr_t Py_intptr_t; -#elif SIZEOF_VOID_P <= SIZEOF_INT -typedef unsigned int Py_uintptr_t; -typedef int Py_intptr_t; - -#elif SIZEOF_VOID_P <= SIZEOF_LONG -typedef unsigned long Py_uintptr_t; -typedef long Py_intptr_t; - -#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P <= SIZEOF_LONG_LONG) -typedef unsigned PY_LONG_LONG Py_uintptr_t; -typedef PY_LONG_LONG Py_intptr_t; - -#else -# error "Python needs a typedef for Py_uintptr_t in pyport.h." -#endif /* HAVE_UINTPTR_T */ /* Py_hash_t is the same size as a pointer. */ #define SIZEOF_PY_HASH_T SIZEOF_SIZE_T @@ -75,17 +41,19 @@ #define SIZEOF_PY_UHASH_T SIZEOF_SIZE_T typedef size_t Py_uhash_t; +/* Largest possible value of size_t. */ +#define PY_SIZE_MAX SIZE_MAX + +/* Largest positive value of type Py_ssize_t. */ +#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1)) +/* Smallest negative value of type Py_ssize_t. */ +#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1) + #include <stdarg.h> -#ifdef __va_copy -#define Py_VA_COPY __va_copy -#else -#ifdef VA_LIST_IS_ARRAY -#define Py_VA_COPY(x, y) Py_MEMCPY((x), (y), sizeof(va_list)) -#else -#define Py_VA_COPY(x, y) (x) = (y) -#endif -#endif +/* CPython needs this for the c-extension datetime, which is pure python on PyPy + downstream packages assume it is here (Pandas for instance) */ +#include <time.h> /******************************* * stat() and fstat() fiddling * @@ -132,8 +100,7 @@ * Hide GCC attributes from compilers that don't support them. */ #if (!defined(__GNUC__) || __GNUC__ < 2 || \ - (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ) && \ - !defined(RISCOS) + (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ) #define Py_GCC_ATTRIBUTE(x) #else #define Py_GCC_ATTRIBUTE(x) __attribute__(x) @@ -148,10 +115,13 @@ #define Py_ALIGNED(x) #endif -/* - * Older Microsoft compilers don't support the C99 long long literal suffixes, - * so these will be defined in PC/pyconfig.h for those compilers. +/* Eliminate end-of-loop code not reached warnings from SunPro C + * when using do{...}while(0) macros */ +#ifdef __SUNPRO_C +#pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED) +#endif + #ifndef Py_LL #define Py_LL(x) x##LL #endif @@ -160,4 +130,7 @@ #define Py_ULL(x) Py_LL(x##U) #endif +#define Py_VA_COPY va_copy + + #endif /* Py_PYPORT_H */ diff --git a/pypy/module/cpyext/parse/cpyext_object.h b/pypy/module/cpyext/parse/cpyext_object.h --- a/pypy/module/cpyext/parse/cpyext_object.h +++ b/pypy/module/cpyext/parse/cpyext_object.h @@ -1,6 +1,6 @@ #pragma once -typedef long Py_ssize_t; +typedef long Py_ssize_t; /* CPython defines it in pyport.h */ #define PyObject_HEAD \ Py_ssize_t ob_refcnt; \ diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -448,6 +448,10 @@ def get_empty_storage(self): raise NotImplementedError + def setitem_str(self, w_dict, key, w_value): + w_dict.setitem(self.space.newtext(key), w_value) + + @jit.look_inside_iff(lambda self, w_dict: w_dict_unrolling_heuristic(w_dict)) def w_keys(self, w_dict): diff --git a/pypy/objspace/std/jsondict.py b/pypy/objspace/std/jsondict.py --- a/pypy/objspace/std/jsondict.py +++ b/pypy/objspace/std/jsondict.py @@ -89,6 +89,10 @@ self.switch_to_unicode_strategy(w_dict) w_dict.setitem(w_key, w_value) + # for setitem_str use the default implementation + # because the jsonmap needs a wrapped key anyway + + def setdefault(self, w_dict, w_key, w_default): if self.is_correct_type(w_key): w_result = self.getitem_unicode(w_dict, w_key) diff --git a/pypy/objspace/std/test/test_jsondict.py b/pypy/objspace/std/test/test_jsondict.py --- a/pypy/objspace/std/test/test_jsondict.py +++ b/pypy/objspace/std/test/test_jsondict.py @@ -103,3 +103,16 @@ str(d) repr(d) + def test_objdict_bug(self): + import _pypyjson + a = """{"foo": "bar"}""" + d = _pypyjson.loads(a) + d['foo'] = 'x' + + class Obj(object): + pass + + x = Obj() + x.__dict__ = d + + x.foo = 'baz' # used to segfault on pypy3 diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py --- a/rpython/rlib/rbigint.py +++ b/rpython/rlib/rbigint.py @@ -1174,7 +1174,7 @@ def lshift(self, int_other): if int_other < 0: raise ValueError("negative shift count") - elif int_other == 0: + elif int_other == 0 or self.sign == 0: return self # wordshift, remshift = divmod(int_other, SHIFT) @@ -1183,8 +1183,6 @@ if not remshift: # So we can avoid problems with eq, AND avoid the need for normalize. - if self.sign == 0: - return self return rbigint([NULLDIGIT] * wordshift + self._digits, self.sign, self.numdigits() + wordshift) oldsize = self.numdigits() diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py --- a/rpython/rlib/test/test_rbigint.py +++ b/rpython/rlib/test/test_rbigint.py @@ -704,6 +704,10 @@ # Chek value accuracy. assert rbigint.fromlong(18446744073709551615L).rshift(1).tolong() == 18446744073709551615L >> 1 + def test_shift_optimization(self): + # does not crash with memory error + assert rbigint.fromint(0).lshift(sys.maxint).tolong() == 0 + def test_qshift(self): for x in range(10): for y in range(1, 161, 16): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit