Author: Ronan Lamy <[email protected]>
Branch: py3.5
Changeset: r92166:90593ef2b17c
Date: 2017-08-18 16:28 +0200
http://bitbucket.org/pypy/pypy/changeset/90593ef2b17c/
Log: hg merge default
diff --git a/lib-python/2.7/ctypes/__init__.py
b/lib-python/2.7/ctypes/__init__.py
--- a/lib-python/2.7/ctypes/__init__.py
+++ b/lib-python/2.7/ctypes/__init__.py
@@ -361,17 +361,20 @@
if handle is None:
if flags & _FUNCFLAG_CDECL:
- self._handle = _ffi.CDLL(name, mode)
+ pypy_dll = _ffi.CDLL(name, mode)
else:
- self._handle = _ffi.WinDLL(name, mode)
- else:
- self._handle = handle
+ pypy_dll = _ffi.WinDLL(name, mode)
+ self._pypy_dll = pypy_dll
+ handle = int(pypy_dll)
+ if _sys.maxint > 2 ** 32:
+ handle = int(handle) # long -> int
+ self._handle = handle
def __repr__(self):
- return "<%s '%s', handle %r at 0x%x>" % (
- self.__class__.__name__, self._name, self._handle,
- id(self) & (_sys.maxint * 2 + 1))
-
+ return "<%s '%s', handle %x at %x>" % \
+ (self.__class__.__name__, self._name,
+ (self._handle & (_sys.maxint*2 + 1)),
+ id(self) & (_sys.maxint*2 + 1))
def __getattr__(self, name):
if name.startswith('__') and name.endswith('__'):
diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py
--- a/lib_pypy/_ctypes/basics.py
+++ b/lib_pypy/_ctypes/basics.py
@@ -82,7 +82,7 @@
return False
def in_dll(self, dll, name):
- return self.from_address(dll._handle.getaddressindll(name))
+ return self.from_address(dll._pypy_dll.getaddressindll(name))
def from_buffer(self, obj, offset=0):
size = self._sizeofinstances()
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -430,7 +430,7 @@
ffires = restype.get_ffi_argtype()
return _ffi.FuncPtr.fromaddr(ptr, '', ffiargs, ffires,
self._flags_)
- cdll = self.dll._handle
+ cdll = self.dll._pypy_dll
try:
ffi_argtypes = [argtype.get_ffi_argtype() for argtype in argtypes]
ffi_restype = restype.get_ffi_argtype()
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -1632,7 +1632,7 @@
assert cpyext_glob_tid_ptr[0] == 0
cpyext_glob_tid_ptr[0] = tid
- preexist_error = PyErr_Occurred(space) is not None
+ preexist_error = PyErr_Occurred(space)
try:
# Call the function
result = call_external_function(func, *boxed_args)
@@ -1656,17 +1656,20 @@
has_result = ret is not None
# Check for exception consistency
- has_error = PyErr_Occurred(space) is not None
- if not preexist_error:
- if has_error and has_result:
- raise oefmt(space.w_SystemError,
- "An exception was set, but function returned a
"
- "value")
- elif not expect_null and not has_error and not has_result:
- raise oefmt(space.w_SystemError,
- "Function returned a NULL result without
setting "
- "an exception")
- if has_error:
+ # XXX best attempt, will miss preexisting error that is
+ # overwritten with a new error of the same type
+ error = PyErr_Occurred(space)
+ has_new_error = (error is not None) and (error is not
preexist_error)
+ has_result = ret is not None
+ if not expect_null and has_new_error and has_result:
+ raise oefmt(space.w_SystemError,
+ "An exception was set, but function returned a "
+ "value")
+ elif not expect_null and not has_new_error and not has_result:
+ raise oefmt(space.w_SystemError,
+ "Function returned a NULL result without setting "
+ "an exception")
+ elif has_new_error:
state = space.fromcache(State)
state.check_and_raise_exception()
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
@@ -24,6 +24,10 @@
def PyPy_Crash2(space):
1/0
[email protected]_api([api.PyObject], api.PyObject, result_is_ll=True)
+def PyPy_Noop(space, pyobj):
+ return pyobj
+
class TestApi:
def test_signature(self):
common_functions = api.FUNCTIONS_BY_HEADER[api.pypy_decl]
@@ -665,6 +669,7 @@
body = """
PyAPI_FUNC(PyObject*) PyPy_Crash1(void);
PyAPI_FUNC(long) PyPy_Crash2(void);
+ PyAPI_FUNC(PyObject*) PyPy_Noop(PyObject*);
static PyObject* foo_crash1(PyObject* self, PyObject *args)
{
return PyPy_Crash1();
@@ -688,9 +693,27 @@
int a = PyPy_Crash2();
return PyFloat_FromDouble(a);
}
+ static PyObject* foo_noop(PyObject* self, PyObject* args)
+ {
+ Py_INCREF(args);
+ return PyPy_Noop(args);
+ }
+ static PyObject* foo_set(PyObject* self, PyObject *args)
+ {
+ PyErr_SetString(PyExc_TypeError, "clear called with no error");
+ if (PyLong_Check(args)) {
+ Py_INCREF(args);
+ return args;
+ }
+ return NULL;
+ }
static PyObject* foo_clear(PyObject* self, PyObject *args)
{
PyErr_Clear();
+ if (PyLong_Check(args)) {
+ Py_INCREF(args);
+ return args;
+ }
return NULL;
}
static PyMethodDef methods[] = {
@@ -698,7 +721,9 @@
{ "crash2", foo_crash2, METH_NOARGS },
{ "crash3", foo_crash3, METH_NOARGS },
{ "crash4", foo_crash4, METH_NOARGS },
- { "clear", foo_clear, METH_NOARGS },
+ { "clear", foo_clear, METH_O },
+ { "set", foo_set, METH_O },
+ { "noop", foo_noop, METH_O },
{ NULL }
};
static struct PyModuleDef moduledef = {
@@ -710,15 +735,46 @@
};
"""
module = self.import_module(name='foo', body=body)
+
# uncaught interplevel exceptions are turned into SystemError
- raises(SystemError, module.crash1)
- raises(SystemError, module.crash2)
- # caught exception
+ expected = "ZeroDivisionError('integer division or modulo by zero',)"
+ exc = raises(SystemError, module.crash1)
+ assert exc.value[0] == expected
+
+ exc = raises(SystemError, module.crash2)
+ assert exc.value[0] == expected
+
+ # caught exception, api.cpython_api return value works
assert module.crash3() == -1
- # An exception was set, but function returned a value
- raises(SystemError, module.crash4)
- # No exception set, but NULL returned
- raises(SystemError, module.clear)
+
+ expected = 'An exception was set, but function returned a value'
+ # PyPy only incompatibility/extension
+ exc = raises(SystemError, module.crash4)
+ assert exc.value[0] == expected
+
+ # An exception was set by the previous call, it can pass
+ # cleanly through a call that doesn't check error state
+ assert module.noop(1) == 1
+
+ # clear the exception but return NULL, signalling an error
+ expected = 'Function returned a NULL result without setting an
exception'
+ exc = raises(SystemError, module.clear, None)
+ assert exc.value[0] == expected
+
+ # Set an exception and return NULL
+ raises(TypeError, module.set, None)
+
+ # clear any exception and return a value
+ assert module.clear(1) == 1
+
+ # Set an exception, but return non-NULL
+ expected = 'An exception was set, but function returned a value'
+ exc = raises(SystemError, module.set, 1)
+ assert exc.value[0] == expected
+
+
+ # Clear the exception and return a value, all is OK
+ assert module.clear(1) == 1
def test_new_exception(self):
mod = self.import_extension('foo', [
diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py
--- a/pypy/module/imp/test/test_app.py
+++ b/pypy/module/imp/test/test_app.py
@@ -81,15 +81,17 @@
def test_suffixes(self):
import imp
for suffix, mode, type in imp.get_suffixes():
- if mode == imp.PY_SOURCE:
+ if type == imp.PY_SOURCE:
assert suffix == '.py'
- assert type == 'r'
- elif mode == imp.PY_COMPILED:
+ assert mode == 'U'
+ elif type == imp.PY_COMPILED:
assert suffix in ('.pyc', '.pyo')
- assert type == 'rb'
- elif mode == imp.C_EXTENSION:
+ assert mode == 'rb'
+ elif type == imp.C_EXTENSION:
assert suffix.endswith(('.pyd', '.so'))
- assert type == 'rb'
+ assert mode == 'rb'
+ else:
+ assert False, ("Unknown type", suffix, mode, type)
def test_ext_suffixes(self):
import _imp
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_loading.py
b/pypy/module/test_lib_pypy/ctypes_tests/test_loading.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_loading.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_loading.py
@@ -43,6 +43,12 @@
cdll.LoadLibrary(lib)
CDLL(lib)
+ def test__handle(self):
+ lib = find_library("c")
+ if lib:
+ cdll = CDLL(lib)
+ assert type(cdll._handle) in (int, long)
+
if os.name in ("nt", "ce"):
def test_load_library(self):
if is_resource_enabled("printing"):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit