Author: Antonio Cuni <anto.c...@gmail.com> Branch: hpy Changeset: r98531:b47edb1d5c11 Date: 2020-01-14 15:22 +0100 http://bitbucket.org/pypy/pypy/changeset/b47edb1d5c11/
Log: hg merge py3.6 diff too long, truncating to 2000 out of 122344 lines 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_ownlib.py b/extra_tests/cffi_tests/cffi0/test_ownlib.py --- a/extra_tests/cffi_tests/cffi0/test_ownlib.py +++ b/extra_tests/cffi_tests/cffi0/test_ownlib.py @@ -372,3 +372,29 @@ assert s.top == 22 assert s.right == 33 assert s.bottom == 44 + + def test_dlopen_handle(self): + if self.module is None: + py.test.skip("fix the auto-generation of the tiny test lib") + if sys.platform == 'win32': + py.test.skip("uses 'dl' explicitly") + if self.__class__.Backend is CTypesBackend: + py.test.skip("not for the ctypes backend") + backend = self.Backend() + ffi1 = FFI(backend=backend) + ffi1.cdef("""void *dlopen(const char *filename, int flags); + int dlclose(void *handle);""") + lib1 = ffi1.dlopen('dl') + handle = lib1.dlopen(self.module.encode(sys.getfilesystemencoding()), + backend.RTLD_LAZY) + assert ffi1.typeof(handle) == ffi1.typeof("void *") + assert handle + + ffi = FFI(backend=backend) + ffi.cdef("""unsigned short foo_2bytes(unsigned short a);""") + lib = ffi.dlopen(handle) + x = lib.foo_2bytes(1000) + assert x == 1042 + + err = lib1.dlclose(handle) + assert err == 0 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_re_python.py b/extra_tests/cffi_tests/cffi1/test_re_python.py --- a/extra_tests/cffi_tests/cffi1/test_re_python.py +++ b/extra_tests/cffi_tests/cffi1/test_re_python.py @@ -261,3 +261,24 @@ # based on issue #429 from re_python_pysrc import ffi ffi.new("selfref_ptr_t") + +def test_dlopen_handle(): + import _cffi_backend + from re_python_pysrc import ffi + if sys.platform == 'win32': + py.test.skip("uses 'dl' explicitly") + ffi1 = FFI() + ffi1.cdef("""void *dlopen(const char *filename, int flags); + int dlclose(void *handle);""") + lib1 = ffi1.dlopen('dl') + handle = lib1.dlopen(extmod.encode(sys.getfilesystemencoding()), + _cffi_backend.RTLD_LAZY) + assert ffi1.typeof(handle) == ffi1.typeof("void *") + assert handle + + lib = ffi.dlopen(handle) + assert lib.add42(-10) == 32 + assert type(lib.add42) is _cffi_backend.FFI.CData + + err = lib1.dlclose(handle) + assert err == 0 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(): @@ -349,9 +351,9 @@ lib = verify(ffi, 'test_verify_exact_field_offset', """struct foo_s { short a; int b; };""") e = py.test.raises(ffi.error, ffi.new, "struct foo_s *", []) # lazily - assert str(e.value) == ("struct foo_s: wrong offset for field 'b' (cdef " - 'says 0, but C compiler says 4). fix it or use "...;" ' - "in the cdef for struct foo_s to make it flexible") + assert str(e.value).startswith( + "struct foo_s: wrong offset for field 'b' (cdef " + 'says 0, but C compiler says 4). fix it or use "...;" ') def test_type_caching(): ffi1 = FFI(); ffi1.cdef("struct foo_s;") @@ -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/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -141,7 +141,11 @@ linked to a particular library, just like C headers; in the library we only look for the actual (untyped) symbols. """ - assert isinstance(name, basestring) or name is None + if not (isinstance(name, basestring) or + name is None or + isinstance(name, self.CData)): + raise TypeError("dlopen(name): name must be a file name, None, " + "or an already-opened 'void *' handle") with self._lock: lib, function_cache = _make_ffi_library(self, name, flags) self._function_caches.append(function_cache) @@ -799,9 +803,9 @@ def _load_backend_lib(backend, name, flags): import os - if name is None: - if sys.platform != "win32": - return backend.load_library(None, flags) + if not isinstance(name, basestring): + if sys.platform != "win32" or name is not None: + return backend.load_library(name, flags) name = "c" # Windows: load_library(None) fails, but this works # on Python 2 (backward compatibility hack only) first_error = None @@ -935,7 +939,7 @@ backendlib.close_lib() self.__dict__.clear() # - if libname is not None: + if isinstance(libname, basestring): try: if not isinstance(libname, str): # unicode, on Python 2 libname = libname.encode('utf-8') 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/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py --- a/pypy/interpreter/astcompiler/codegen.py +++ b/pypy/interpreter/astcompiler/codegen.py @@ -394,8 +394,10 @@ return l def _visit_defaults(self, defaults): + assert len(defaults) > 0 w_tup = self._tuple_of_consts(defaults) if w_tup: + self.update_position(defaults[-1].lineno, True) self.load_const(w_tup) else: self.visit_sequence(defaults) diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py --- a/pypy/interpreter/astcompiler/test/test_astbuilder.py +++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py @@ -663,7 +663,7 @@ assert exc_list.msg == "only single target (not list) can be annotated" exc_bad_target = pytest.raises(SyntaxError, self.get_ast, '{}: int').value - assert exc_bad_target.msg == "illegal target for annoation" + assert exc_bad_target.msg == "illegal target for annotation" def test_augassign(self): diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -1255,6 +1255,27 @@ src = """# -*- coding: utf-8 -*-\nz=ord(fr'\xc3\x98')\n""" yield self.st, src, 'z', 0xd8 + def test_func_defaults_lineno(self): + # like CPython 3.6.9 (at least), check that '''def f( + # x = 5, + # y = 6, + # ):''' + # generates the tuple (5, 6) as a constant for the defaults, + # but with the lineno for the last item (here the 6). There + # is no lineno for the other items, of course, because the + # complete tuple is loaded with just one LOAD_CONST. + yield self.simple_test, """\ + def fdl(): # line 1 + def f( # line 2 + x = 5, # line 3 + y = 6 # line 4 + ): # line 5 + pass # line 6 + import dis + co = fdl.__code__ + x = [y for (x, y) in dis.findlinestarts(co)] + """, 'x', [4] + class TestCompilerRevDB(BaseTestCompiler): spaceconfig = {"translation.reverse_debugger": True} diff --git a/pypy/interpreter/test/test_nestedscope.py b/pypy/interpreter/test/apptest_nestedscope.py rename from pypy/interpreter/test/test_nestedscope.py rename to pypy/interpreter/test/apptest_nestedscope.py --- a/pypy/interpreter/test/test_nestedscope.py +++ b/pypy/interpreter/test/apptest_nestedscope.py @@ -1,171 +1,169 @@ +from pytest import raises +def test_nested_scope(): + x = 42 + def f(): return x + assert f() == 42 -class AppTestNestedScope: +def test_nested_scope2(): + x = 42 + y = 3 + def f(): return x + assert f() == 42 - def test_nested_scope(self): - x = 42 - def f(): return x - assert f() == 42 +def test_nested_scope3(): + x = 42 + def f(): + def g(): + return x + return g + assert f()() == 42 - def test_nested_scope2(self): - x = 42 - y = 3 - def f(): return x - assert f() == 42 +def test_nested_scope4(): + def f(): + x = 3 + def g(): + return x + a = g() + x = 4 + b = g() + return (a, b) + assert f() == (3, 4) - def test_nested_scope3(self): - x = 42 - def f(): - def g(): - return x - return g - assert f()() == 42 +def test_nested_scope_locals(): + def f(): + x = 3 + def g(): + i = x + return locals() + return g() + d = f() + assert d == {'i':3, 'x':3} - def test_nested_scope4(self): - def f(): - x = 3 - def g(): - return x - a = g() - x = 4 - b = g() - return (a, b) - assert f() == (3, 4) - - def test_nested_scope_locals(self): - def f(): - x = 3 - def g(): +def test_deeply_nested_scope_locals(): + def f(): + x = 3 + def g(): + def h(): i = x return locals() - return g() - d = f() - assert d == {'i':3, 'x':3} + return locals(), h() + return g() + outer_locals, inner_locals = f() + assert inner_locals == {'i':3, 'x':3} + keys = sorted(outer_locals.keys()) + assert keys == ['h', 'x'] - def test_deeply_nested_scope_locals(self): - def f(): - x = 3 - def g(): - def h(): - i = x - return locals() - return locals(), h() - return g() - outer_locals, inner_locals = f() - assert inner_locals == {'i':3, 'x':3} - keys = sorted(outer_locals.keys()) - assert keys == ['h', 'x'] +def test_lambda_in_genexpr(): + assert [x() for x in (lambda: x for x in range(10))] == list(range(10)) - def test_lambda_in_genexpr(self): - assert [x() for x in (lambda: x for x in range(10))] == list(range(10)) +def test_cell_repr(): + import re + from reprlib import repr as r # Don't shadow builtin repr - def test_cell_repr(self): - import re - from reprlib import repr as r # Don't shadow builtin repr + def get_cell(): + x = 42 + def inner(): + return x + return inner + x = get_cell().__closure__[0] + assert re.match(r'<cell at 0x[0-9A-Fa-f]+: int object at 0x[0-9A-Fa-f]+>', repr(x)) + assert re.match(r'<cell at 0x.*\.\.\..*>', r(x)) - def get_cell(): + def get_cell(): + if False: x = 42 - def inner(): + def inner(): + return x + return inner + x = get_cell().__closure__[0] + assert re.match(r'<cell at 0x[0-9A-Fa-f]+: empty>', repr(x)) + +def test_cell_contents(): + def f(x): + def f(y): + return x + y + return f + + g = f(10) + assert g.__closure__[0].cell_contents == 10 + +def test_empty_cell_contents(): + + def f(): + def f(y): + return x + y + return f + x = 1 + + g = f() + with raises(ValueError): + g.__closure__[0].cell_contents + +def test_compare_cells(): + def f(n): + if n: + x = n + def f(y): + return x + y + return f + + empty_cell_1 = f(0).__closure__[0] + empty_cell_2 = f(0).__closure__[0] + g1 = f(1).__closure__[0] + g2 = f(2).__closure__[0] + assert g1 < g2 + assert g1 <= g2 + assert g2 > g1 + assert g2 >= g1 + assert not g1 == g2 + assert g1 != g2 + # + assert empty_cell_1 == empty_cell_2 + assert not empty_cell_1 != empty_cell_2 + assert empty_cell_1 < g1 + +def test_leaking_class_locals(): + def f(x): + class X: + x = 12 + def f(self): return x - return inner - x = get_cell().__closure__[0] - assert re.match(r'<cell at 0x[0-9A-Fa-f]+: int object at 0x[0-9A-Fa-f]+>', repr(x)) - assert re.match(r'<cell at 0x.*\.\.\..*>', r(x)) + locals() + return X + assert f(1).x == 12 - def get_cell(): - if False: - x = 42 - def inner(): - return x - return inner - x = get_cell().__closure__[0] - assert re.match(r'<cell at 0x[0-9A-Fa-f]+: empty>', repr(x)) +def test_nested_scope_locals_mutating_cellvars(): + def f(): + x = 12 + def m(): + locals() + x + locals() + return x + return m + assert f()() == 12 - def test_cell_contents(self): - def f(x): - def f(y): - return x + y - return f - g = f(10) - assert g.__closure__[0].cell_contents == 10 +def test_unbound_local_after_del(): + """ + # #4617: It is now legal to delete a cell variable. + # The following functions must obviously compile, + # and give the correct error when accessing the deleted name. + def errorInOuter(): + y = 1 + del y + print(y) + def inner(): + return y - def test_empty_cell_contents(self): + def errorInInner(): + def inner(): + return y + y = 1 + del y + inner() - def f(): - def f(y): - return x + y - return f - x = 1 - - g = f() - with raises(ValueError): - g.__closure__[0].cell_contents - - def test_compare_cells(self): - def f(n): - if n: - x = n - def f(y): - return x + y - return f - - empty_cell_1 = f(0).__closure__[0] - empty_cell_2 = f(0).__closure__[0] - g1 = f(1).__closure__[0] - g2 = f(2).__closure__[0] - assert g1 < g2 - assert g1 <= g2 - assert g2 > g1 - assert g2 >= g1 - assert not g1 == g2 - assert g1 != g2 - # - assert empty_cell_1 == empty_cell_2 - assert not empty_cell_1 != empty_cell_2 - assert empty_cell_1 < g1 - - def test_leaking_class_locals(self): - def f(x): - class X: - x = 12 - def f(self): - return x - locals() - return X - assert f(1).x == 12 - - def test_nested_scope_locals_mutating_cellvars(self): - def f(): - x = 12 - def m(): - locals() - x - locals() - return x - return m - assert f()() == 12 - - - def test_unbound_local_after_del(self): - """ - # #4617: It is now legal to delete a cell variable. - # The following functions must obviously compile, - # and give the correct error when accessing the deleted name. - def errorInOuter(): - y = 1 - del y - print(y) - def inner(): - return y - - def errorInInner(): - def inner(): - return y - y = 1 - del y - inner() - - raises(UnboundLocalError, "errorInOuter()") - raises(NameError, "errorInInner()") - """ + raises(UnboundLocalError, "errorInOuter()") + raises(NameError, "errorInInner()") + """ diff --git a/pypy/interpreter/test/test_class.py b/pypy/interpreter/test/test_class.py --- a/pypy/interpreter/test/test_class.py +++ b/pypy/interpreter/test/test_class.py @@ -140,3 +140,9 @@ "metaclass found to be 'function', but calling <class 'function'> " "with args ('Foo', (<function test_nonsensical_base_error_message" ".<locals>.foo_func at ") + + with raises(TypeError) as exc: + class Foo(object, object): + pass + assert str(exc.value).startswith( + "duplicate base class 'object'") 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__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -155,7 +155,8 @@ # give a more comprehensible error message for TypeErrors if e.got_any_traceback(): raise - if not e.match(space, space.w_TypeError): + if (not e.match(space, space.w_TypeError) or + space.is_w(w_meta, space.w_type)): raise raise oefmt(space.w_TypeError, "metaclass found to be '%N', but calling %R " 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/_cffi_backend/cdlopen.py b/pypy/module/_cffi_backend/cdlopen.py --- a/pypy/module/_cffi_backend/cdlopen.py +++ b/pypy/module/_cffi_backend/cdlopen.py @@ -15,10 +15,11 @@ def __init__(self, ffi, w_filename, flags): space = ffi.space - fname, handle = misc.dlopen_w(space, w_filename, flags) + fname, handle, autoclose = misc.dlopen_w(space, w_filename, flags) W_LibObject.__init__(self, ffi, fname) self.libhandle = handle - self.register_finalizer(space) + if autoclose: + self.register_finalizer(space) def _finalize_(self): h = self.libhandle diff --git a/pypy/module/_cffi_backend/libraryobj.py b/pypy/module/_cffi_backend/libraryobj.py --- a/pypy/module/_cffi_backend/libraryobj.py +++ b/pypy/module/_cffi_backend/libraryobj.py @@ -18,8 +18,10 @@ def __init__(self, space, w_filename, flags): self.space = space - self.name, self.handle = misc.dlopen_w(space, w_filename, flags) - self.register_finalizer(space) + self.name, self.handle, autoclose = ( + misc.dlopen_w(space, w_filename, flags)) + if autoclose: + self.register_finalizer(space) def _finalize_(self): h = self.handle diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -8,7 +8,7 @@ from rpython.rlib.objectmodel import specialize, we_are_translated from rpython.rlib.rarithmetic import r_uint, r_ulonglong from rpython.rlib.unroll import unrolling_iterable -from rpython.rlib.rdynload import dlopen, DLOpenError +from rpython.rlib.rdynload import dlopen, DLOpenError, DLLHANDLE from rpython.rlib.nonconst import NonConstant from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo @@ -408,7 +408,26 @@ # ____________________________________________________________ def dlopen_w(space, w_filename, flags): - if WIN32 and space.isinstance_w(w_filename, space.w_unicode): + from pypy.module._cffi_backend.cdataobj import W_CData + from pypy.module._cffi_backend import ctypeptr + + autoclose = True + if isinstance(w_filename, W_CData): + # 'flags' ignored in this case + w_ctype = w_filename.ctype + if (not isinstance(w_ctype, ctypeptr.W_CTypePointer) or + not w_ctype.is_void_ptr): + raise oefmt(space.w_TypeError, + "dlopen() takes a file name or 'void *' handle, not '%s'", + w_ctype.name) + handle = w_filename.unsafe_escaping_ptr() + if not handle: + raise oefmt(space.w_RuntimeError, "cannot call dlopen(NULL)") + fname = w_ctype.extra_repr(handle) + handle = rffi.cast(DLLHANDLE, handle) + autoclose = False + # + elif WIN32 and space.isinstance_w(w_filename, space.w_unicode): fname = space.text_w(space.repr(w_filename)) utf8_name = space.utf8_w(w_filename) uni_len = space.len_w(w_filename) @@ -429,4 +448,4 @@ handle = dlopen(ll_libname, flags) except DLOpenError as e: raise wrap_dlopenerror(space, e, fname) - return fname, handle + return fname, handle, autoclose diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -308,8 +308,8 @@ w_FFIError = get_ffi_error(w_ctype.space) raise oefmt(w_FFIError, '%s: %s%s%s (cdef says %d, but C compiler says %d).' - ' fix it or use "...;" in the cdef for %s to ' - 'make it flexible', + ' fix it or use "...;" as the last field in the ' + 'cdef for %s to make it flexible', w_ctype.name, msg1, msg2, msg3, cdef_value, compiler_value, w_ctype.name) w_ctype._custom_field_pos = True diff --git a/pypy/module/_cffi_backend/test/test_re_python.py b/pypy/module/_cffi_backend/test/test_re_python.py --- a/pypy/module/_cffi_backend/test/test_re_python.py +++ b/pypy/module/_cffi_backend/test/test_re_python.py @@ -75,6 +75,9 @@ typedef struct bar_s { int x; signed char a[]; } bar_t; enum foo_e { AA, BB, CC }; typedef struct selfref { struct selfref *next; } *selfref_ptr_t; + + void *dlopen(const char *filename, int flags); + int dlclose(void *handle); """) ffi.set_source('re_python_pysrc', None) ffi.emit_python_code(str(tmpdir.join('re_python_pysrc.py'))) @@ -96,6 +99,11 @@ return fix_path """) + cls.w_dl_libpath = space.w_None + if sys.platform != 'win32': + import ctypes.util + cls.w_dl_libpath = space.wrap(ctypes.util.find_library('dl')) + def teardown_method(self, meth): self.space.appexec([], """(): import sys @@ -245,3 +253,22 @@ self.fix_path() from re_python_pysrc import ffi ffi.new("selfref_ptr_t") + + def test_dlopen_handle(self): + import _cffi_backend, sys + self.fix_path() + from re_python_pysrc import ffi + if self.dl_libpath is None: + py.test.skip("uses 'dl' explicitly") + lib1 = ffi.dlopen(self.dl_libpath) + handle = lib1.dlopen(self.extmod.encode(sys.getfilesystemencoding()), + _cffi_backend.RTLD_LAZY) + assert ffi.typeof(handle) == ffi.typeof("void *") + assert handle + + lib = ffi.dlopen(handle) + assert lib.add42(-10) == 32 + assert type(lib.add42) is _cffi_backend.FFI.CData + + err = lib1.dlclose(handle) + assert err == 0 diff --git a/pypy/module/_cffi_backend/test/test_recompiler.py b/pypy/module/_cffi_backend/test/test_recompiler.py --- a/pypy/module/_cffi_backend/test/test_recompiler.py +++ b/pypy/module/_cffi_backend/test/test_recompiler.py @@ -348,9 +348,9 @@ 'test_verify_exact_field_offset', """struct foo_s { short a; int b; };""") e = raises(ffi.error, ffi.new, "struct foo_s *", []) # lazily - assert str(e.value) == ("struct foo_s: wrong offset for field 'b' (cdef " - 'says 0, but C compiler says 4). fix it or use "...;" ' - "in the cdef for struct foo_s to make it flexible") + assert str(e.value).startswith( + "struct foo_s: wrong offset for field 'b' (cdef " + 'says 0, but C compiler says 4). fix it or use "...;" ') def test_type_caching(self): ffi1, lib1 = self.prepare( 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/module/fcntl/interp_fcntl.py b/pypy/module/fcntl/interp_fcntl.py --- a/pypy/module/fcntl/interp_fcntl.py +++ b/pypy/module/fcntl/interp_fcntl.py @@ -77,7 +77,9 @@ c_flock = external('flock', [rffi.INT, rffi.INT], rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO) -def _get_error(space, funcname): +def _raise_error_maybe(space, funcname): + # wrap_oserror(..., eintr_retry=True) raises an OSError or returns None + # when appropriate errno = rposix.get_saved_errno() return wrap_oserror(space, OSError(errno, funcname), exception_name = 'w_IOError', eintr_retry=True) @@ -109,7 +111,7 @@ while True: rv = fcntl_str(fd, op, ll_arg) if rv < 0: - _get_error(space, "fcntl") + _raise_error_maybe(space, "fcntl") else: arg = rffi.charpsize2str(ll_arg, len(arg)) return space.newbytes(arg) @@ -119,7 +121,7 @@ while True: rv = fcntl_int(fd, op, intarg) if rv < 0: - _get_error(space, "fcntl") + _raise_error_maybe(space, "fcntl") else: return space.newint(rv) @@ -137,7 +139,7 @@ while True: rv = c_flock(fd, op) if rv < 0: - _get_error(space, "flock") + _raise_error_maybe(space, "flock") else: return else: @@ -191,7 +193,7 @@ while True: rv = fcntl_flock(fd, op, l) if rv < 0: - _get_error(space, "fcntl") + _raise_error_maybe(space, "fcntl") else: return @@ -229,7 +231,7 @@ rffi.cast(rffi.VOIDP, ll_arg), len(arg)) rv = ioctl_str(fd, op, buf.raw) if rv < 0: - raise _get_error(space, "ioctl") + _raise_error_maybe(space, "ioctl") arg = rffi.charpsize2str(buf.raw, len(arg)) if mutate_flag != 0: rwbuffer.setslice(0, arg) @@ -257,7 +259,7 @@ rffi.cast(rffi.VOIDP, ll_arg), len(arg)) rv = ioctl_str(fd, op, buf.raw) if rv < 0: - raise _get_error(space, "ioctl") + _raise_error_maybe(space, "ioctl") arg = rffi.charpsize2str(buf.raw, len(arg)) return space.newbytes(arg) finally: @@ -267,5 +269,5 @@ intarg = rffi.cast(rffi.INT, intarg) # C long => C int rv = ioctl_int(fd, op, intarg) if rv < 0: - raise _get_error(space, "ioctl") + _raise_error_maybe(space, "ioctl") return space.newint(rv) diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -1068,7 +1068,8 @@ w_newkey = w_newvalue else: w_newkey = space.call_function(groupby.w_keyfunc, w_newvalue) - assert groupby.w_currvalue is None + #assert groupby.w_currvalue is None + # ^^^ check disabled, see http://bugs.python.org/issue30347 groupby.w_currkey = w_newkey groupby.w_currvalue = w_newvalue diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py --- a/pypy/module/itertools/test/test_itertools.py +++ b/pypy/module/itertools/test/test_itertools.py @@ -541,6 +541,16 @@ assert a == [] assert b == [(True, 9)] + def test_groupby_crash(self): + # see http://bugs.python.org/issue30347 + from itertools import groupby + def f(n): + if n == 5: + list(b) + return n != 6 + for (k, b) in groupby(range(10), f): + list(b) # shouldn't crash + def test_iterables(self): import itertools 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/pypy/tool/pytest/apptest2.py b/pypy/tool/pytest/apptest2.py --- a/pypy/tool/pytest/apptest2.py +++ b/pypy/tool/pytest/apptest2.py @@ -46,6 +46,7 @@ if not isinstance(w_obj, pypy.interpreter.function.Function): continue items.append(AppTestFunction(name, self, w_obj)) + items.sort(key=lambda item: item.reportinfo()[:2]) return items def setup(self): 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): diff --git a/rpython/rlib/unicodedata/CaseFolding-11.0.0.txt b/rpython/rlib/unicodedata/CaseFolding-11.0.0.txt new file mode 100644 --- /dev/null +++ b/rpython/rlib/unicodedata/CaseFolding-11.0.0.txt @@ -0,0 +1,1574 @@ +# CaseFolding-11.0.0.txt +# Date: 2018-01-31, 08:20:09 GMT +# © 2018 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see http://www.unicode.org/reports/tr44/ +# +# Case Folding Properties +# +# This file is a supplement to the UnicodeData file. +# It provides a case folding mapping generated from the Unicode Character Database. +# If all characters are mapped according to the full mapping below, then +# case differences (according to UnicodeData.txt and SpecialCasing.txt) +# are eliminated. +# +# The data supports both implementations that require simple case foldings +# (where string lengths don't change), and implementations that allow full case folding +# (where string lengths may grow). Note that where they can be supported, the +# full case foldings are superior: for example, they allow "MASSE" and "Maße" to match. +# +# All code points not listed in this file map to themselves. +# +# NOTE: case folding does not preserve normalization formats! +# +# For information on case folding, including how to have case folding +# preserve normalization formats, see Section 3.13 Default Case Algorithms in +# The Unicode Standard. +# +# ================================================================================ +# Format +# ================================================================================ +# The entries in this file are in the following machine-readable format: +# +# <code>; <status>; <mapping>; # <name> +# +# The status field is: +# C: common case folding, common mappings shared by both simple and full mappings. +# F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces. +# S: simple case folding, mappings to single characters where different from F. +# T: special case for uppercase I and dotted uppercase I +# - For non-Turkic languages, this mapping is normally not used. +# - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters. +# Note that the Turkic mappings do not maintain canonical equivalence without additional processing. +# See the discussions of case mapping in the Unicode Standard for more information. +# +# Usage: +# A. To do a simple case folding, use the mappings with status C + S. +# B. To do a full case folding, use the mappings with status C + F. +# +# The mappings with status T can be used or omitted depending on the desired case-folding +# behavior. (The default option is to exclude them.) +# +# ================================================================= + +# Property: Case_Folding + +# All code points not explicitly listed for Case_Folding +# have the value C for the status field, and the code point itself for the mapping field. + +# ================================================================= +0041; C; 0061; # LATIN CAPITAL LETTER A +0042; C; 0062; # LATIN CAPITAL LETTER B +0043; C; 0063; # LATIN CAPITAL LETTER C +0044; C; 0064; # LATIN CAPITAL LETTER D +0045; C; 0065; # LATIN CAPITAL LETTER E +0046; C; 0066; # LATIN CAPITAL LETTER F +0047; C; 0067; # LATIN CAPITAL LETTER G +0048; C; 0068; # LATIN CAPITAL LETTER H +0049; C; 0069; # LATIN CAPITAL LETTER I +0049; T; 0131; # LATIN CAPITAL LETTER I +004A; C; 006A; # LATIN CAPITAL LETTER J +004B; C; 006B; # LATIN CAPITAL LETTER K +004C; C; 006C; # LATIN CAPITAL LETTER L +004D; C; 006D; # LATIN CAPITAL LETTER M +004E; C; 006E; # LATIN CAPITAL LETTER N +004F; C; 006F; # LATIN CAPITAL LETTER O +0050; C; 0070; # LATIN CAPITAL LETTER P +0051; C; 0071; # LATIN CAPITAL LETTER Q +0052; C; 0072; # LATIN CAPITAL LETTER R +0053; C; 0073; # LATIN CAPITAL LETTER S +0054; C; 0074; # LATIN CAPITAL LETTER T +0055; C; 0075; # LATIN CAPITAL LETTER U +0056; C; 0076; # LATIN CAPITAL LETTER V +0057; C; 0077; # LATIN CAPITAL LETTER W +0058; C; 0078; # LATIN CAPITAL LETTER X +0059; C; 0079; # LATIN CAPITAL LETTER Y +005A; C; 007A; # LATIN CAPITAL LETTER Z +00B5; C; 03BC; # MICRO SIGN +00C0; C; 00E0; # LATIN CAPITAL LETTER A WITH GRAVE +00C1; C; 00E1; # LATIN CAPITAL LETTER A WITH ACUTE +00C2; C; 00E2; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +00C3; C; 00E3; # LATIN CAPITAL LETTER A WITH TILDE +00C4; C; 00E4; # LATIN CAPITAL LETTER A WITH DIAERESIS +00C5; C; 00E5; # LATIN CAPITAL LETTER A WITH RING ABOVE +00C6; C; 00E6; # LATIN CAPITAL LETTER AE +00C7; C; 00E7; # LATIN CAPITAL LETTER C WITH CEDILLA +00C8; C; 00E8; # LATIN CAPITAL LETTER E WITH GRAVE +00C9; C; 00E9; # LATIN CAPITAL LETTER E WITH ACUTE +00CA; C; 00EA; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +00CB; C; 00EB; # LATIN CAPITAL LETTER E WITH DIAERESIS +00CC; C; 00EC; # LATIN CAPITAL LETTER I WITH GRAVE +00CD; C; 00ED; # LATIN CAPITAL LETTER I WITH ACUTE +00CE; C; 00EE; # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +00CF; C; 00EF; # LATIN CAPITAL LETTER I WITH DIAERESIS +00D0; C; 00F0; # LATIN CAPITAL LETTER ETH +00D1; C; 00F1; # LATIN CAPITAL LETTER N WITH TILDE +00D2; C; 00F2; # LATIN CAPITAL LETTER O WITH GRAVE +00D3; C; 00F3; # LATIN CAPITAL LETTER O WITH ACUTE +00D4; C; 00F4; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +00D5; C; 00F5; # LATIN CAPITAL LETTER O WITH TILDE +00D6; C; 00F6; # LATIN CAPITAL LETTER O WITH DIAERESIS +00D8; C; 00F8; # LATIN CAPITAL LETTER O WITH STROKE +00D9; C; 00F9; # LATIN CAPITAL LETTER U WITH GRAVE +00DA; C; 00FA; # LATIN CAPITAL LETTER U WITH ACUTE +00DB; C; 00FB; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +00DC; C; 00FC; # LATIN CAPITAL LETTER U WITH DIAERESIS +00DD; C; 00FD; # LATIN CAPITAL LETTER Y WITH ACUTE +00DE; C; 00FE; # LATIN CAPITAL LETTER THORN +00DF; F; 0073 0073; # LATIN SMALL LETTER SHARP S +0100; C; 0101; # LATIN CAPITAL LETTER A WITH MACRON +0102; C; 0103; # LATIN CAPITAL LETTER A WITH BREVE +0104; C; 0105; # LATIN CAPITAL LETTER A WITH OGONEK +0106; C; 0107; # LATIN CAPITAL LETTER C WITH ACUTE +0108; C; 0109; # LATIN CAPITAL LETTER C WITH CIRCUMFLEX +010A; C; 010B; # LATIN CAPITAL LETTER C WITH DOT ABOVE +010C; C; 010D; # LATIN CAPITAL LETTER C WITH CARON +010E; C; 010F; # LATIN CAPITAL LETTER D WITH CARON +0110; C; 0111; # LATIN CAPITAL LETTER D WITH STROKE +0112; C; 0113; # LATIN CAPITAL LETTER E WITH MACRON +0114; C; 0115; # LATIN CAPITAL LETTER E WITH BREVE +0116; C; 0117; # LATIN CAPITAL LETTER E WITH DOT ABOVE +0118; C; 0119; # LATIN CAPITAL LETTER E WITH OGONEK +011A; C; 011B; # LATIN CAPITAL LETTER E WITH CARON +011C; C; 011D; # LATIN CAPITAL LETTER G WITH CIRCUMFLEX +011E; C; 011F; # LATIN CAPITAL LETTER G WITH BREVE +0120; C; 0121; # LATIN CAPITAL LETTER G WITH DOT ABOVE +0122; C; 0123; # LATIN CAPITAL LETTER G WITH CEDILLA +0124; C; 0125; # LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0126; C; 0127; # LATIN CAPITAL LETTER H WITH STROKE +0128; C; 0129; # LATIN CAPITAL LETTER I WITH TILDE +012A; C; 012B; # LATIN CAPITAL LETTER I WITH MACRON +012C; C; 012D; # LATIN CAPITAL LETTER I WITH BREVE +012E; C; 012F; # LATIN CAPITAL LETTER I WITH OGONEK +0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE +0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE +0132; C; 0133; # LATIN CAPITAL LIGATURE IJ +0134; C; 0135; # LATIN CAPITAL LETTER J WITH CIRCUMFLEX +0136; C; 0137; # LATIN CAPITAL LETTER K WITH CEDILLA +0139; C; 013A; # LATIN CAPITAL LETTER L WITH ACUTE +013B; C; 013C; # LATIN CAPITAL LETTER L WITH CEDILLA +013D; C; 013E; # LATIN CAPITAL LETTER L WITH CARON +013F; C; 0140; # LATIN CAPITAL LETTER L WITH MIDDLE DOT +0141; C; 0142; # LATIN CAPITAL LETTER L WITH STROKE +0143; C; 0144; # LATIN CAPITAL LETTER N WITH ACUTE +0145; C; 0146; # LATIN CAPITAL LETTER N WITH CEDILLA +0147; C; 0148; # LATIN CAPITAL LETTER N WITH CARON +0149; F; 02BC 006E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +014A; C; 014B; # LATIN CAPITAL LETTER ENG +014C; C; 014D; # LATIN CAPITAL LETTER O WITH MACRON +014E; C; 014F; # LATIN CAPITAL LETTER O WITH BREVE +0150; C; 0151; # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0152; C; 0153; # LATIN CAPITAL LIGATURE OE +0154; C; 0155; # LATIN CAPITAL LETTER R WITH ACUTE +0156; C; 0157; # LATIN CAPITAL LETTER R WITH CEDILLA +0158; C; 0159; # LATIN CAPITAL LETTER R WITH CARON +015A; C; 015B; # LATIN CAPITAL LETTER S WITH ACUTE +015C; C; 015D; # LATIN CAPITAL LETTER S WITH CIRCUMFLEX +015E; C; 015F; # LATIN CAPITAL LETTER S WITH CEDILLA +0160; C; 0161; # LATIN CAPITAL LETTER S WITH CARON +0162; C; 0163; # LATIN CAPITAL LETTER T WITH CEDILLA +0164; C; 0165; # LATIN CAPITAL LETTER T WITH CARON +0166; C; 0167; # LATIN CAPITAL LETTER T WITH STROKE +0168; C; 0169; # LATIN CAPITAL LETTER U WITH TILDE +016A; C; 016B; # LATIN CAPITAL LETTER U WITH MACRON +016C; C; 016D; # LATIN CAPITAL LETTER U WITH BREVE +016E; C; 016F; # LATIN CAPITAL LETTER U WITH RING ABOVE +0170; C; 0171; # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0172; C; 0173; # LATIN CAPITAL LETTER U WITH OGONEK +0174; C; 0175; # LATIN CAPITAL LETTER W WITH CIRCUMFLEX +0176; C; 0177; # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +0178; C; 00FF; # LATIN CAPITAL LETTER Y WITH DIAERESIS +0179; C; 017A; # LATIN CAPITAL LETTER Z WITH ACUTE +017B; C; 017C; # LATIN CAPITAL LETTER Z WITH DOT ABOVE +017D; C; 017E; # LATIN CAPITAL LETTER Z WITH CARON +017F; C; 0073; # LATIN SMALL LETTER LONG S +0181; C; 0253; # LATIN CAPITAL LETTER B WITH HOOK +0182; C; 0183; # LATIN CAPITAL LETTER B WITH TOPBAR +0184; C; 0185; # LATIN CAPITAL LETTER TONE SIX +0186; C; 0254; # LATIN CAPITAL LETTER OPEN O +0187; C; 0188; # LATIN CAPITAL LETTER C WITH HOOK +0189; C; 0256; # LATIN CAPITAL LETTER AFRICAN D +018A; C; 0257; # LATIN CAPITAL LETTER D WITH HOOK +018B; C; 018C; # LATIN CAPITAL LETTER D WITH TOPBAR +018E; C; 01DD; # LATIN CAPITAL LETTER REVERSED E +018F; C; 0259; # LATIN CAPITAL LETTER SCHWA +0190; C; 025B; # LATIN CAPITAL LETTER OPEN E +0191; C; 0192; # LATIN CAPITAL LETTER F WITH HOOK +0193; C; 0260; # LATIN CAPITAL LETTER G WITH HOOK +0194; C; 0263; # LATIN CAPITAL LETTER GAMMA +0196; C; 0269; # LATIN CAPITAL LETTER IOTA +0197; C; 0268; # LATIN CAPITAL LETTER I WITH STROKE +0198; C; 0199; # LATIN CAPITAL LETTER K WITH HOOK +019C; C; 026F; # LATIN CAPITAL LETTER TURNED M +019D; C; 0272; # LATIN CAPITAL LETTER N WITH LEFT HOOK +019F; C; 0275; # LATIN CAPITAL LETTER O WITH MIDDLE TILDE +01A0; C; 01A1; # LATIN CAPITAL LETTER O WITH HORN +01A2; C; 01A3; # LATIN CAPITAL LETTER OI +01A4; C; 01A5; # LATIN CAPITAL LETTER P WITH HOOK +01A6; C; 0280; # LATIN LETTER YR +01A7; C; 01A8; # LATIN CAPITAL LETTER TONE TWO +01A9; C; 0283; # LATIN CAPITAL LETTER ESH +01AC; C; 01AD; # LATIN CAPITAL LETTER T WITH HOOK +01AE; C; 0288; # LATIN CAPITAL LETTER T WITH RETROFLEX HOOK +01AF; C; 01B0; # LATIN CAPITAL LETTER U WITH HORN +01B1; C; 028A; # LATIN CAPITAL LETTER UPSILON +01B2; C; 028B; # LATIN CAPITAL LETTER V WITH HOOK +01B3; C; 01B4; # LATIN CAPITAL LETTER Y WITH HOOK +01B5; C; 01B6; # LATIN CAPITAL LETTER Z WITH STROKE +01B7; C; 0292; # LATIN CAPITAL LETTER EZH +01B8; C; 01B9; # LATIN CAPITAL LETTER EZH REVERSED +01BC; C; 01BD; # LATIN CAPITAL LETTER TONE FIVE +01C4; C; 01C6; # LATIN CAPITAL LETTER DZ WITH CARON +01C5; C; 01C6; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON +01C7; C; 01C9; # LATIN CAPITAL LETTER LJ +01C8; C; 01C9; # LATIN CAPITAL LETTER L WITH SMALL LETTER J +01CA; C; 01CC; # LATIN CAPITAL LETTER NJ +01CB; C; 01CC; # LATIN CAPITAL LETTER N WITH SMALL LETTER J +01CD; C; 01CE; # LATIN CAPITAL LETTER A WITH CARON +01CF; C; 01D0; # LATIN CAPITAL LETTER I WITH CARON +01D1; C; 01D2; # LATIN CAPITAL LETTER O WITH CARON +01D3; C; 01D4; # LATIN CAPITAL LETTER U WITH CARON +01D5; C; 01D6; # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON +01D7; C; 01D8; # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE +01D9; C; 01DA; # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON +01DB; C; 01DC; # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE +01DE; C; 01DF; # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON +01E0; C; 01E1; # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON +01E2; C; 01E3; # LATIN CAPITAL LETTER AE WITH MACRON +01E4; C; 01E5; # LATIN CAPITAL LETTER G WITH STROKE +01E6; C; 01E7; # LATIN CAPITAL LETTER G WITH CARON +01E8; C; 01E9; # LATIN CAPITAL LETTER K WITH CARON +01EA; C; 01EB; # LATIN CAPITAL LETTER O WITH OGONEK +01EC; C; 01ED; # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON +01EE; C; 01EF; # LATIN CAPITAL LETTER EZH WITH CARON +01F0; F; 006A 030C; # LATIN SMALL LETTER J WITH CARON +01F1; C; 01F3; # LATIN CAPITAL LETTER DZ +01F2; C; 01F3; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z +01F4; C; 01F5; # LATIN CAPITAL LETTER G WITH ACUTE +01F6; C; 0195; # LATIN CAPITAL LETTER HWAIR +01F7; C; 01BF; # LATIN CAPITAL LETTER WYNN +01F8; C; 01F9; # LATIN CAPITAL LETTER N WITH GRAVE +01FA; C; 01FB; # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE +01FC; C; 01FD; # LATIN CAPITAL LETTER AE WITH ACUTE +01FE; C; 01FF; # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE +0200; C; 0201; # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE +0202; C; 0203; # LATIN CAPITAL LETTER A WITH INVERTED BREVE +0204; C; 0205; # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE +0206; C; 0207; # LATIN CAPITAL LETTER E WITH INVERTED BREVE +0208; C; 0209; # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE +020A; C; 020B; # LATIN CAPITAL LETTER I WITH INVERTED BREVE +020C; C; 020D; # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE +020E; C; 020F; # LATIN CAPITAL LETTER O WITH INVERTED BREVE +0210; C; 0211; # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE +0212; C; 0213; # LATIN CAPITAL LETTER R WITH INVERTED BREVE +0214; C; 0215; # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE +0216; C; 0217; # LATIN CAPITAL LETTER U WITH INVERTED BREVE +0218; C; 0219; # LATIN CAPITAL LETTER S WITH COMMA BELOW +021A; C; 021B; # LATIN CAPITAL LETTER T WITH COMMA BELOW +021C; C; 021D; # LATIN CAPITAL LETTER YOGH +021E; C; 021F; # LATIN CAPITAL LETTER H WITH CARON +0220; C; 019E; # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG +0222; C; 0223; # LATIN CAPITAL LETTER OU +0224; C; 0225; # LATIN CAPITAL LETTER Z WITH HOOK +0226; C; 0227; # LATIN CAPITAL LETTER A WITH DOT ABOVE +0228; C; 0229; # LATIN CAPITAL LETTER E WITH CEDILLA +022A; C; 022B; # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON +022C; C; 022D; # LATIN CAPITAL LETTER O WITH TILDE AND MACRON +022E; C; 022F; # LATIN CAPITAL LETTER O WITH DOT ABOVE +0230; C; 0231; # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON +0232; C; 0233; # LATIN CAPITAL LETTER Y WITH MACRON +023A; C; 2C65; # LATIN CAPITAL LETTER A WITH STROKE +023B; C; 023C; # LATIN CAPITAL LETTER C WITH STROKE +023D; C; 019A; # LATIN CAPITAL LETTER L WITH BAR +023E; C; 2C66; # LATIN CAPITAL LETTER T WITH DIAGONAL STROKE +0241; C; 0242; # LATIN CAPITAL LETTER GLOTTAL STOP +0243; C; 0180; # LATIN CAPITAL LETTER B WITH STROKE +0244; C; 0289; # LATIN CAPITAL LETTER U BAR +0245; C; 028C; # LATIN CAPITAL LETTER TURNED V +0246; C; 0247; # LATIN CAPITAL LETTER E WITH STROKE +0248; C; 0249; # LATIN CAPITAL LETTER J WITH STROKE +024A; C; 024B; # LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL +024C; C; 024D; # LATIN CAPITAL LETTER R WITH STROKE +024E; C; 024F; # LATIN CAPITAL LETTER Y WITH STROKE +0345; C; 03B9; # COMBINING GREEK YPOGEGRAMMENI +0370; C; 0371; # GREEK CAPITAL LETTER HETA +0372; C; 0373; # GREEK CAPITAL LETTER ARCHAIC SAMPI +0376; C; 0377; # GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA +037F; C; 03F3; # GREEK CAPITAL LETTER YOT +0386; C; 03AC; # GREEK CAPITAL LETTER ALPHA WITH TONOS +0388; C; 03AD; # GREEK CAPITAL LETTER EPSILON WITH TONOS +0389; C; 03AE; # GREEK CAPITAL LETTER ETA WITH TONOS +038A; C; 03AF; # GREEK CAPITAL LETTER IOTA WITH TONOS +038C; C; 03CC; # GREEK CAPITAL LETTER OMICRON WITH TONOS +038E; C; 03CD; # GREEK CAPITAL LETTER UPSILON WITH TONOS +038F; C; 03CE; # GREEK CAPITAL LETTER OMEGA WITH TONOS +0390; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +0391; C; 03B1; # GREEK CAPITAL LETTER ALPHA +0392; C; 03B2; # GREEK CAPITAL LETTER BETA +0393; C; 03B3; # GREEK CAPITAL LETTER GAMMA +0394; C; 03B4; # GREEK CAPITAL LETTER DELTA +0395; C; 03B5; # GREEK CAPITAL LETTER EPSILON +0396; C; 03B6; # GREEK CAPITAL LETTER ZETA +0397; C; 03B7; # GREEK CAPITAL LETTER ETA +0398; C; 03B8; # GREEK CAPITAL LETTER THETA +0399; C; 03B9; # GREEK CAPITAL LETTER IOTA +039A; C; 03BA; # GREEK CAPITAL LETTER KAPPA +039B; C; 03BB; # GREEK CAPITAL LETTER LAMDA +039C; C; 03BC; # GREEK CAPITAL LETTER MU +039D; C; 03BD; # GREEK CAPITAL LETTER NU +039E; C; 03BE; # GREEK CAPITAL LETTER XI +039F; C; 03BF; # GREEK CAPITAL LETTER OMICRON +03A0; C; 03C0; # GREEK CAPITAL LETTER PI +03A1; C; 03C1; # GREEK CAPITAL LETTER RHO +03A3; C; 03C3; # GREEK CAPITAL LETTER SIGMA +03A4; C; 03C4; # GREEK CAPITAL LETTER TAU +03A5; C; 03C5; # GREEK CAPITAL LETTER UPSILON +03A6; C; 03C6; # GREEK CAPITAL LETTER PHI +03A7; C; 03C7; # GREEK CAPITAL LETTER CHI +03A8; C; 03C8; # GREEK CAPITAL LETTER PSI +03A9; C; 03C9; # GREEK CAPITAL LETTER OMEGA +03AA; C; 03CA; # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +03AB; C; 03CB; # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +03B0; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +03C2; C; 03C3; # GREEK SMALL LETTER FINAL SIGMA _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit