[pypy-svn] r74360 - in pypy/trunk/pypy/module/cpyext: . test
afa at codespeak.net
afa at codespeak.net
Tue May 4 16:34:36 CEST 2010
Author: afa
Date: Tue May 4 16:34:34 2010
New Revision: 74360
Modified:
pypy/trunk/pypy/module/cpyext/api.py
pypy/trunk/pypy/module/cpyext/pyerrors.py
pypy/trunk/pypy/module/cpyext/state.py
pypy/trunk/pypy/module/cpyext/test/test_api.py
pypy/trunk/pypy/module/cpyext/test/test_pyerrors.py
Log:
Store an OperationError instead of the (exc_type, exc_value) attributes pair.
This is a little faster when errors are passed from C to pypy and vice-versa,
and it will be easier to add the traceback.
Modified: pypy/trunk/pypy/module/cpyext/api.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/api.py (original)
+++ pypy/trunk/pypy/module/cpyext/api.py Tue May 4 16:34:34 2010
@@ -210,8 +210,7 @@
if not hasattr(api_function, "error_value"):
raise
state = space.fromcache(State)
- e.normalize_exception(space)
- state.set_exception(e.w_type, e.get_w_value(space))
+ state.set_exception(e)
if restype is PyObject:
return None
else:
@@ -426,11 +425,11 @@
print >>sys.stderr, " DONE"
except OperationError, e:
failed = True
- e.normalize_exception(space)
- state.set_exception(e.w_type, e.get_w_value(space))
+ state.set_exception(e)
except BaseException, e:
failed = True
- state.set_exception(space.w_SystemError, space.wrap(str(e)))
+ state.set_exception(OperationError(space.w_SystemError,
+ space.wrap(str(e))))
if not we_are_translated():
import traceback
traceback.print_exc()
Modified: pypy/trunk/pypy/module/cpyext/pyerrors.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/pyerrors.py (original)
+++ pypy/trunk/pypy/module/cpyext/pyerrors.py Tue May 4 16:34:34 2010
@@ -14,7 +14,7 @@
"""This function is similar to PyErr_SetString() but lets you specify an
arbitrary Python object for the "value" of the exception."""
state = space.fromcache(State)
- state.set_exception(w_type, w_value)
+ state.set_exception(OperationError(w_type, w_value))
@cpython_api([PyObject, CONST_STRING], lltype.Void)
def PyErr_SetString(space, w_type, message_ptr):
@@ -29,8 +29,10 @@
@cpython_api([], PyObject, borrowed=True)
def PyErr_Occurred(space):
state = space.fromcache(State)
+ if state.operror is None:
+ return None
register_container(space, lltype.nullptr(PyObject.TO))
- return state.exc_type
+ return state.operror.w_type
@cpython_api([], lltype.Void)
def PyErr_Clear(space):
@@ -47,10 +49,13 @@
This function is normally only used by code that needs to handle exceptions or
by code that needs to save and restore the error indicator temporarily."""
state = space.fromcache(State)
- ptype[0] = make_ref(space, state.exc_type, steal=True)
- pvalue[0] = make_ref(space, state.exc_type, steal=True)
- state.exc_type = None
- state.exc_value = None
+ operror = state.clear_exception()
+ if operror:
+ ptype[0] = make_ref(space, operror.w_type)
+ pvalue[0] = make_ref(space, operror.get_w_value(space))
+ else:
+ ptype[0] = lltype.nullptr(PyObject.TO)
+ pvalue[0] = lltype.nullptr(PyObject.TO)
ptraceback[0] = lltype.nullptr(PyObject.TO)
@cpython_api([PyObject, PyObject, PyObject], lltype.Void)
@@ -69,8 +74,7 @@
error indicator temporarily; use PyErr_Fetch() to save the current
exception state."""
state = space.fromcache(State)
- state.exc_type = w_type
- state.exc_value = w_value
+ state.set_exception(OperationError(w_type, w_value))
Py_DecRef(space, w_type)
Py_DecRef(space, w_value)
Modified: pypy/trunk/pypy/module/cpyext/state.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/state.py (original)
+++ pypy/trunk/pypy/module/cpyext/state.py Tue May 4 16:34:34 2010
@@ -18,8 +18,7 @@
self.borrowed_objects = {} # { addr of containee -> None }
self.non_heaptypes = [] # list of wrapped objects
self.last_container = 0 # addr of last container
- self.exc_type = None
- self.exc_value = None
+ self.operror = None
self.new_method_def = lltype.nullptr(PyMethodDef)
# When importing a package, use this to keep track of its name. This is
@@ -43,31 +42,32 @@
ptr = rffi.cast(ADDR, obj)
self.py_objects_r2w[ptr] = w_obj
- def set_exception(self, w_type, w_value):
+ def set_exception(self, operror):
self.clear_exception()
- self.exc_type = w_type
- self.exc_value = w_value
+ self.operror = operror
def clear_exception(self):
+ """Clear the current exception state, and return the operror.
+ Also frees the borrowed reference returned by PyErr_Occurred()
+ """
from pypy.module.cpyext.pyobject import Py_DecRef, make_ref
from pypy.module.cpyext.api import ADDR
# handling of borrowed objects, remove when we have
# a weakkeydict
- exc_type = make_ref(self.space, self.exc_type, borrowed=True)
- if exc_type:
+ operror = self.operror
+ if operror is not None:
+ exc_type = make_ref(self.space, operror.w_type, borrowed=True)
Py_DecRef(self.space, exc_type)
containee_ptr = rffi.cast(ADDR, exc_type)
del self.borrowed_objects[containee_ptr]
- self.exc_type = None
- self.exc_value = None
+ self.operror = None
+ return operror
def check_and_raise_exception(self, always=False):
- exc_value = self.exc_value
- exc_type = self.exc_type
- if exc_type is not None or exc_value is not None:
+ operror = self.operror
+ if operror:
self.clear_exception()
- op_err = OperationError(exc_type, exc_value)
- raise op_err
+ raise operror
if always:
raise OperationError(self.space.w_SystemError, self.space.wrap(
"Function returned an error result without setting an exception"))
Modified: pypy/trunk/pypy/module/cpyext/test/test_api.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/test_api.py (original)
+++ pypy/trunk/pypy/module/cpyext/test/test_api.py Tue May 4 16:34:34 2010
@@ -30,10 +30,10 @@
raise Exception("%s is not callable" % (f,))
f(*args)
state = space.fromcache(State)
- tp = state.exc_type
- if not tp:
+ operror = state.operror
+ if not operror:
raise Exception("DID NOT RAISE")
- if getattr(space, 'w_' + expected_exc.__name__) is not tp:
+ if getattr(space, 'w_' + expected_exc.__name__) is not operror.w_type:
raise Exception("Wrong exception")
state.clear_exception()
Modified: pypy/trunk/pypy/module/cpyext/test/test_pyerrors.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/test_pyerrors.py (original)
+++ pypy/trunk/pypy/module/cpyext/test/test_pyerrors.py Tue May 4 16:34:34 2010
@@ -50,25 +50,26 @@
api.PyErr_SetObject(space.w_ValueError, space.wrap("a value"))
assert api.PyErr_Occurred() is space.w_ValueError
state = space.fromcache(State)
- assert space.eq_w(state.exc_value, space.wrap("a value"))
+ assert space.eq_w(state.operror.get_w_value(space),
+ space.wrap("a value"))
api.PyErr_Clear()
def test_SetNone(self, space, api):
api.PyErr_SetNone(space.w_KeyError)
state = space.fromcache(State)
- assert space.eq_w(state.exc_type, space.w_KeyError)
- assert space.eq_w(state.exc_value, space.w_None)
+ assert space.eq_w(state.operror.w_type, space.w_KeyError)
+ assert space.eq_w(state.operror.get_w_value(space), space.w_None)
api.PyErr_Clear()
api.PyErr_NoMemory()
- assert space.eq_w(state.exc_type, space.w_MemoryError)
+ assert space.eq_w(state.operror.w_type, space.w_MemoryError)
api.PyErr_Clear()
def test_BadArgument(self, space, api):
api.PyErr_BadArgument()
state = space.fromcache(State)
- assert space.eq_w(state.exc_type, space.w_TypeError)
+ assert space.eq_w(state.operror.w_type, space.w_TypeError)
api.PyErr_Clear()
class AppTestFetch(AppTestCpythonExtensionBase):
@@ -92,7 +93,7 @@
'''
),
])
- module.check_error()
+ assert module.check_error()
def test_fetch_and_restore(self):
module = self.import_extension('foo', [
@@ -106,8 +107,6 @@
return NULL;
if (type != PyExc_TypeError)
Py_RETURN_FALSE;
- if (val->ob_type != type)
- Py_RETURN_FALSE;
PyErr_Restore(type, val, tb);
if (!PyErr_Occurred())
Py_RETURN_FALSE;
@@ -116,7 +115,7 @@
'''
),
])
- module.check_error()
+ assert module.check_error()
def test_SetFromErrno(self):
skip("The test does not set the errno in a way which "
More information about the Pypy-commit
mailing list