Author: Matti Picus <[email protected]>
Branch: py3.6
Changeset: r96032:6e5e91318ea6
Date: 2019-02-16 20:13 +0200
http://bitbucket.org/pypy/pypy/changeset/6e5e91318ea6/
Log: merge default into branch
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
@@ -352,6 +352,8 @@
def test_modify_struct_value(self):
if self.module is None:
py.test.skip("fix the auto-generation of the tiny test lib")
+ if self.Backend is CTypesBackend:
+ py.test.skip("fails with the ctypes backend on some architectures")
ffi = FFI(backend=self.Backend())
ffi.cdef("""
typedef struct {
diff --git a/extra_tests/cffi_tests/embedding/thread3-test.c
b/extra_tests/cffi_tests/embedding/thread3-test.c
--- a/extra_tests/cffi_tests/embedding/thread3-test.c
+++ b/extra_tests/cffi_tests/embedding/thread3-test.c
@@ -52,5 +52,6 @@
assert(status == 0);
}
printf("done\n");
+ fflush(stdout); /* this is occasionally needed on Windows */
return 0;
}
diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -5,8 +5,8 @@
from .error import CDefError, FFIError, VerificationError, VerificationMissing
from .error import PkgConfigError
-__version__ = "1.12.0"
-__version_info__ = (1, 12, 0)
+__version__ = "1.12.1"
+__version_info__ = (1, 12, 1)
# The verifier module file names are based on the CRC32 of a string that
# contains the following version number. It may be older than __version__
diff --git a/lib_pypy/cffi/_cffi_include.h b/lib_pypy/cffi/_cffi_include.h
--- a/lib_pypy/cffi/_cffi_include.h
+++ b/lib_pypy/cffi/_cffi_include.h
@@ -8,43 +8,20 @@
the same works for the other two macros. Py_DEBUG implies them,
but not the other way around.
- The implementation is messy (issue #350): on Windows, with _MSC_VER,
- we have to define Py_LIMITED_API even before including pyconfig.h.
- In that case, we guess what pyconfig.h will do to the macros above,
- and check our guess after the #include.
-
- Note that on Windows, with CPython 3.x, you need virtualenv version
- >= 16.0.0. Older versions don't copy PYTHON3.DLL. As a workaround
- you can remove the definition of Py_LIMITED_API here.
-
- See also 'py_limited_api' in cffi/setuptools_ext.py.
+ Issue #350 is still open: on Windows, the code here causes it to link
+ with PYTHON36.DLL (for example) instead of PYTHON3.DLL. A fix was
+ attempted in 164e526a5515 and 14ce6985e1c3, but reverted: virtualenv
+ does not make PYTHON3.DLL available, and so the "correctly" compiled
+ version would not run inside a virtualenv. We will re-apply the fix
+ after virtualenv has been fixed for some time. For explanation, see
+ issue #355. For a workaround if you want PYTHON3.DLL and don't worry
+ about virtualenv, see issue #350. See also 'py_limited_api' in
+ setuptools_ext.py.
*/
#if !defined(_CFFI_USE_EMBEDDING) && !defined(Py_LIMITED_API)
-# ifdef _MSC_VER
-# if !defined(_DEBUG) && !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) &&
!defined(Py_REF_DEBUG)
-# define Py_LIMITED_API
-# endif
-# include <pyconfig.h>
- /* sanity-check: Py_LIMITED_API will cause crashes if any of these
- are also defined. Normally, the Python file PC/pyconfig.h does not
- cause any of these to be defined, with the exception that _DEBUG
- causes Py_DEBUG. Double-check that. */
-# ifdef Py_LIMITED_API
-# if defined(Py_DEBUG)
-# error "pyconfig.h unexpectedly defines Py_DEBUG, but Py_LIMITED_API
is set"
-# endif
-# if defined(Py_TRACE_REFS)
-# error "pyconfig.h unexpectedly defines Py_TRACE_REFS, but
Py_LIMITED_API is set"
-# endif
-# if defined(Py_REF_DEBUG)
-# error "pyconfig.h unexpectedly defines Py_REF_DEBUG, but
Py_LIMITED_API is set"
-# endif
-# endif
-# else
-# include <pyconfig.h>
-# if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG)
-# define Py_LIMITED_API
-# endif
+# include <pyconfig.h>
+# if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG)
+# define Py_LIMITED_API
# endif
#endif
diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h
--- a/lib_pypy/cffi/_embedding.h
+++ b/lib_pypy/cffi/_embedding.h
@@ -221,7 +221,7 @@
if (f != NULL && f != Py_None) {
PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME
- "\ncompiled with cffi version: 1.12.0"
+ "\ncompiled with cffi version: 1.12.1"
"\n_cffi_backend module: ", f);
modules = PyImport_GetModuleDict();
mod = PyDict_GetItemString(modules, "_cffi_backend");
diff --git a/lib_pypy/cffi/setuptools_ext.py b/lib_pypy/cffi/setuptools_ext.py
--- a/lib_pypy/cffi/setuptools_ext.py
+++ b/lib_pypy/cffi/setuptools_ext.py
@@ -81,8 +81,14 @@
it doesn't so far, creating troubles. That's why we check
for "not hasattr(sys, 'gettotalrefcount')" (the 2.7 compatible equivalent
of 'd' not in sys.abiflags). (http://bugs.python.org/issue28401)
+
+ On Windows, with CPython <= 3.4, it's better not to use py_limited_api
+ because virtualenv *still* doesn't copy PYTHON3.DLL on these versions.
+ For now we'll skip py_limited_api on all Windows versions to avoid an
+ inconsistent mess.
"""
- if 'py_limited_api' not in kwds and not hasattr(sys, 'gettotalrefcount'):
+ if ('py_limited_api' not in kwds and not hasattr(sys, 'gettotalrefcount')
+ and sys.platform != 'win32'):
import setuptools
try:
setuptools_major_version =
int(setuptools.__version__.partition('.')[0])
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py
b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -1,7 +1,7 @@
# ____________________________________________________________
import sys
-assert __version__ == "1.12.0", ("This test_c.py file is for testing a version"
+assert __version__ == "1.12.1", ("This test_c.py file is for testing a version"
" of cffi that differs from the one that we"
" get from 'import _cffi_backend'")
if sys.version_info < (3,):
diff --git a/pypy/module/cpyext/listobject.py b/pypy/module/cpyext/listobject.py
--- a/pypy/module/cpyext/listobject.py
+++ b/pypy/module/cpyext/listobject.py
@@ -104,7 +104,8 @@
def PyList_GET_SIZE(space, w_obj):
"""Macro form of PyList_Size() without error checking.
"""
- return space.len_w(w_obj)
+ assert isinstance(w_obj, W_ListObject)
+ return w_obj.length()
@cpython_api([PyObject], Py_ssize_t, error=-1)
diff --git a/pypy/module/cpyext/sequence.py b/pypy/module/cpyext/sequence.py
--- a/pypy/module/cpyext/sequence.py
+++ b/pypy/module/cpyext/sequence.py
@@ -50,50 +50,56 @@
converted to a sequence, and raises a TypeError, raise a new TypeError with
m as the message text. If the conversion otherwise, fails, reraise the
original exception"""
- if isinstance(w_obj, tupleobject.W_TupleObject):
+ if isinstance(w_obj, tupleobject.W_AbstractTupleObject):
return w_obj # CCC avoid the double conversion that occurs here
if isinstance(w_obj, W_ListObject):
- # make sure we can return a borrowed obj from PySequence_Fast_GET_ITEM
- w_obj.convert_to_cpy_strategy(space)
+ # note: we used to call w_obj.convert_to_cpy_strategy() here,
+ # but we really have to call it from PySequence_Fast_GET_ITEM()
+ # because some people never call PySequence_Fast() if they know
+ # the object is a list.
return w_obj
try:
- return W_ListObject.newlist_cpyext(space, space.listview(w_obj))
+ return tupleobject.W_TupleObject(space.fixedview(w_obj))
except OperationError as e:
if e.match(space, space.w_TypeError):
raise OperationError(space.w_TypeError,
space.newtext(rffi.charp2str(m)))
raise e
-# CCC this should be written as a C macro
-@cpython_api([rffi.VOIDP, Py_ssize_t], PyObject, result_borrowed=True)
-def PySequence_Fast_GET_ITEM(space, w_obj, index):
+# CCC this should be written as a C macro, at least for the tuple case
+@cpython_api([rffi.VOIDP, Py_ssize_t], PyObject, result_is_ll=True)
+def PySequence_Fast_GET_ITEM(space, py_obj, index):
"""Return the ith element of o, assuming that o was returned by
PySequence_Fast(), o is not NULL, and that i is within bounds.
"""
- if isinstance(w_obj, W_ListObject):
- return w_obj.getitem(index)
- elif isinstance(w_obj, tupleobject.W_TupleObject):
- return w_obj.wrappeditems[index]
- raise oefmt(space.w_TypeError,
- "PySequence_Fast_GET_ITEM called but object is not a list or "
- "sequence")
+ py_obj = rffi.cast(PyObject, py_obj)
+ if PyTuple_Check(space, py_obj):
+ from pypy.module.cpyext.tupleobject import PyTupleObject
+ py_tuple = rffi.cast(PyTupleObject, py_obj)
+ return py_tuple.c_ob_item[index]
+ else:
+ from pypy.module.cpyext.listobject import PyList_GET_ITEM
+ w_obj = from_ref(space, py_obj)
+ return PyList_GET_ITEM(space, w_obj, index)
@cpython_api([rffi.VOIDP], Py_ssize_t, error=CANNOT_FAIL)
-def PySequence_Fast_GET_SIZE(space, w_obj):
+def PySequence_Fast_GET_SIZE(space, py_obj):
"""Returns the length of o, assuming that o was returned by
PySequence_Fast() and that o is not NULL. The size can also be
gotten by calling PySequence_Size() on o, but
PySequence_Fast_GET_SIZE() is faster because it can assume o is a list
or tuple."""
- if isinstance(w_obj, W_ListObject):
- return w_obj.length()
- elif isinstance(w_obj, tupleobject.W_TupleObject):
- return len(w_obj.wrappeditems)
- raise oefmt(space.w_TypeError,
- "PySequence_Fast_GET_SIZE called but object is not a list or "
- "sequence")
+ py_obj = rffi.cast(PyObject, py_obj)
+ if PyTuple_Check(space, py_obj):
+ from pypy.module.cpyext.tupleobject import PyTupleObject
+ py_tuple = rffi.cast(PyTupleObject, py_obj)
+ return py_tuple.c_ob_size
+ else:
+ from pypy.module.cpyext.listobject import PyList_GET_SIZE
+ w_obj = from_ref(space, py_obj)
+ return PyList_GET_SIZE(space, w_obj)
@cpython_api([rffi.VOIDP], PyObjectP)
-def PySequence_Fast_ITEMS(space, w_obj):
+def PySequence_Fast_ITEMS(space, py_obj):
"""Return the underlying array of PyObject pointers. Assumes that o was
returned
by PySequence_Fast() and o is not NULL.
@@ -101,18 +107,17 @@
So, only use the underlying array pointer in contexts where the sequence
cannot change.
"""
- if isinstance(w_obj, W_ListObject):
- cpy_strategy = space.fromcache(CPyListStrategy)
- if w_obj.strategy is cpy_strategy:
- return w_obj.get_raw_items() # asserts it's a cpyext strategy
- elif isinstance(w_obj, tupleobject.W_TupleObject):
+ py_obj = rffi.cast(PyObject, py_obj)
+ if PyTuple_Check(space, py_obj):
from pypy.module.cpyext.tupleobject import PyTupleObject
- py_obj = as_pyobj(space, w_obj)
py_tuple = rffi.cast(PyTupleObject, py_obj)
return rffi.cast(PyObjectP, py_tuple.c_ob_item)
- raise oefmt(space.w_TypeError,
- "PySequence_Fast_ITEMS called but object is not the result of "
- "PySequence_Fast")
+ else:
+ from pypy.module.cpyext.listobject import get_list_storage
+ w_obj = from_ref(space, py_obj)
+ assert isinstance(w_obj, W_ListObject)
+ storage = get_list_storage(space, w_obj)
+ return rffi.cast(PyObjectP, storage._elems)
@cpython_api([PyObject, Py_ssize_t, Py_ssize_t], PyObject)
def PySequence_GetSlice(space, w_obj, start, end):
@@ -300,10 +305,6 @@
storage = self.unerase(w_list.lstorage)
return storage._length
- def get_raw_items(self, w_list):
- storage = self.unerase(w_list.lstorage)
- return storage._elems
-
def getslice(self, w_list, start, stop, step, length):
w_list.switch_to_object_strategy()
return w_list.strategy.getslice(w_list, start, stop, step, length)
diff --git a/pypy/module/cpyext/test/test_cpyext.py
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -141,6 +141,7 @@
'_cffi_backend',
],
"objspace.disable_entrypoints_in_cffi": True}
+ spaceconfig["objspace.std.withspecialisedtuple"] = True
@classmethod
def preload_builtins(cls, space):
diff --git a/pypy/module/cpyext/test/test_sequence.py
b/pypy/module/cpyext/test/test_sequence.py
--- a/pypy/module/cpyext/test/test_sequence.py
+++ b/pypy/module/cpyext/test/test_sequence.py
@@ -5,7 +5,7 @@
from pypy.module.cpyext.sequence import (
PySequence_Fast, PySequence_Contains, PySequence_Index,
PySequence_GetItem, PySequence_SetItem, PySequence_DelItem)
-from pypy.module.cpyext.pyobject import get_w_obj_and_decref
+from pypy.module.cpyext.pyobject import get_w_obj_and_decref, from_ref
from pypy.module.cpyext.state import State
import pytest
@@ -21,12 +21,14 @@
w_l = space.wrap([1, 2, 3, 4])
assert api.PySequence_Fast(w_l, "message") is w_l
- assert space.int_w(api.PySequence_Fast_GET_ITEM(w_l, 1)) == 2
+ py_result = api.PySequence_Fast_GET_ITEM(w_l, 1)
+ w_result = from_ref(space, py_result)
+ assert space.int_w(w_result) == 2
assert api.PySequence_Fast_GET_SIZE(w_l) == 4
w_set = space.wrap(set((1, 2, 3, 4)))
w_seq = api.PySequence_Fast(w_set, "message")
- assert space.type(w_seq) is space.w_list
+ assert space.type(w_seq) is space.w_tuple
assert space.len_w(w_seq) == 4
w_seq = api.PySequence_Tuple(w_set)
@@ -83,7 +85,7 @@
def test_get_slice_fast(self, space, api):
w_t = space.wrap([1, 2, 3, 4, 5])
- api.PySequence_Fast(w_t, "foo") # converts
+ api.PyList_GetItem(w_t, 0) # converts to cpy strategy
assert space.unwrap(api.PySequence_GetSlice(w_t, 2, 4)) == [3, 4]
assert space.unwrap(api.PySequence_GetSlice(w_t, 1, -1)) == [2, 3, 4]
@@ -215,7 +217,7 @@
class TestCPyListStrategy(BaseApiTest):
def test_getitem_setitem(self, space, api):
w_l = space.wrap([1, 2, 3, 4])
- api.PySequence_Fast(w_l, "foo") # converts
+ api.PyList_GetItem(w_l, 0) # converts to cpy strategy
assert space.int_w(space.len(w_l)) == 4
assert space.int_w(space.getitem(w_l, space.wrap(1))) == 2
assert space.int_w(space.getitem(w_l, space.wrap(0))) == 1
@@ -229,17 +231,17 @@
w = space.wrap
w_l = w([1, 2, 3, 4])
- api.PySequence_Fast(w_l, "foo") # converts
+ api.PyList_GetItem(w_l, 0) # converts to cpy strategy
space.call_method(w_l, 'insert', w(0), w(0))
assert space.int_w(space.len(w_l)) == 5
assert space.int_w(space.getitem(w_l, w(3))) == 3
- api.PySequence_Fast(w_l, "foo") # converts
+ api.PyList_GetItem(w_l, 0) # converts to cpy strategy
space.call_method(w_l, 'sort')
assert space.int_w(space.len(w_l)) == 5
assert space.int_w(space.getitem(w_l, w(0))) == 0
- api.PySequence_Fast(w_l, "foo") # converts
+ api.PyList_GetItem(w_l, 0) # converts to cpy strategy
w_t = space.wrap(space.fixedview(w_l))
assert space.int_w(space.len(w_t)) == 5
assert space.int_w(space.getitem(w_t, w(0))) == 0
@@ -247,22 +249,22 @@
assert space.int_w(space.len(w_l2)) == 5
assert space.int_w(space.getitem(w_l2, w(0))) == 0
- api.PySequence_Fast(w_l, "foo") # converts
+ api.PyList_GetItem(w_l, 0) # converts to cpy strategy
w_sum = space.add(w_l, w_l)
assert space.int_w(space.len(w_sum)) == 10
- api.PySequence_Fast(w_l, "foo") # converts
+ api.PyList_GetItem(w_l, 0) # converts to cpy strategy
w_prod = space.mul(w_l, space.wrap(2))
assert space.int_w(space.len(w_prod)) == 10
- api.PySequence_Fast(w_l, "foo") # converts
+ api.PyList_GetItem(w_l, 0) # converts to cpy strategy
w_l.inplace_mul(2)
assert space.int_w(space.len(w_l)) == 10
def test_getstorage_copy(self, space, api):
w = space.wrap
w_l = w([1, 2, 3, 4])
- api.PySequence_Fast(w_l, "foo") # converts
+ api.PyList_GetItem(w_l, 0) # converts to cpy strategy
w_l1 = w([])
space.setitem(w_l1, space.newslice(w(0), w(0), w(1)), w_l)
@@ -285,6 +287,10 @@
if (objects == NULL)
return NULL;
size = PySequence_Fast_GET_SIZE(foo);
+ for (i = 0; i < size; ++i) {
+ if (objects[i] != PySequence_Fast_GET_ITEM(foo, i))
+ return PyBool_FromLong(0);
+ }
common_type = size > 0 ? Py_TYPE(objects[0]) : NULL;
for (i = 1; i < size; ++i) {
if (Py_TYPE(objects[i]) != common_type) {
@@ -304,6 +310,9 @@
s = (1, 2, 3, 4)
assert module.test_fast_sequence(s[0:-1])
assert module.test_fast_sequence(s[::-1])
+ s = (1, 2) # specialized tuple
+ assert module.test_fast_sequence(s[0:-1])
+ assert module.test_fast_sequence(s[::-1])
s = "1234"
assert module.test_fast_sequence(s[0:-1])
assert module.test_fast_sequence(s[::-1])
diff --git a/pypy/module/cpyext/test/test_typeobject.py
b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -514,7 +514,8 @@
py_type = rffi.cast(PyTypeObjectPtr, ref)
assert py_type.c_tp_alloc
- assert from_ref(space, py_type.c_tp_mro).wrappeditems is w_class.mro_w
+ w_tup = from_ref(space, py_type.c_tp_mro)
+ assert space.fixedview(w_tup) == w_class.mro_w
decref(space, ref)
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
@@ -45,7 +45,8 @@
# for json decoder
def create_empty_unicode_key_dict(space):
return r_dict(unicode_eq, unicode_hash,
- force_non_null=True)
+ force_non_null=True,
+ simple_hash_eq=True)
def from_unicode_key_dict(space, d):
strategy = space.fromcache(UnicodeDictStrategy)
@@ -1176,6 +1177,7 @@
return unwrapped
def unwrap(self, wrapped):
+ assert type(wrapped) is self.space.UnicodeObjectCls
return wrapped
def is_correct_type(self, w_obj):
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -214,13 +214,6 @@
storage = strategy.erase(list_f)
return W_ListObject.from_storage_and_strategy(space, storage, strategy)
- @staticmethod
- def newlist_cpyext(space, list):
- from pypy.module.cpyext.sequence import CPyListStrategy, CPyListStorage
- strategy = space.fromcache(CPyListStrategy)
- storage = strategy.erase(CPyListStorage(space, list))
- return W_ListObject.from_storage_and_strategy(space, storage, strategy)
-
def __repr__(self):
""" representation for debugging purposes """
return "%s(%s, %s)" % (self.__class__.__name__, self.strategy,
@@ -259,13 +252,6 @@
self.strategy = cpy_strategy
self.lstorage = cpy_strategy.erase(CPyListStorage(space, lst))
- def get_raw_items(self):
- from pypy.module.cpyext.sequence import CPyListStrategy
-
- cpy_strategy = self.space.fromcache(CPyListStrategy)
- assert self.strategy is cpy_strategy # should we return an error?
- return cpy_strategy.get_raw_items(self)
-
# ___________________________________________________
def init_from_list_w(self, list_w):
diff --git a/rpython/rlib/rutf8.py b/rpython/rlib/rutf8.py
--- a/rpython/rlib/rutf8.py
+++ b/rpython/rlib/rutf8.py
@@ -133,9 +133,11 @@
return pos + 1
if _is_64bit and not jit.we_are_jitted():
# optimized for Intel x86-64 by hand
- return pos + 1 + (
+ res = pos + 1 + (
((chr1 > 0xDF) << 1) +
rarithmetic.intmask((_constant_ncp >> (chr1 & 0x3F)) & 1))
+ assert res >= 0
+ return res
if chr1 <= 0xDF:
return pos + 2
if chr1 <= 0xEF:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit