Author: Ronan Lamy <[email protected]>
Branch: rffi-parser-2
Changeset: r89510:421ea2f68c13
Date: 2017-01-12 14:34 +0000
http://bitbucket.org/pypy/pypy/changeset/421ea2f68c13/

Log:    hg merge default

diff too long, truncating to 2000 out of 2826 lines

diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -97,3 +97,7 @@
 
 Fix a test failure introduced by strbuf-as-buffer
 
+.. branch: cpyext-FromBuffer
+
+Do not recreate the object in PyMemoryView_FromBuffer, rather pass it to
+the returned PyMemoryViewObject, to take ownership of it. Fixes a ref leak.
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -8,6 +8,7 @@
 
 from rpython.rlib.jit import promote
 from rpython.rlib.objectmodel import compute_identity_hash, specialize
+from rpython.rlib.objectmodel import instantiate
 from rpython.tool.sourcetools import compile2, func_with_new_name
 
 
@@ -221,10 +222,6 @@
     exec source.compile() in miniglobals
     return miniglobals['descr_typecheck_%s' % func.__name__]
 
-def unknown_objclass_getter(space):
-    # NB. this is an AttributeError to make inspect.py happy
-    raise oefmt(space.w_AttributeError, "generic property has no __objclass__")
-
 @specialize.arg(0)
 def make_objclass_getter(tag, func, cls):
     if func and hasattr(func, 'im_func'):
@@ -235,7 +232,7 @@
 @specialize.memo()
 def _make_objclass_getter(cls):
     if not cls:
-        return unknown_objclass_getter, cls
+        return None, cls
     miniglobals = {}
     if isinstance(cls, str):
         assert cls.startswith('<'), "pythontype typecheck should begin with <"
@@ -254,6 +251,8 @@
 
 class GetSetProperty(W_Root):
     _immutable_fields_ = ["fget", "fset", "fdel"]
+    name = '<generic property>'
+    w_objclass = None
 
     @specialize.arg(7)
     def __init__(self, fget, fset=None, fdel=None, doc=None,
@@ -265,15 +264,25 @@
                                             cls=cls, use_closure=use_closure)
         fdel = make_descr_typecheck_wrapper((tag, 2), fdel,
                                             cls=cls, use_closure=use_closure)
+        self._init(fget, fset, fdel, doc, cls, objclass_getter, use_closure)
+
+    def _init(self, fget, fset, fdel, doc, cls, objclass_getter, use_closure):
         self.fget = fget
         self.fset = fset
         self.fdel = fdel
         self.doc = doc
         self.reqcls = cls
-        self.name = '<generic property>'
         self.objclass_getter = objclass_getter
         self.use_closure = use_closure
 
+    def copy_for_type(self, w_objclass):
+        new = instantiate(GetSetProperty)
+        new._init(self.fget, self.fset, self.fdel, self.doc, self.reqcls,
+                  None, self.use_closure)
+        new.name = self.name
+        new.w_objclass = w_objclass
+        return new
+
     @unwrap_spec(w_cls = WrappedDefault(None))
     def descr_property_get(self, space, w_obj, w_cls=None):
         """property.__get__(obj[, type]) -> value
@@ -322,7 +331,14 @@
                                                space.wrap(self.name)]))
 
     def descr_get_objclass(space, property):
-        return property.objclass_getter(space)
+        if property.w_objclass is not None:
+            return property.w_objclass
+        if property.objclass_getter is not None:
+            return property.objclass_getter(space)
+        # NB. this is an AttributeError to make inspect.py happy
+        raise oefmt(space.w_AttributeError,
+                    "generic property has no __objclass__")
+
 
 def interp_attrproperty(name, cls, doc=None):
     "NOT_RPYTHON: initialization-time only"
@@ -467,7 +483,7 @@
     return lifeline.get_any_weakref(space)
 
 dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict,
-                            doc="dictionary for instance variables (if 
defined)")
+                            doc="dictionary for instance variables")
 dict_descr.name = '__dict__'
 
 
@@ -499,7 +515,7 @@
     return space.newtuple([w_docstring])
 
 weakref_descr = GetSetProperty(descr_get_weakref,
-                    doc="list of weak references to the object (if defined)")
+                               doc="list of weak references to the object")
 weakref_descr.name = '__weakref__'
 
 def make_weakref_descr(cls):
diff --git a/pypy/module/cppyy/test/conftest.py 
b/pypy/module/cppyy/test/conftest.py
--- a/pypy/module/cppyy/test/conftest.py
+++ b/pypy/module/cppyy/test/conftest.py
@@ -23,6 +23,10 @@
 def pytest_ignore_collect(path, config):
     if py.path.local.sysfind('genreflex') is None and 
config.option.runappdirect:
         return True          # "can't run dummy tests in -A"
+    if disabled:
+        return True
+
+disabled = None
 
 def pytest_configure(config):
     if py.path.local.sysfind('genreflex') is None:
@@ -37,7 +41,7 @@
             # build dummy backend (which has reflex info and calls hard-wired)
             import os
             from rpython.translator.tool.cbuild import ExternalCompilationInfo
-            from rpython.translator.platform import platform
+            from rpython.translator.platform import platform, CompilationError
             from rpython.translator import cdir
 
             from rpython.rtyper.lltypesystem import rffi
@@ -55,9 +59,16 @@
                 use_cpp_linker=True,
             )
 
-            soname = platform.compile(
-                [], eci,
-                outputfilename='libcppyy_dummy_backend',
-                standalone=False)
+            try:
+                soname = platform.compile(
+                    [], eci,
+                    outputfilename='libcppyy_dummy_backend',
+                    standalone=False)
+            except CompilationError as e:
+                if '-std=c++11' in str(e):
+                    global disabled
+                    disabled = str(e)
+                    return
+                raise
 
             lcapi.reflection_library = str(soname)
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
@@ -123,6 +123,7 @@
 METH_NOARGS METH_VARARGS METH_KEYWORDS METH_O Py_TPFLAGS_HAVE_INPLACEOPS
 Py_TPFLAGS_HEAPTYPE Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_HAVE_NEWBUFFER
 Py_LT Py_LE Py_EQ Py_NE Py_GT Py_GE Py_TPFLAGS_CHECKTYPES Py_MAX_NDIMS
+PyBUF_FORMAT PyBUF_ND PyBUF_STRIDES
 """.split()
 for name in constant_names:
     setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name))
@@ -244,14 +245,13 @@
 cpyext_namespace = NameManager('cpyext_')
 
 class ApiFunction(object):
-    def __init__(self, argtypes, restype, callable, error=_NOT_SPECIFIED,
+    def __init__(self, argtypes, restype, callable, error=CANNOT_FAIL,
                  c_name=None, gil=None, result_borrowed=False, 
result_is_ll=False):
         self.argtypes = argtypes
         self.restype = restype
         self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype))
         self.callable = callable
-        if error is not _NOT_SPECIFIED:
-            self.error_value = error
+        self.error_value = error
         self.c_name = c_name
 
         # extract the signature from the (CPython-level) code object
@@ -291,7 +291,7 @@
 
         argtypesw = zip(self.argtypes,
                         [_name.startswith("w_") for _name in self.argnames])
-        error_value = getattr(self, "error_value", CANNOT_FAIL)
+        error_value = self.error_value
         if (isinstance(self.restype, lltype.Ptr)
                 and error_value is not CANNOT_FAIL):
             assert lltype.typeOf(error_value) == self.restype
@@ -429,12 +429,12 @@
     def decorate(func):
         if func.__name__ in FUNCTIONS_BY_HEADER[header]:
             raise ValueError("%s already registered" % func.__name__)
-        api_function = _create_api_func(
-            func, argtypes, restype, error, gil=gil,
+        func._always_inline_ = 'try'
+        api_function = ApiFunction(
+            argtypes, restype, func,
+            error=_compute_error(error, restype), gil=gil,
             result_borrowed=result_borrowed, result_is_ll=result_is_ll)
-        unwrapper = api_function.get_unwrapper()
-        unwrapper.func = func
-        unwrapper.api_func = api_function
+        FUNCTIONS_BY_HEADER[header][func.__name__] = api_function
 
         # ZZZ is this whole logic really needed???  It seems to be only
         # for RPython code calling PyXxx() functions directly.  I would
@@ -462,32 +462,33 @@
             assert got_integer == expect_integer, (
                 'got %r not integer' % (res,))
             return res
+        INTERPLEVEL_API[func.__name__] = unwrapper_catch  # used in tests
 
-        if header is not None:
-            FUNCTIONS_BY_HEADER[header][func.__name__] = api_function
-            INTERPLEVEL_API[func.__name__] = unwrapper_catch  # used in tests
-        return unwrapper
-    return decorate
-
-def slot_function(argtypes, restype, error=_NOT_SPECIFIED):
-    def decorate(func):
-        c_name = func.__name__
-        api_function = _create_api_func(func, argtypes, restype, error, c_name)
         unwrapper = api_function.get_unwrapper()
         unwrapper.func = func
         unwrapper.api_func = api_function
         return unwrapper
     return decorate
 
+def slot_function(argtypes, restype, error=_NOT_SPECIFIED):
+    def decorate(func):
+        func._always_inline_ = 'try'
+        api_function = ApiFunction(
+            argtypes, restype, func,
+            error=_compute_error(error, restype),
+            c_name=func.__name__)
+        unwrapper = api_function.get_unwrapper()
+        unwrapper.func = func
+        unwrapper.api_func = api_function
+        return unwrapper
+    return decorate
 
-def _create_api_func(
-        func, argtypes, restype, error=_NOT_SPECIFIED, c_name=None,
-        gil=None, result_borrowed=False, result_is_ll=False):
+def _compute_error(error, restype):
+    """Convert error specification to actual error value of type restype."""
     if isinstance(restype, lltype.Typedef):
         real_restype = restype.OF
     else:
         real_restype = restype
-
     if error is _NOT_SPECIFIED:
         if isinstance(real_restype, lltype.Ptr):
             error = lltype.nullptr(real_restype.TO)
@@ -495,11 +496,7 @@
             error = CANNOT_FAIL
     if type(error) is int:
         error = rffi.cast(real_restype, error)
-
-    func._always_inline_ = 'try'
-    return ApiFunction(
-        argtypes, restype, func, error, c_name=c_name, gil=gil,
-        result_borrowed=result_borrowed, result_is_ll=result_is_ll)
+    return error
 
 
 def cpython_struct(name, fields, forward=None, level=1):
diff --git a/pypy/module/cpyext/cdatetime.py b/pypy/module/cpyext/cdatetime.py
--- a/pypy/module/cpyext/cdatetime.py
+++ b/pypy/module/cpyext/cdatetime.py
@@ -118,12 +118,16 @@
                     """ % (type_name,)))
         except OperationError:
             return 0
+    return check, check_exact
 
-make_check_function("PyDateTime_Check", "datetime")
-make_check_function("PyDate_Check", "date")
-make_check_function("PyTime_Check", "time")
-make_check_function("PyDelta_Check", "timedelta")
-make_check_function("PyTZInfo_Check", "tzinfo")
+PyDateTime_Check, PyDateTime_CheckExact = make_check_function(
+    "PyDateTime_Check", "datetime")
+PyDate_Check, PyDate_CheckExact = make_check_function("PyDate_Check", "date")
+PyTime_Check, PyTime_CheckExact = make_check_function("PyTime_Check", "time")
+PyDelta_Check, PyDelta_CheckExact = make_check_function(
+    "PyDelta_Check", "timedelta")
+PyTZInfo_Check, PyTZInfo_CheckExact = make_check_function(
+    "PyTZInfo_Check", "tzinfo")
 
 # Constructors. They are better used as macros.
 
diff --git a/pypy/module/cpyext/memoryobject.py 
b/pypy/module/cpyext/memoryobject.py
--- a/pypy/module/cpyext/memoryobject.py
+++ b/pypy/module/cpyext/memoryobject.py
@@ -3,7 +3,8 @@
     build_type_checkers, Py_ssize_tP, PyObjectFields, cpython_struct,
     bootstrap_function, Py_bufferP, slot_function)
 from pypy.module.cpyext.pyobject import (
-    PyObject, make_ref, as_pyobj, incref, decref, from_ref, make_typedescr)
+    PyObject, make_ref, as_pyobj, incref, decref, from_ref, make_typedescr,
+    get_typedescr, track_reference)
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rlib.rarithmetic import widen
 from pypy.objspace.std.memoryobject import W_MemoryView
@@ -28,7 +29,7 @@
                    basestruct=PyMemoryViewObject.TO,
                    attach=memory_attach,
                    dealloc=memory_dealloc,
-                   #realize=memory_realize,
+                   realize=memory_realize,
                   )
 
 def memory_attach(space, py_obj, w_obj, w_userdata=None):
@@ -54,11 +55,35 @@
                                              track_allocation=False))
         rffi.setintfield(view, 'c_readonly', 1)
 
-def memory_realize(space, py_obj):
+def memory_realize(space, obj):
     """
     Creates the memory object in the interpreter
     """
-    raise oefmt(space.w_NotImplementedError, "cannot call this yet")
+    from pypy.module.cpyext.slotdefs import CPyBuffer, fq
+    py_mem = rffi.cast(PyMemoryViewObject, obj)
+    view = py_mem.c_view
+    ndim = widen(view.c_ndim)
+    shape = None
+    if view.c_shape:
+        shape = [view.c_shape[i] for i in range(ndim)]
+    strides = None
+    if view.c_strides:
+        strides = [view.c_strides[i] for i in range(ndim)]
+    format = 'B'
+    if view.c_format:
+        format = rffi.charp2str(view.c_format)
+    buf = CPyBuffer(space, view.c_buf, view.c_len, from_ref(space, view.c_obj),
+                    format=format, shape=shape, strides=strides,
+                    ndim=ndim, itemsize=view.c_itemsize,
+                    readonly=widen(view.c_readonly))
+    # Ensure view.c_buf is released upon object finalization
+    fq.register_finalizer(buf)
+    # Allow subclassing W_MemeoryView
+    w_type = from_ref(space, rffi.cast(PyObject, obj.c_ob_type))
+    w_obj = space.allocate_instance(W_MemoryView, w_type)
+    w_obj.__init__(buf)
+    track_reference(space, obj, w_obj)
+    return w_obj
 
 @slot_function([PyObject], lltype.Void)
 def memory_dealloc(space, py_obj):
@@ -208,17 +233,41 @@
     py_memview = make_ref(space, w_memview, w_obj)
     return py_memview
 
-@cpython_api([Py_bufferP], PyObject)
+@cpython_api([Py_bufferP], PyObject, result_is_ll=True)
 def PyMemoryView_FromBuffer(space, view):
     """Create a memoryview object wrapping the given buffer-info structure 
view.
     The memoryview object then owns the buffer, which means you shouldn't
     try to release it yourself: it will be released on deallocation of the
     memoryview object."""
-    assert view.c_obj
-    w_obj = from_ref(space, view.c_obj)
-    if isinstance(w_obj, W_MemoryView):
-        return w_obj
-    return space.call_method(space.builtin, "memoryview", w_obj)
+    # XXX this should allocate a PyMemoryViewObject and
+    # copy view into obj.c_view, without creating a new view.c_obj
+    typedescr = get_typedescr(W_MemoryView.typedef)
+    py_obj = typedescr.allocate(space, space.w_memoryview)
+    py_mem = rffi.cast(PyMemoryViewObject, py_obj)
+    mview = py_mem.c_view
+    mview.c_buf = view.c_buf
+    mview.c_obj = view.c_obj
+    mview.c_len = view.c_len
+    mview.c_itemsize = view.c_itemsize
+    mview.c_readonly = view.c_readonly
+    mview.c_ndim = view.c_ndim
+    mview.c_format = view.c_format
+    if view.c_strides == rffi.cast(Py_ssize_tP, view.c__strides):
+        py_mem.c_view.c_strides = rffi.cast(Py_ssize_tP, 
py_mem.c_view.c__strides)
+        for i in range(view.c_ndim):
+            py_mem.c_view.c_strides[i] = view.c_strides[i]
+    else:
+        # some externally allocated memory chunk
+        py_mem.c_view.c_strides = view.c_strides
+    if view.c_shape == rffi.cast(Py_ssize_tP, view.c__shape):
+        py_mem.c_view.c_shape = rffi.cast(Py_ssize_tP, py_mem.c_view.c__shape)
+        for i in range(view.c_ndim):
+            py_mem.c_view.c_shape[i] = view.c_shape[i]
+    else:
+        # some externally allocated memory chunk
+        py_mem.c_view.c_shape = view.c_shape
+    # XXX ignore suboffsets?
+    return py_obj
 
 @cpython_api([PyObject], PyObject)
 def PyMemoryView_GET_BASE(space, w_obj):
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -2,6 +2,7 @@
 from pypy.module.cpyext.api import (
     cpython_api, generic_cpy_call, CANNOT_FAIL, Py_ssize_t, Py_ssize_tP,
     PyVarObject, Py_buffer, size_t, slot_function,
+    PyBUF_FORMAT, PyBUF_ND, PyBUF_STRIDES,
     Py_TPFLAGS_HEAPTYPE, Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT,
     Py_GE, CONST_STRING, CONST_STRINGP, FILEP, fwrite)
 from pypy.module.cpyext.pyobject import (
@@ -486,22 +487,28 @@
     Fills in a buffer-info structure correctly for an exporter that can only
     share a contiguous chunk of memory of "unsigned bytes" of the given
     length. Returns 0 on success and -1 (with raising an error) on error.
-
-    This is not a complete re-implementation of the CPython API; it only
-    provides a subset of CPython's behavior.
     """
     if flags & PyBUF_WRITABLE and readonly:
         raise oefmt(space.w_ValueError, "Object is not writable")
     view.c_buf = buf
     view.c_len = length
     view.c_obj = obj
-    Py_IncRef(space, obj)
+    if obj:
+        Py_IncRef(space, obj)
     view.c_itemsize = 1
     rffi.setintfield(view, 'c_readonly', readonly)
-    rffi.setintfield(view, 'c_ndim', 0)
+    rffi.setintfield(view, 'c_ndim', 1)
     view.c_format = lltype.nullptr(rffi.CCHARP.TO)
+    if (flags & PyBUF_FORMAT) == PyBUF_FORMAT:
+        view.c_format = rffi.str2charp("B")
     view.c_shape = lltype.nullptr(Py_ssize_tP.TO)
+    if (flags & PyBUF_ND) == PyBUF_ND:
+        view.c_shape = rffi.cast(Py_ssize_tP, view.c__shape)
+        view.c_shape[0] = view.c_len
     view.c_strides = lltype.nullptr(Py_ssize_tP.TO)
+    if (flags & PyBUF_STRIDES) == PyBUF_STRIDES:
+        view.c_strides = rffi.cast(Py_ssize_tP, view.c__strides)
+        view.c_strides[0] = view.c_itemsize
     view.c_suboffsets = lltype.nullptr(Py_ssize_tP.TO)
     view.c_internal = lltype.nullptr(rffi.VOIDP.TO)
 
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -324,7 +324,7 @@
 
     def __init__(self, space, ptr, size, w_obj, format='B', shape=None,
                 strides=None, ndim=1, itemsize=1, readonly=True,
-                releasebuffer=None):
+                releasebufferproc=rffi.cast(rffi.VOIDP, 0)):
         self.space = space
         self.ptr = ptr
         self.size = size
@@ -342,7 +342,7 @@
         self.ndim = ndim
         self.itemsize = itemsize
         self.readonly = readonly
-        self.releasebufferproc = releasebuffer
+        self.releasebufferproc = releasebufferproc
 
     def releasebuffer(self):
         if self.pyobj:
@@ -360,7 +360,10 @@
                 for i in range(self.ndim):
                     pybuf.c_shape[i] = self.shape[i]
                     pybuf.c_strides[i] = self.strides[i]
-                pybuf.c_format = rffi.str2charp(self.format)
+                if self.format:
+                    pybuf.c_format = rffi.str2charp(self.format)
+                else:
+                    pybuf.c_format = rffi.str2charp("B")
                 generic_cpy_call(self.space, func_target, self.pyobj, pybuf)
             self.releasebufferproc = rffi.cast(rffi.VOIDP, 0)
 
@@ -407,9 +410,9 @@
     func_target = rffi.cast(readbufferproc, func)
     py_obj = make_ref(space, w_self)
     py_type = py_obj.c_ob_type
-    releasebuffer = rffi.cast(rffi.VOIDP, 0)
+    rbp = rffi.cast(rffi.VOIDP, 0)
     if py_type.c_tp_as_buffer:
-        releasebuffer = rffi.cast(rffi.VOIDP, 
py_type.c_tp_as_buffer.c_bf_releasebuffer)
+        rbp = rffi.cast(rffi.VOIDP, py_type.c_tp_as_buffer.c_bf_releasebuffer)
     decref(space, py_obj)
     with lltype.scoped_alloc(rffi.VOIDPP.TO, 1) as ptr:
         index = rffi.cast(Py_ssize_t, 0)
@@ -417,7 +420,7 @@
         if size < 0:
             space.fromcache(State).check_and_raise_exception(always=True)
         buf = CPyBuffer(space, ptr[0], size, w_self,
-                               releasebuffer=releasebuffer)
+                               releasebufferproc=rbp)
         fq.register_finalizer(buf)
         return space.newbuffer(buf)
 
@@ -426,16 +429,16 @@
     py_obj = make_ref(space, w_self)
     py_type = py_obj.c_ob_type
     decref(space, py_obj)
-    releasebuffer = rffi.cast(rffi.VOIDP, 0)
+    rbp = rffi.cast(rffi.VOIDP, 0)
     if py_type.c_tp_as_buffer:
-        releasebuffer = rffi.cast(rffi.VOIDP, 
py_type.c_tp_as_buffer.c_bf_releasebuffer)
+        rbp = rffi.cast(rffi.VOIDP, py_type.c_tp_as_buffer.c_bf_releasebuffer)
     with lltype.scoped_alloc(rffi.VOIDPP.TO, 1) as ptr:
         index = rffi.cast(Py_ssize_t, 0)
         size = generic_cpy_call(space, func_target, w_self, index, ptr)
         if size < 0:
             space.fromcache(State).check_and_raise_exception(always=True)
         buf = CPyBuffer(space, ptr[0], size, w_self, readonly=False,
-                               releasebuffer=releasebuffer)
+                               releasebufferproc=rbp)
         fq.register_finalizer(buf)
         return space.newbuffer(buf)
 
@@ -443,9 +446,9 @@
     func_target = rffi.cast(getbufferproc, func)
     py_obj = make_ref(space, w_self)
     py_type = py_obj.c_ob_type
-    releasebuffer = rffi.cast(rffi.VOIDP, 0)
+    rbp = rffi.cast(rffi.VOIDP, 0)
     if py_type.c_tp_as_buffer:
-        releasebuffer = rffi.cast(rffi.VOIDP, 
py_type.c_tp_as_buffer.c_bf_releasebuffer)
+        rbp = rffi.cast(rffi.VOIDP, py_type.c_tp_as_buffer.c_bf_releasebuffer)
     decref(space, py_obj)
     with lltype.scoped_alloc(Py_buffer) as pybuf:
         _flags = 0
@@ -471,7 +474,7 @@
                             ndim=ndim, shape=shape, strides=strides,
                             itemsize=pybuf.c_itemsize,
                             readonly=widen(pybuf.c_readonly),
-                            releasebuffer = releasebuffer)
+                            releasebufferproc = rbp)
         fq.register_finalizer(buf)
         return space.newbuffer(buf)
 
diff --git a/pypy/module/cpyext/test/test_api.py 
b/pypy/module/cpyext/test/test_api.py
--- a/pypy/module/cpyext/test/test_api.py
+++ b/pypy/module/cpyext/test/test_api.py
@@ -1,20 +1,22 @@
 import py, pytest
+import contextlib
 from rpython.rtyper.lltypesystem import lltype
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.module.cpyext.state import State
-from pypy.module.cpyext import api
+from pypy.module.cpyext.api import (
+    slot_function, cpython_api, copy_header_files, INTERPLEVEL_API,
+    Py_ssize_t, Py_ssize_tP, PyObject)
 from pypy.module.cpyext.test.test_cpyext import freeze_refcnts, 
LeakCheckingTest
-PyObject = api.PyObject
 from pypy.interpreter.error import OperationError
 from rpython.rlib import rawrefcount
 import os
 
[email protected]_api([PyObject], lltype.Void)
-def PyPy_GetWrapped(space, w_arg):
-    assert isinstance(w_arg, W_Root)
[email protected]_api([PyObject], lltype.Void)
-def PyPy_GetReference(space, arg):
-    assert lltype.typeOf(arg) ==  PyObject
[email protected]
+def raises_w(space, expected_exc):
+    with pytest.raises(OperationError) as excinfo:
+        yield
+    operror = excinfo.value
+    assert operror.w_type is getattr(space, 'w_' + expected_exc.__name__)
 
 class BaseApiTest(LeakCheckingTest):
     def setup_class(cls):
@@ -35,7 +37,7 @@
             def __getattr__(self, name):
                 return getattr(cls.space, name)
         cls.api = CAPI()
-        CAPI.__dict__.update(api.INTERPLEVEL_API)
+        CAPI.__dict__.update(INTERPLEVEL_API)
 
         print 'DONT_FREE_ANY_MORE'
         rawrefcount._dont_free_any_more()
@@ -71,20 +73,28 @@
         if self.check_and_print_leaks():
             assert False, "Test leaks or loses object(s)."
 
[email protected]_api([api.Py_ssize_t], api.Py_ssize_t, error=-1)
+@slot_function([PyObject], lltype.Void)
+def PyPy_GetWrapped(space, w_arg):
+    assert isinstance(w_arg, W_Root)
+
+@slot_function([PyObject], lltype.Void)
+def PyPy_GetReference(space, arg):
+    assert lltype.typeOf(arg) ==  PyObject
+
+@cpython_api([Py_ssize_t], Py_ssize_t, error=-1)
 def PyPy_TypedefTest1(space, arg):
-    assert lltype.typeOf(arg) == api.Py_ssize_t
+    assert lltype.typeOf(arg) == Py_ssize_t
     return 0
 
[email protected]_api([api.Py_ssize_tP], api.Py_ssize_tP)
+@cpython_api([Py_ssize_tP], Py_ssize_tP)
 def PyPy_TypedefTest2(space, arg):
-    assert lltype.typeOf(arg) == api.Py_ssize_tP
+    assert lltype.typeOf(arg) == Py_ssize_tP
     return None
 
 class TestConversion(BaseApiTest):
-    def test_conversions(self, space, api):
-        api.PyPy_GetWrapped(space.w_None)
-        api.PyPy_GetReference(space.w_None)
+    def test_conversions(self, space):
+        PyPy_GetWrapped(space, space.w_None)
+        PyPy_GetReference(space, space.w_None)
 
     def test_typedef(self, space):
         from rpython.translator.c.database import LowLevelDatabase
@@ -95,7 +105,7 @@
         assert PyPy_TypedefTest2.api_func.get_c_args(db) == 'Signed *arg0'
 
         PyPy_TypedefTest1(space, 0)
-        ppos = lltype.malloc(api.Py_ssize_tP.TO, 1, flavor='raw')
+        ppos = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
         ppos[0] = 0
         PyPy_TypedefTest2(space, ppos)
         lltype.free(ppos, flavor='raw')
@@ -103,7 +113,7 @@
 @pytest.mark.skipif(os.environ.get('USER')=='root',
                     reason='root can write to all files')
 def test_copy_header_files(tmpdir):
-    api.copy_header_files(tmpdir, True)
+    copy_header_files(tmpdir, True)
     def check(name):
         f = tmpdir.join(name)
         assert f.check(file=True)
diff --git a/pypy/module/cpyext/test/test_boolobject.py 
b/pypy/module/cpyext/test/test_boolobject.py
--- a/pypy/module/cpyext/test/test_boolobject.py
+++ b/pypy/module/cpyext/test/test_boolobject.py
@@ -1,20 +1,22 @@
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.boolobject import PyBool_Check, PyBool_FromLong
+from pypy.module.cpyext.floatobject import PyFloat_FromDouble
 
 class TestBoolObject(BaseApiTest):
-    def test_fromlong(self, space, api):
+    def test_fromlong(self, space):
         for i in range(-3, 3):
-            obj = api.PyBool_FromLong(i)
+            obj = PyBool_FromLong(space, i)
             if i:
                 assert obj is space.w_True
             else:
                 assert obj is space.w_False
 
-    def test_check(self, space, api):
-        assert api.PyBool_Check(space.w_True)
-        assert api.PyBool_Check(space.w_False)
-        assert not api.PyBool_Check(space.w_None)
-        assert not api.PyBool_Check(api.PyFloat_FromDouble(1.0))
+    def test_check(self, space):
+        assert PyBool_Check(space, space.w_True)
+        assert PyBool_Check(space, space.w_False)
+        assert not PyBool_Check(space, space.w_None)
+        assert not PyBool_Check(space, PyFloat_FromDouble(space, 1.0))
 
 class AppTestBoolMacros(AppTestCpythonExtensionBase):
     def test_macros(self):
diff --git a/pypy/module/cpyext/test/test_bytesobject.py 
b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -1,14 +1,19 @@
 # encoding: utf-8
+import pytest
 from rpython.rtyper.lltypesystem import rffi, lltype
-from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.interpreter.error import OperationError
+from pypy.module.cpyext.test.test_api import BaseApiTest, raises_w
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
-from pypy.module.cpyext.bytesobject import new_empty_str, PyBytesObject
+from pypy.module.cpyext.bytesobject import (
+    new_empty_str, PyBytesObject, _PyString_Resize, PyString_Concat,
+    PyString_ConcatAndDel, PyString_Format, PyString_InternFromString,
+    PyString_AsEncodedObject, PyString_AsDecodedObject, _PyString_Eq,
+    _PyString_Join)
 from pypy.module.cpyext.api import PyObjectP, PyObject, Py_ssize_tP, 
generic_cpy_call
 from pypy.module.cpyext.pyobject import Py_DecRef, from_ref, make_ref
+from pypy.module.cpyext.object import PyObject_AsCharBuffer
 from pypy.module.cpyext.api import PyTypeObjectPtr
 
-import py
-import sys
 
 class AppTestBytesObject(AppTestCpythonExtensionBase):
     def test_bytesobject(self):
@@ -441,21 +446,21 @@
         assert a == 'abc'
 
 class TestBytes(BaseApiTest):
-    def test_bytes_resize(self, space, api):
+    def test_bytes_resize(self, space):
         py_str = new_empty_str(space, 10)
         ar = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
         py_str.c_ob_sval[0] = 'a'
         py_str.c_ob_sval[1] = 'b'
         py_str.c_ob_sval[2] = 'c'
         ar[0] = rffi.cast(PyObject, py_str)
-        api._PyString_Resize(ar, 3)
+        _PyString_Resize(space, ar, 3)
         py_str = rffi.cast(PyBytesObject, ar[0])
         assert py_str.c_ob_size == 3
         assert py_str.c_ob_sval[1] == 'b'
         assert py_str.c_ob_sval[3] == '\x00'
         # the same for growing
         ar[0] = rffi.cast(PyObject, py_str)
-        api._PyString_Resize(ar, 10)
+        _PyString_Resize(space, ar, 10)
         py_str = rffi.cast(PyBytesObject, ar[0])
         assert py_str.c_ob_size == 10
         assert py_str.c_ob_sval[1] == 'b'
@@ -463,7 +468,7 @@
         Py_DecRef(space, ar[0])
         lltype.free(ar, flavor='raw')
 
-    def test_string_buffer(self, space, api):
+    def test_string_buffer(self, space):
         py_str = new_empty_str(space, 10)
         c_buf = py_str.c_ob_type.c_tp_as_buffer
         assert c_buf
@@ -481,108 +486,106 @@
         lltype.free(ref, flavor='raw')
         Py_DecRef(space, py_obj)
 
-    def test_Concat(self, space, api):
+    def test_Concat(self, space):
         ref = make_ref(space, space.wrap('abc'))
         ptr = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
         ptr[0] = ref
         prev_refcnt = ref.c_ob_refcnt
-        api.PyString_Concat(ptr, space.wrap('def'))
+        PyString_Concat(space, ptr, space.wrap('def'))
         assert ref.c_ob_refcnt == prev_refcnt - 1
         assert space.str_w(from_ref(space, ptr[0])) == 'abcdef'
-        api.PyString_Concat(ptr, space.w_None)
+        with pytest.raises(OperationError):
+            PyString_Concat(space, ptr, space.w_None)
         assert not ptr[0]
-        api.PyErr_Clear()
         ptr[0] = lltype.nullptr(PyObject.TO)
-        api.PyString_Concat(ptr, space.wrap('def')) # should not crash
+        PyString_Concat(space, ptr, space.wrap('def')) # should not crash
         lltype.free(ptr, flavor='raw')
 
-    def test_ConcatAndDel(self, space, api):
+    def test_ConcatAndDel(self, space):
         ref1 = make_ref(space, space.wrap('abc'))
         ref2 = make_ref(space, space.wrap('def'))
         ptr = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
         ptr[0] = ref1
         prev_refcnf = ref2.c_ob_refcnt
-        api.PyString_ConcatAndDel(ptr, ref2)
+        PyString_ConcatAndDel(space, ptr, ref2)
         assert space.str_w(from_ref(space, ptr[0])) == 'abcdef'
         assert ref2.c_ob_refcnt == prev_refcnf - 1
         Py_DecRef(space, ptr[0])
         ptr[0] = lltype.nullptr(PyObject.TO)
         ref2 = make_ref(space, space.wrap('foo'))
         prev_refcnf = ref2.c_ob_refcnt
-        api.PyString_ConcatAndDel(ptr, ref2) # should not crash
+        PyString_ConcatAndDel(space, ptr, ref2) # should not crash
         assert ref2.c_ob_refcnt == prev_refcnf - 1
         lltype.free(ptr, flavor='raw')
 
-    def test_format(self, space, api):
+    def test_format(self, space):
         assert "1 2" == space.unwrap(
-            api.PyString_Format(space.wrap('%s %d'), space.wrap((1, 2))))
+            PyString_Format(space, space.wrap('%s %d'), space.wrap((1, 2))))
 
-    def test_asbuffer(self, space, api):
+    def test_asbuffer(self, space):
         bufp = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
         lenp = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
 
         w_text = space.wrap("text")
         ref = make_ref(space, w_text)
         prev_refcnt = ref.c_ob_refcnt
-        assert api.PyObject_AsCharBuffer(ref, bufp, lenp) == 0
+        assert PyObject_AsCharBuffer(space, ref, bufp, lenp) == 0
         assert ref.c_ob_refcnt == prev_refcnt
         assert lenp[0] == 4
         assert rffi.charp2str(bufp[0]) == 'text'
         lltype.free(bufp, flavor='raw')
         lltype.free(lenp, flavor='raw')
-        api.Py_DecRef(ref)
+        Py_DecRef(space, ref)
 
-    def test_intern(self, space, api):
+    def test_intern(self, space):
         buf = rffi.str2charp("test")
-        w_s1 = api.PyString_InternFromString(buf)
-        w_s2 = api.PyString_InternFromString(buf)
+        w_s1 = PyString_InternFromString(space, buf)
+        w_s2 = PyString_InternFromString(space, buf)
         rffi.free_charp(buf)
         assert w_s1 is w_s2
 
-    def test_AsEncodedObject(self, space, api):
+    def test_AsEncodedObject(self, space):
         ptr = space.wrap('abc')
 
         errors = rffi.str2charp("strict")
 
         encoding = rffi.str2charp("hex")
-        res = api.PyString_AsEncodedObject(
-            ptr, encoding, errors)
+        res = PyString_AsEncodedObject(space, ptr, encoding, errors)
         assert space.unwrap(res) == "616263"
 
-        res = api.PyString_AsEncodedObject(
+        res = PyString_AsEncodedObject(space,
             ptr, encoding, lltype.nullptr(rffi.CCHARP.TO))
         assert space.unwrap(res) == "616263"
         rffi.free_charp(encoding)
 
         encoding = rffi.str2charp("unknown_encoding")
-        self.raises(space, api, LookupError, api.PyString_AsEncodedObject,
-                    ptr, encoding, errors)
+        with raises_w(space, LookupError):
+            PyString_AsEncodedObject(space, ptr, encoding, errors)
         rffi.free_charp(encoding)
 
         rffi.free_charp(errors)
 
-        res = api.PyString_AsEncodedObject(
-            ptr, lltype.nullptr(rffi.CCHARP.TO), 
lltype.nullptr(rffi.CCHARP.TO))
+        NULL = lltype.nullptr(rffi.CCHARP.TO)
+        res = PyString_AsEncodedObject(space, ptr, NULL, NULL)
         assert space.unwrap(res) == "abc"
+        with raises_w(space, TypeError):
+            PyString_AsEncodedObject(space, space.wrap(2), NULL, NULL)
 
-        self.raises(space, api, TypeError, api.PyString_AsEncodedObject,
-            space.wrap(2), lltype.nullptr(rffi.CCHARP.TO), 
lltype.nullptr(rffi.CCHARP.TO)
-        )
-
-    def test_AsDecodedObject(self, space, api):
+    def test_AsDecodedObject(self, space):
         w_str = space.wrap('caf\xe9')
         encoding = rffi.str2charp("latin-1")
-        w_res = api.PyString_AsDecodedObject(w_str, encoding, None)
+        w_res = PyString_AsDecodedObject(space, w_str, encoding, None)
         rffi.free_charp(encoding)
         assert space.unwrap(w_res) == u"caf\xe9"
 
-    def test_eq(self, space, api):
-        assert 1 == api._PyString_Eq(space.wrap("hello"), space.wrap("hello"))
-        assert 0 == api._PyString_Eq(space.wrap("hello"), space.wrap("world"))
+    def test_eq(self, space):
+        assert 1 == _PyString_Eq(
+            space, space.wrap("hello"), space.wrap("hello"))
+        assert 0 == _PyString_Eq(
+            space, space.wrap("hello"), space.wrap("world"))
 
-    def test_join(self, space, api):
+    def test_join(self, space):
         w_sep = space.wrap('<sep>')
         w_seq = space.wrap(['a', 'b'])
-        w_joined = api._PyString_Join(w_sep, w_seq)
+        w_joined = _PyString_Join(space, w_sep, w_seq)
         assert space.unwrap(w_joined) == 'a<sep>b'
-
diff --git a/pypy/module/cpyext/test/test_classobject.py 
b/pypy/module/cpyext/test/test_classobject.py
--- a/pypy/module/cpyext/test/test_classobject.py
+++ b/pypy/module/cpyext/test/test_classobject.py
@@ -1,9 +1,13 @@
+from pypy.interpreter.function import Function
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
-from pypy.interpreter.function import Function, Method
+from pypy.module.cpyext.classobject import (
+    PyClass_Check, PyClass_New, PyInstance_Check, PyInstance_New,
+    PyInstance_NewRaw, _PyInstance_Lookup)
+from pypy.module.cpyext.object import PyObject_GetAttr
 
 class TestClassObject(BaseApiTest):
-    def test_newinstance(self, space, api):
+    def test_newinstance(self, space):
         w_class = space.appexec([], """():
             class C:
                 x = None
@@ -14,23 +18,23 @@
             return C
         """)
 
-        assert api.PyClass_Check(w_class)
+        assert PyClass_Check(space, w_class)
 
-        w_instance = api.PyInstance_NewRaw(w_class, None)
-        assert api.PyInstance_Check(w_instance)
+        w_instance = PyInstance_NewRaw(space, w_class, None)
+        assert PyInstance_Check(space, w_instance)
         assert space.getattr(w_instance, space.wrap('x')) is space.w_None
 
-        w_instance = api.PyInstance_NewRaw(w_class, space.wrap(dict(a=3)))
+        w_instance = PyInstance_NewRaw(space, w_class, space.wrap(dict(a=3)))
         assert space.getattr(w_instance, space.wrap('x')) is space.w_None
         assert space.unwrap(space.getattr(w_instance, space.wrap('a'))) == 3
 
-        w_instance = api.PyInstance_New(w_class,
+        w_instance = PyInstance_New(space, w_class,
                                         space.wrap((3,)), 
space.wrap(dict(y=2)))
         assert space.unwrap(space.getattr(w_instance, space.wrap('x'))) == 1
         assert space.unwrap(space.getattr(w_instance, space.wrap('y'))) == 2
         assert space.unwrap(space.getattr(w_instance, space.wrap('args'))) == 
(3,)
 
-    def test_lookup(self, space, api):
+    def test_lookup(self, space):
         w_instance = space.appexec([], """():
             class C:
                 def __init__(self):
@@ -39,25 +43,26 @@
             return C()
         """)
 
-        assert api.PyInstance_Check(w_instance)
-        assert api.PyObject_GetAttr(w_instance, space.wrap('x')) is 
space.w_None
-        assert api._PyInstance_Lookup(w_instance, space.wrap('x')) is 
space.w_None
-        assert api._PyInstance_Lookup(w_instance, space.wrap('y')) is None
-        assert not api.PyErr_Occurred()
+        assert PyInstance_Check(space, w_instance)
+        assert PyObject_GetAttr(space, w_instance, space.wrap('x')) is 
space.w_None
+        assert _PyInstance_Lookup(space, w_instance, space.wrap('x')) is 
space.w_None
+        assert _PyInstance_Lookup(space, w_instance, space.wrap('y')) is None
 
         # getattr returns a bound method
-        assert not isinstance(api.PyObject_GetAttr(w_instance, 
space.wrap('f')), Function)
+        assert not isinstance(
+            PyObject_GetAttr(space, w_instance, space.wrap('f')), Function)
         # _PyInstance_Lookup returns the raw descriptor
-        assert isinstance(api._PyInstance_Lookup(w_instance, space.wrap('f')), 
Function)
+        assert isinstance(
+            _PyInstance_Lookup(space, w_instance, space.wrap('f')), Function)
 
-    def test_pyclass_new(self, space, api):
+    def test_pyclass_new(self, space):
         w_bases = space.newtuple([])
         w_dict = space.newdict()
         w_name = space.wrap("C")
-        w_class = api.PyClass_New(w_bases, w_dict, w_name)
+        w_class = PyClass_New(space, w_bases, w_dict, w_name)
         assert not space.isinstance_w(w_class, space.w_type)
         w_instance = space.call_function(w_class)
-        assert api.PyInstance_Check(w_instance)
+        assert PyInstance_Check(space, w_instance)
         assert space.is_true(space.call_method(space.builtin, "isinstance",
                                                w_instance, w_class))
 
@@ -69,5 +74,6 @@
                  Py_INCREF(&PyClass_Type);
                  return (PyObject*)&PyClass_Type;
              """)])
-        class C: pass
+        class C:
+            pass
         assert module.get_classtype() is type(C)
diff --git a/pypy/module/cpyext/test/test_codecs.py 
b/pypy/module/cpyext/test/test_codecs.py
--- a/pypy/module/cpyext/test/test_codecs.py
+++ b/pypy/module/cpyext/test/test_codecs.py
@@ -1,14 +1,15 @@
 # encoding: iso-8859-15
 from pypy.module.cpyext.test.test_api import BaseApiTest
-from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rtyper.lltypesystem import rffi
+from pypy.module.cpyext.codecs import (
+    PyCodec_IncrementalEncoder, PyCodec_IncrementalDecoder)
 
 class TestCodecs(BaseApiTest):
-    def test_incremental(self, space, api):
+    def test_incremental(self, space):
         utf8 = rffi.str2charp('utf-8')
-        w_encoder = api.PyCodec_IncrementalEncoder(utf8, None)
+        w_encoder = PyCodec_IncrementalEncoder(space, utf8, None)
         w_encoded = space.call_method(w_encoder, 'encode', 
space.wrap(u'sp&#228;m'))
-        w_decoder = api.PyCodec_IncrementalDecoder(utf8, None)
+        w_decoder = PyCodec_IncrementalDecoder(space, utf8, None)
         w_decoded = space.call_method(w_decoder, 'decode', w_encoded)
         assert space.unwrap(w_decoded) == u'sp&#228;m'
         rffi.free_charp(utf8)
-
diff --git a/pypy/module/cpyext/test/test_complexobject.py 
b/pypy/module/cpyext/test/test_complexobject.py
--- a/pypy/module/cpyext/test/test_complexobject.py
+++ b/pypy/module/cpyext/test/test_complexobject.py
@@ -1,23 +1,23 @@
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
-from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.test.test_api import BaseApiTest, raises_w
+from pypy.module.cpyext.complexobject import (
+    PyComplex_FromDoubles, PyComplex_RealAsDouble, PyComplex_ImagAsDouble)
 
 class TestComplexObject(BaseApiTest):
-    def test_complexobject(self, space, api):
-        w_value = api.PyComplex_FromDoubles(1.2, 3.4)
+    def test_complexobject(self, space):
+        w_value = PyComplex_FromDoubles(space, 1.2, 3.4)
         assert space.unwrap(w_value) == 1.2+3.4j
-        assert api.PyComplex_RealAsDouble(w_value) == 1.2
-        assert api.PyComplex_ImagAsDouble(w_value) == 3.4
+        assert PyComplex_RealAsDouble(space, w_value) == 1.2
+        assert PyComplex_ImagAsDouble(space, w_value) == 3.4
 
-        assert api.PyComplex_RealAsDouble(space.wrap(42)) == 42
-        assert api.PyComplex_RealAsDouble(space.wrap(1.5)) == 1.5
-        assert api.PyComplex_ImagAsDouble(space.wrap(1.5)) == 0.0
+        assert PyComplex_RealAsDouble(space, space.wrap(42)) == 42
+        assert PyComplex_RealAsDouble(space, space.wrap(1.5)) == 1.5
+        assert PyComplex_ImagAsDouble(space, space.wrap(1.5)) == 0.0
 
         # cpython accepts anything for PyComplex_ImagAsDouble
-        assert api.PyComplex_ImagAsDouble(space.w_None) == 0.0
-        assert not api.PyErr_Occurred()
-        assert api.PyComplex_RealAsDouble(space.w_None) == -1.0
-        assert api.PyErr_Occurred()
-        api.PyErr_Clear()
+        assert PyComplex_ImagAsDouble(space, space.w_None) == 0.0
+        with raises_w(space, TypeError):
+            PyComplex_RealAsDouble(space, space.w_None)
 
 class AppTestCComplex(AppTestCpythonExtensionBase):
     def test_AsCComplex(self):
diff --git a/pypy/module/cpyext/test/test_datetime.py 
b/pypy/module/cpyext/test/test_datetime.py
--- a/pypy/module/cpyext/test/test_datetime.py
+++ b/pypy/module/cpyext/test/test_datetime.py
@@ -1,92 +1,96 @@
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.cdatetime import *
+from pypy.module.cpyext.cdatetime import (
+    _PyDateTime_Import, _PyDateTime_FromDateAndTime, _PyDate_FromDate,
+    _PyTime_FromTime, _PyDelta_FromDelta)
 import datetime
 
 class TestDatetime(BaseApiTest):
-    def test_date(self, space, api):
-        date_api = api._PyDateTime_Import()
-        w_date = api._PyDate_FromDate(2010, 06, 03, date_api.c_DateType)
+    def test_date(self, space):
+        date_api = _PyDateTime_Import(space)
+        w_date = _PyDate_FromDate(space, 2010, 06, 03, date_api.c_DateType)
         assert space.unwrap(space.str(w_date)) == '2010-06-03'
 
-        assert api.PyDate_Check(w_date)
-        assert api.PyDate_CheckExact(w_date)
+        assert PyDate_Check(space, w_date)
+        assert PyDate_CheckExact(space, w_date)
 
-        assert api.PyDateTime_GET_YEAR(w_date) == 2010
-        assert api.PyDateTime_GET_MONTH(w_date) == 6
-        assert api.PyDateTime_GET_DAY(w_date) == 3
+        assert PyDateTime_GET_YEAR(space, w_date) == 2010
+        assert PyDateTime_GET_MONTH(space, w_date) == 6
+        assert PyDateTime_GET_DAY(space, w_date) == 3
 
-    def test_time(self, space, api):
-        date_api = api._PyDateTime_Import()
-        w_time = api._PyTime_FromTime(23, 15, 40, 123456,
-                                      space.w_None, date_api.c_TimeType)
+    def test_time(self, space):
+        date_api = _PyDateTime_Import(space)
+        w_time = _PyTime_FromTime(
+            space, 23, 15, 40, 123456, space.w_None, date_api.c_TimeType)
         assert space.unwrap(space.str(w_time)) == '23:15:40.123456'
 
-        assert api.PyTime_Check(w_time)
-        assert api.PyTime_CheckExact(w_time)
+        assert PyTime_Check(space, w_time)
+        assert PyTime_CheckExact(space, w_time)
 
-        assert api.PyDateTime_TIME_GET_HOUR(w_time) == 23
-        assert api.PyDateTime_TIME_GET_MINUTE(w_time) == 15
-        assert api.PyDateTime_TIME_GET_SECOND(w_time) == 40
-        assert api.PyDateTime_TIME_GET_MICROSECOND(w_time) == 123456
+        assert PyDateTime_TIME_GET_HOUR(space, w_time) == 23
+        assert PyDateTime_TIME_GET_MINUTE(space, w_time) == 15
+        assert PyDateTime_TIME_GET_SECOND(space, w_time) == 40
+        assert PyDateTime_TIME_GET_MICROSECOND(space, w_time) == 123456
 
-    def test_datetime(self, space, api):
-        date_api = api._PyDateTime_Import()
-        w_date = api._PyDateTime_FromDateAndTime(
-            2010, 06, 03, 23, 15, 40, 123456,
-            space.w_None, date_api.c_DateTimeType)
+    def test_datetime(self, space):
+        date_api = _PyDateTime_Import(space)
+        w_date = _PyDateTime_FromDateAndTime(
+            space, 2010, 06, 03, 23, 15, 40, 123456, space.w_None,
+            date_api.c_DateTimeType)
         assert space.unwrap(space.str(w_date)) == '2010-06-03 23:15:40.123456'
 
-        assert api.PyDateTime_Check(w_date)
-        assert api.PyDateTime_CheckExact(w_date)
-        assert api.PyDate_Check(w_date)
-        assert not api.PyDate_CheckExact(w_date)
+        assert PyDateTime_Check(space, w_date)
+        assert PyDateTime_CheckExact(space, w_date)
+        assert PyDate_Check(space, w_date)
+        assert not PyDate_CheckExact(space, w_date)
 
-        assert api.PyDateTime_GET_YEAR(w_date) == 2010
-        assert api.PyDateTime_GET_MONTH(w_date) == 6
-        assert api.PyDateTime_GET_DAY(w_date) == 3
-        assert api.PyDateTime_DATE_GET_HOUR(w_date) == 23
-        assert api.PyDateTime_DATE_GET_MINUTE(w_date) == 15
-        assert api.PyDateTime_DATE_GET_SECOND(w_date) == 40
-        assert api.PyDateTime_DATE_GET_MICROSECOND(w_date) == 123456
+        assert PyDateTime_GET_YEAR(space, w_date) == 2010
+        assert PyDateTime_GET_MONTH(space, w_date) == 6
+        assert PyDateTime_GET_DAY(space, w_date) == 3
+        assert PyDateTime_DATE_GET_HOUR(space, w_date) == 23
+        assert PyDateTime_DATE_GET_MINUTE(space, w_date) == 15
+        assert PyDateTime_DATE_GET_SECOND(space, w_date) == 40
+        assert PyDateTime_DATE_GET_MICROSECOND(space, w_date) == 123456
 
-    def test_delta(self, space, api):
-        date_api = api._PyDateTime_Import()
+    def test_delta(self, space):
+        date_api = _PyDateTime_Import(space)
         w_delta = space.appexec(
             [space.wrap(3), space.wrap(15)], """(days, seconds):
             from datetime import timedelta
             return timedelta(days, seconds)
         """)
-        assert api.PyDelta_Check(w_delta)
-        assert api.PyDelta_CheckExact(w_delta)
+        assert PyDelta_Check(space, w_delta)
+        assert PyDelta_CheckExact(space, w_delta)
 
-        w_delta = api._PyDelta_FromDelta(10, 20, 30, True, 
date_api.c_DeltaType)
-        assert api.PyDelta_Check(w_delta)
-        assert api.PyDelta_CheckExact(w_delta)
+        w_delta = _PyDelta_FromDelta(space, 10, 20, 30, True, 
date_api.c_DeltaType)
+        assert PyDelta_Check(space, w_delta)
+        assert PyDelta_CheckExact(space, w_delta)
 
-        assert api.PyDateTime_DELTA_GET_DAYS(w_delta) == 10
-        assert api.PyDateTime_DELTA_GET_SECONDS(w_delta) == 20
-        assert api.PyDateTime_DELTA_GET_MICROSECONDS(w_delta) == 30
+        assert PyDateTime_DELTA_GET_DAYS(space, w_delta) == 10
+        assert PyDateTime_DELTA_GET_SECONDS(space, w_delta) == 20
+        assert PyDateTime_DELTA_GET_MICROSECONDS(space, w_delta) == 30
 
-    def test_fromtimestamp(self, space, api):
+    def test_fromtimestamp(self, space):
         w_args = space.wrap((0,))
-        w_date = api.PyDate_FromTimestamp(w_args)
+        w_date = PyDate_FromTimestamp(space, w_args)
         date = datetime.date.fromtimestamp(0)
         assert space.unwrap(space.str(w_date)) == str(date)
 
         w_args = space.wrap((0,))
-        w_date = api.PyDateTime_FromTimestamp(w_args)
+        w_date = PyDateTime_FromTimestamp(space, w_args)
         date = datetime.datetime.fromtimestamp(0)
         assert space.unwrap(space.str(w_date)) == str(date)
 
-    def test_tzinfo(self, space, api):
+    def test_tzinfo(self, space):
         w_tzinfo = space.appexec(
             [], """():
             from datetime import tzinfo
             return tzinfo()
         """)
-        assert api.PyTZInfo_Check(w_tzinfo)
-        assert api.PyTZInfo_CheckExact(w_tzinfo)
-        assert not api.PyTZInfo_Check(space.w_None)
+        assert PyTZInfo_Check(space, w_tzinfo)
+        assert PyTZInfo_CheckExact(space, w_tzinfo)
+        assert not PyTZInfo_Check(space, space.w_None)
 
 class AppTestDatetime(AppTestCpythonExtensionBase):
     def test_CAPI(self):
diff --git a/pypy/module/cpyext/test/test_dictobject.py 
b/pypy/module/cpyext/test/test_dictobject.py
--- a/pypy/module/cpyext/test/test_dictobject.py
+++ b/pypy/module/cpyext/test/test_dictobject.py
@@ -1,83 +1,81 @@
 import py
 from rpython.rtyper.lltypesystem import rffi, lltype
-from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.test.test_api import BaseApiTest, raises_w
 from pypy.module.cpyext.api import Py_ssize_tP, PyObjectP, PyTypeObjectPtr
 from pypy.module.cpyext.pyobject import make_ref, from_ref
 from pypy.interpreter.error import OperationError
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+from pypy.module.cpyext.dictobject import *
+from pypy.module.cpyext.pyobject import decref
 
 class TestDictObject(BaseApiTest):
-    def test_dict(self, space, api):
-        d = api.PyDict_New()
+    def test_dict(self, space):
+        d = PyDict_New(space)
         assert space.eq_w(d, space.newdict())
 
-        assert space.eq_w(api.PyDict_GetItem(space.wrap({"a": 72}),
+        assert space.eq_w(PyDict_GetItem(space, space.wrap({"a": 72}),
                                              space.wrap("a")),
                           space.wrap(72))
 
-        assert api.PyDict_SetItem(d, space.wrap("c"), space.wrap(42)) >= 0
+        PyDict_SetItem(space, d, space.wrap("c"), space.wrap(42))
         assert space.eq_w(space.getitem(d, space.wrap("c")),
                           space.wrap(42))
 
         space.setitem(d, space.wrap("name"), space.wrap(3))
-        assert space.eq_w(api.PyDict_GetItem(d, space.wrap("name")),
+        assert space.eq_w(PyDict_GetItem(space, d, space.wrap("name")),
                           space.wrap(3))
 
         space.delitem(d, space.wrap("name"))
-        assert not api.PyDict_GetItem(d, space.wrap("name"))
-        assert not api.PyErr_Occurred()
+        assert not PyDict_GetItem(space, d, space.wrap("name"))
 
         buf = rffi.str2charp("name")
-        assert not api.PyDict_GetItemString(d, buf)
+        assert not PyDict_GetItemString(space, d, buf)
         rffi.free_charp(buf)
-        assert not api.PyErr_Occurred()
 
-        assert api.PyDict_Contains(d, space.wrap("c"))
-        assert not api.PyDict_Contains(d, space.wrap("z"))
+        assert PyDict_Contains(space, d, space.wrap("c"))
+        assert not PyDict_Contains(space, d, space.wrap("z"))
 
-        assert api.PyDict_DelItem(d, space.wrap("c")) == 0
-        assert api.PyDict_DelItem(d, space.wrap("name")) < 0
-        assert api.PyErr_Occurred() is space.w_KeyError
-        api.PyErr_Clear()
-        assert api.PyDict_Size(d) == 0
+        PyDict_DelItem(space, d, space.wrap("c"))
+        with raises_w(space, KeyError):
+            PyDict_DelItem(space, d, space.wrap("name"))
+        assert PyDict_Size(space, d) == 0
 
         space.setitem(d, space.wrap("some_key"), space.wrap(3))
         buf = rffi.str2charp("some_key")
-        assert api.PyDict_DelItemString(d, buf) == 0
-        assert api.PyDict_Size(d) == 0
-        assert api.PyDict_DelItemString(d, buf) < 0
-        assert api.PyErr_Occurred() is space.w_KeyError
-        api.PyErr_Clear()
+        PyDict_DelItemString(space, d, buf)
+        assert PyDict_Size(space, d) == 0
+        with raises_w(space, KeyError):
+            PyDict_DelItemString(space, d, buf)
         rffi.free_charp(buf)
 
         d = space.wrap({'a': 'b'})
-        api.PyDict_Clear(d)
-        assert api.PyDict_Size(d) == 0
+        PyDict_Clear(space, d)
+        assert PyDict_Size(space, d) == 0
 
-    def test_check(self, space, api):
-        d = api.PyDict_New()
-        assert api.PyDict_Check(d)
-        assert api.PyDict_CheckExact(d)
+    def test_check(self, space):
+        d = PyDict_New(space, )
+        assert PyDict_Check(space, d)
+        assert PyDict_CheckExact(space, d)
         sub = space.appexec([], """():
             class D(dict):
                 pass
             return D""")
         d = space.call_function(sub)
-        assert api.PyDict_Check(d)
-        assert not api.PyDict_CheckExact(d)
+        assert PyDict_Check(space, d)
+        assert not PyDict_CheckExact(space, d)
         i = space.wrap(2)
-        assert not api.PyDict_Check(i)
-        assert not api.PyDict_CheckExact(i)
+        assert not PyDict_Check(space, i)
+        assert not PyDict_CheckExact(space, i)
 
-    def test_keys(self, space, api):
+    def test_keys(self, space):
         w_d = space.newdict()
         space.setitem(w_d, space.wrap("a"), space.wrap("b"))
 
-        assert space.eq_w(api.PyDict_Keys(w_d), space.wrap(["a"]))
-        assert space.eq_w(api.PyDict_Values(w_d), space.wrap(["b"]))
-        assert space.eq_w(api.PyDict_Items(w_d), space.wrap([("a", "b")]))
+        assert space.eq_w(PyDict_Keys(space, w_d), space.wrap(["a"]))
+        assert space.eq_w(PyDict_Values(space, w_d), space.wrap(["b"]))
+        assert space.eq_w(PyDict_Items(space, w_d), space.wrap([("a", "b")]))
 
-    def test_merge(self, space, api):
+    def test_merge(self, space):
         w_d = space.newdict()
         space.setitem(w_d, space.wrap("a"), space.wrap("b"))
 
@@ -86,35 +84,34 @@
         space.setitem(w_d2, space.wrap("c"), space.wrap("d"))
         space.setitem(w_d2, space.wrap("e"), space.wrap("f"))
 
-        api.PyDict_Merge(w_d, w_d2, 0)
+        PyDict_Merge(space, w_d, w_d2, 0)
         assert space.unwrap(w_d) == dict(a='b', c='d', e='f')
-        api.PyDict_Merge(w_d, w_d2, 1)
+        PyDict_Merge(space, w_d, w_d2, 1)
         assert space.unwrap(w_d) == dict(a='c', c='d', e='f')
 
-    def test_update(self, space, api):
+    def test_update(self, space):
         w_d = space.newdict()
         space.setitem(w_d, space.wrap("a"), space.wrap("b"))
 
-        w_d2 = api.PyDict_Copy(w_d)
+        w_d2 = PyDict_Copy(space, w_d)
         assert not space.is_w(w_d2, w_d)
         space.setitem(w_d, space.wrap("c"), space.wrap("d"))
         space.setitem(w_d2, space.wrap("e"), space.wrap("f"))
 
-        api.PyDict_Update(w_d, w_d2)
+        PyDict_Update(space, w_d, w_d2)
         assert space.unwrap(w_d) == dict(a='b', c='d', e='f')
 
-    def test_update_doesnt_accept_list_of_tuples(self, space, api):
+    def test_update_doesnt_accept_list_of_tuples(self, space):
         w_d = space.newdict()
         space.setitem(w_d, space.wrap("a"), space.wrap("b"))
 
         w_d2 = space.wrap([("c", "d"), ("e", "f")])
 
-        api.PyDict_Update(w_d, w_d2)
-        assert api.PyErr_Occurred() is space.w_AttributeError
-        api.PyErr_Clear()
+        with raises_w(space, AttributeError):
+            PyDict_Update(space, w_d, w_d2)
         assert space.unwrap(w_d) == dict(a='b') # unchanged
 
-    def test_iter(self, space, api):
+    def test_iter(self, space):
         w_dict = space.sys.getdict(space)
         py_dict = make_ref(space, w_dict)
 
@@ -125,7 +122,7 @@
 
         try:
             w_copy = space.newdict()
-            while api.PyDict_Next(w_dict, ppos, pkey, pvalue):
+            while PyDict_Next(space, w_dict, ppos, pkey, pvalue):
                 w_key = from_ref(space, pkey[0])
                 w_value = from_ref(space, pvalue[0])
                 space.setitem(w_copy, w_key, w_value)
@@ -134,12 +131,12 @@
             lltype.free(pkey, flavor='raw')
             lltype.free(pvalue, flavor='raw')
 
-        api.Py_DecRef(py_dict) # release borrowed references
+        decref(space, py_dict) # release borrowed references
 
         assert space.eq_w(space.len(w_copy), space.len(w_dict))
         assert space.eq_w(w_copy, w_dict)
 
-    def test_iterkeys(self, space, api):
+    def test_iterkeys(self, space):
         w_dict = space.sys.getdict(space)
         py_dict = make_ref(space, w_dict)
 
@@ -151,11 +148,11 @@
         values_w = []
         try:
             ppos[0] = 0
-            while api.PyDict_Next(w_dict, ppos, pkey, None):
+            while PyDict_Next(space, w_dict, ppos, pkey, None):
                 w_key = from_ref(space, pkey[0])
                 keys_w.append(w_key)
             ppos[0] = 0
-            while api.PyDict_Next(w_dict, ppos, None, pvalue):
+            while PyDict_Next(space, w_dict, ppos, None, pvalue):
                 w_value = from_ref(space, pvalue[0])
                 values_w.append(w_value)
         finally:
@@ -163,25 +160,25 @@
             lltype.free(pkey, flavor='raw')
             lltype.free(pvalue, flavor='raw')
 
-        api.Py_DecRef(py_dict) # release borrowed references
+        decref(space, py_dict) # release borrowed references
 
         assert space.eq_w(space.newlist(keys_w),
                           space.call_method(w_dict, "keys"))
         assert space.eq_w(space.newlist(values_w),
                           space.call_method(w_dict, "values"))
 
-    def test_dictproxy(self, space, api):
+    def test_dictproxy(self, space):
         w_dict = space.sys.get('modules')
-        w_proxy = api.PyDictProxy_New(w_dict)
+        w_proxy = PyDictProxy_New(space, w_dict)
         assert space.contains_w(w_proxy, space.wrap('sys'))
         raises(OperationError, space.setitem,
                w_proxy, space.wrap('sys'), space.w_None)
         raises(OperationError, space.delitem,
                w_proxy, space.wrap('sys'))
         raises(OperationError, space.call_method, w_proxy, 'clear')
-        assert api.PyDictProxy_Check(w_proxy)
+        assert PyDictProxy_Check(space, w_proxy)
 
-    def test_typedict1(self, space, api):
+    def test_typedict1(self, space):
         py_type = make_ref(space, space.w_int)
         py_dict = rffi.cast(PyTypeObjectPtr, py_type).c_tp_dict
         ppos = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
@@ -191,7 +188,7 @@
         pvalue = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
         try:
             w_copy = space.newdict()
-            while api.PyDict_Next(py_dict, ppos, pkey, pvalue):
+            while PyDict_Next(space, py_dict, ppos, pkey, pvalue):
                 w_key = from_ref(space, pkey[0])
                 w_value = from_ref(space, pvalue[0])
                 space.setitem(w_copy, w_key, w_value)
@@ -199,7 +196,7 @@
             lltype.free(ppos, flavor='raw')
             lltype.free(pkey, flavor='raw')
             lltype.free(pvalue, flavor='raw')
-        api.Py_DecRef(py_type) # release borrowed references
+        decref(space, py_type) # release borrowed references
         # do something with w_copy ?
 
 class AppTestDictObject(AppTestCpythonExtensionBase):
diff --git a/pypy/module/cpyext/test/test_eval.py 
b/pypy/module/cpyext/test/test_eval.py
--- a/pypy/module/cpyext/test/test_eval.py
+++ b/pypy/module/cpyext/test/test_eval.py
@@ -1,17 +1,26 @@
+import sys
+import os
+import pytest
 from rpython.rtyper.lltypesystem import rffi, lltype
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
-from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.test.test_api import BaseApiTest, raises_w
+from pypy.module.cpyext.object import PyObject_Size, PyObject_GetItem
+from pypy.module.cpyext.pythonrun import Py_AtExit
 from pypy.module.cpyext.eval import (
-    Py_single_input, Py_file_input, Py_eval_input, PyCompilerFlags)
-from pypy.module.cpyext.api import (c_fopen, c_fclose, c_fileno, 
-                Py_ssize_tP, is_valid_fd)
+    Py_single_input, Py_file_input, Py_eval_input, PyCompilerFlags,
+    PyEval_CallObjectWithKeywords, PyObject_CallObject, PyEval_EvalCode,
+    PyRun_SimpleString, PyRun_String, PyRun_StringFlags, PyRun_File,
+    PyEval_GetBuiltins, PyEval_GetLocals, PyEval_GetGlobals,
+    _PyEval_SliceIndex)
+from pypy.module.cpyext.api import (
+    c_fopen, c_fclose, c_fileno, Py_ssize_tP, is_valid_fd)
 from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.error import OperationError
 from pypy.interpreter.astcompiler import consts
 from rpython.tool.udir import udir
-import sys, os
 
 class TestEval(BaseApiTest):
-    def test_eval(self, space, api):
+    def test_eval(self, space):
         w_l, w_f = space.fixedview(space.appexec([], """():
         l = []
         def f(arg1, arg2):
@@ -22,7 +31,7 @@
         """))
 
         w_t = space.newtuple([space.wrap(1), space.wrap(2)])
-        w_res = api.PyEval_CallObjectWithKeywords(w_f, w_t, None)
+        w_res = PyEval_CallObjectWithKeywords(space, w_f, w_t, None)
         assert space.int_w(w_res) == 2
         assert space.len_w(w_l) == 2
         w_f = space.appexec([], """():
@@ -35,10 +44,10 @@
         w_t = space.newtuple([space.w_None, space.w_None])
         w_d = space.newdict()
         space.setitem(w_d, space.wrap("xyz"), space.wrap(3))
-        w_res = api.PyEval_CallObjectWithKeywords(w_f, w_t, w_d)
+        w_res = PyEval_CallObjectWithKeywords(space, w_f, w_t, w_d)
         assert space.int_w(w_res) == 21
 
-    def test_call_object(self, space, api):
+    def test_call_object(self, space):
         w_l, w_f = space.fixedview(space.appexec([], """():
         l = []
         def f(arg1, arg2):
@@ -49,7 +58,7 @@
         """))
 
         w_t = space.newtuple([space.wrap(1), space.wrap(2)])
-        w_res = api.PyObject_CallObject(w_f, w_t)
+        w_res = PyObject_CallObject(space, w_f, w_t)
         assert space.int_w(w_res) == 2
         assert space.len_w(w_l) == 2
 
@@ -61,11 +70,11 @@
             """)
 
         w_t = space.newtuple([space.wrap(1), space.wrap(2)])
-        w_res = api.PyObject_CallObject(w_f, w_t)
+        w_res = PyObject_CallObject(space, w_f, w_t)
 
         assert space.int_w(w_res) == 10
 
-    def test_evalcode(self, space, api):
+    def test_evalcode(self, space):
         w_f = space.appexec([], """():
             def f(*args):
                 assert isinstance(args, tuple)
@@ -77,84 +86,78 @@
         w_globals = space.newdict()
         w_locals = space.newdict()
         space.setitem(w_locals, space.wrap("args"), w_t)
-        w_res = api.PyEval_EvalCode(w_f.code, w_globals, w_locals)
+        w_res = PyEval_EvalCode(space, w_f.code, w_globals, w_locals)
 
         assert space.int_w(w_res) == 10
 
-    def test_run_simple_string(self, space, api):
+    def test_run_simple_string(self, space):
         def run(code):
             buf = rffi.str2charp(code)
             try:
-                return api.PyRun_SimpleString(buf)
+                return PyRun_SimpleString(space, buf)
             finally:
                 rffi.free_charp(buf)
 
-        assert 0 == run("42 * 43")
+        assert run("42 * 43") == 0  # no error
+        with pytest.raises(OperationError):
+            run("4..3 * 43")
 
-        assert -1 == run("4..3 * 43")
-
-        assert api.PyErr_Occurred()
-        api.PyErr_Clear()
-
-    def test_run_string(self, space, api):
+    def test_run_string(self, space):
         def run(code, start, w_globals, w_locals):
             buf = rffi.str2charp(code)
             try:
-                return api.PyRun_String(buf, start, w_globals, w_locals)
+                return PyRun_String(space, buf, start, w_globals, w_locals)
             finally:
                 rffi.free_charp(buf)
 
         w_globals = space.newdict()
         assert 42 * 43 == space.unwrap(
             run("42 * 43", Py_eval_input, w_globals, w_globals))
-        assert api.PyObject_Size(w_globals) == 0
+        assert PyObject_Size(space, w_globals) == 0
 
         assert run("a = 42 * 43", Py_single_input,
                    w_globals, w_globals) == space.w_None
         assert 42 * 43 == space.unwrap(
-            api.PyObject_GetItem(w_globals, space.wrap("a")))
+            PyObject_GetItem(space, w_globals, space.wrap("a")))
 
-    def test_run_string_flags(self, space, api):
+    def test_run_string_flags(self, space):
         flags = lltype.malloc(PyCompilerFlags, flavor='raw')
         flags.c_cf_flags = rffi.cast(rffi.INT, consts.PyCF_SOURCE_IS_UTF8)
         w_globals = space.newdict()
         buf = rffi.str2charp("a = u'caf\xc3\xa9'")
         try:
-            api.PyRun_StringFlags(buf, Py_single_input,
-                                  w_globals, w_globals, flags)
+            PyRun_StringFlags(space, buf, Py_single_input, w_globals,
+                              w_globals, flags)
         finally:
             rffi.free_charp(buf)
         w_a = space.getitem(w_globals, space.wrap("a"))
         assert space.unwrap(w_a) == u'caf\xe9'
         lltype.free(flags, flavor='raw')
 
-    def test_run_file(self, space, api):
+    def test_run_file(self, space):
         filepath = udir / "cpyext_test_runfile.py"
         filepath.write("raise ZeroDivisionError")
         fp = c_fopen(str(filepath), "rb")
         filename = rffi.str2charp(str(filepath))
         w_globals = w_locals = space.newdict()
-        api.PyRun_File(fp, filename, Py_file_input, w_globals, w_locals)
+        with raises_w(space, ZeroDivisionError):
+            PyRun_File(space, fp, filename, Py_file_input, w_globals, w_locals)
         c_fclose(fp)
-        assert api.PyErr_Occurred() is space.w_ZeroDivisionError
-        api.PyErr_Clear()
 
         # try again, but with a closed file
         fp = c_fopen(str(filepath), "rb")
         os.close(c_fileno(fp))
-        api.PyRun_File(fp, filename, Py_file_input, w_globals, w_locals)
+        with raises_w(space, IOError):
+            PyRun_File(space, fp, filename, Py_file_input, w_globals, w_locals)
         if is_valid_fd(c_fileno(fp)):
             c_fclose(fp)
-        assert api.PyErr_Occurred() is space.w_IOError
-        api.PyErr_Clear()
-
         rffi.free_charp(filename)
 
-    def test_getbuiltins(self, space, api):
-        assert api.PyEval_GetBuiltins() is space.builtin.w_dict
+    def test_getbuiltins(self, space):
+        assert PyEval_GetBuiltins(space) is space.builtin.w_dict
 
         def cpybuiltins(space):
-            return api.PyEval_GetBuiltins()
+            return PyEval_GetBuiltins(space)
         w_cpybuiltins = space.wrap(interp2app(cpybuiltins))
 
         w_result = space.appexec([w_cpybuiltins], """(cpybuiltins):
@@ -168,13 +171,13 @@
         """)
         assert space.len_w(w_result) == 1
 
-    def test_getglobals(self, space, api):
-        assert api.PyEval_GetLocals() is None
-        assert api.PyEval_GetGlobals() is None
+    def test_getglobals(self, space):
+        assert PyEval_GetLocals(space) is None
+        assert PyEval_GetGlobals(space) is None
 
         def cpyvars(space):
-            return space.newtuple([api.PyEval_GetGlobals(),
-                                   api.PyEval_GetLocals()])
+            return space.newtuple([PyEval_GetGlobals(space),
+                                   PyEval_GetLocals(space)])
         w_cpyvars = space.wrap(interp2app(cpyvars))
 
         w_result = space.appexec([w_cpyvars], """(cpyvars):
@@ -186,26 +189,26 @@
         assert sorted(locals) == ['cpyvars', 'x']
         assert sorted(globals) == ['__builtins__', 'anonymous', 'y']
 
-    def test_sliceindex(self, space, api):
+    def test_sliceindex(self, space):
         pi = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
-        assert api._PyEval_SliceIndex(space.w_None, pi) == 0
-        api.PyErr_Clear()
+        with pytest.raises(OperationError):
+            _PyEval_SliceIndex(space, space.w_None, pi)
 
-        assert api._PyEval_SliceIndex(space.wrap(123), pi) == 1
+        assert _PyEval_SliceIndex(space, space.wrap(123), pi) == 1
         assert pi[0] == 123
 
-        assert api._PyEval_SliceIndex(space.wrap(1 << 66), pi) == 1
+        assert _PyEval_SliceIndex(space, space.wrap(1 << 66), pi) == 1
         assert pi[0] == sys.maxint
 
         lltype.free(pi, flavor='raw')
 
-    def test_atexit(self, space, api):
+    def test_atexit(self, space):
         lst = []
         def func():
             lst.append(42)
-        api.Py_AtExit(func)
+        Py_AtExit(space, func)
         cpyext = space.getbuiltinmodule('cpyext')
-        cpyext.shutdown(space) # simulate shutdown
+        cpyext.shutdown(space)  # simulate shutdown
         assert lst == [42]
 
 class AppTestCall(AppTestCpythonExtensionBase):
@@ -269,6 +272,7 @@
                 return res;
              """),
             ])
+
         def f(*args):
             return args
         assert module.call_func(f) == (None,)
@@ -322,7 +326,7 @@
             ])
         assert module.get_flags() == (0, 0)
 
-        ns = {'module':module}
+        ns = {'module': module}
         exec """from __future__ import division    \nif 1:
                 def nested_flags():
                     return module.get_flags()""" in ns
diff --git a/pypy/module/cpyext/test/test_floatobject.py 
b/pypy/module/cpyext/test/test_floatobject.py
--- a/pypy/module/cpyext/test/test_floatobject.py
+++ b/pypy/module/cpyext/test/test_floatobject.py
@@ -1,36 +1,40 @@
+import pytest
+from pypy.interpreter.error import OperationError
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from rpython.rtyper.lltypesystem import rffi
+from pypy.module.cpyext.floatobject import (
+    PyFloat_FromDouble, PyFloat_AsDouble, PyFloat_AS_DOUBLE, PyNumber_Float,
+    _PyFloat_Unpack4, _PyFloat_Unpack8)
 
 class TestFloatObject(BaseApiTest):
-    def test_floatobject(self, space, api):
-        assert space.unwrap(api.PyFloat_FromDouble(3.14)) == 3.14
-        assert api.PyFloat_AsDouble(space.wrap(23.45)) == 23.45
-        assert api.PyFloat_AS_DOUBLE(space.wrap(23.45)) == 23.45
+    def test_floatobject(self, space):
+        assert space.unwrap(PyFloat_FromDouble(space, 3.14)) == 3.14
+        assert PyFloat_AsDouble(space, space.wrap(23.45)) == 23.45
+        assert PyFloat_AS_DOUBLE(space, space.wrap(23.45)) == 23.45
+        with pytest.raises(OperationError):
+            PyFloat_AsDouble(space, space.w_None)
 
-        assert api.PyFloat_AsDouble(space.w_None) == -1
-        api.PyErr_Clear()
-
-    def test_coerce(self, space, api):
-        assert space.type(api.PyNumber_Float(space.wrap(3))) is space.w_float
-        assert space.type(api.PyNumber_Float(space.wrap("3"))) is space.w_float
+    def test_coerce(self, space):
+        assert space.type(PyNumber_Float(space, space.wrap(3))) is 
space.w_float
+        assert space.type(PyNumber_Float(space, space.wrap("3"))) is 
space.w_float
 
         w_obj = space.appexec([], """():
             class Coerce(object):
                 def __float__(self):
                     return 42.5
             return Coerce()""")
-        assert space.eq_w(api.PyNumber_Float(w_obj), space.wrap(42.5))
+        assert space.eq_w(PyNumber_Float(space, w_obj), space.wrap(42.5))
 
-    def test_unpack(self, space, api):
+    def test_unpack(self, space):
         with rffi.scoped_str2charp("\x9a\x99\x99?") as ptr:
-            assert abs(api._PyFloat_Unpack4(ptr, 1) - 1.2) < 1e-7
+            assert abs(_PyFloat_Unpack4(space, ptr, 1) - 1.2) < 1e-7
         with rffi.scoped_str2charp("?\x99\x99\x9a") as ptr:
-            assert abs(api._PyFloat_Unpack4(ptr, 0) - 1.2) < 1e-7
+            assert abs(_PyFloat_Unpack4(space, ptr, 0) - 1.2) < 1e-7
         with rffi.scoped_str2charp("\x1f\x85\xebQ\xb8\x1e\t@") as ptr:
-            assert abs(api._PyFloat_Unpack8(ptr, 1) - 3.14) < 1e-15
+            assert abs(_PyFloat_Unpack8(space, ptr, 1) - 3.14) < 1e-15
         with rffi.scoped_str2charp("@\t\x1e\xb8Q\xeb\x85\x1f") as ptr:
-            assert abs(api._PyFloat_Unpack8(ptr, 0) - 3.14) < 1e-15
+            assert abs(_PyFloat_Unpack8(space, ptr, 0) - 3.14) < 1e-15
 
 class AppTestFloatObject(AppTestCpythonExtensionBase):
     def test_fromstring(self):
@@ -79,8 +83,6 @@
         assert math.isinf(neginf)
 
     def test_macro_accepts_wrong_pointer_type(self):
-        import math
-
         module = self.import_extension('foo', [
             ("test_macros", "METH_NOARGS",
              """
diff --git a/pypy/module/cpyext/test/test_funcobject.py 
b/pypy/module/cpyext/test/test_funcobject.py
--- a/pypy/module/cpyext/test/test_funcobject.py
+++ b/pypy/module/cpyext/test/test_funcobject.py
@@ -1,16 +1,18 @@
-from rpython.rtyper.lltypesystem import rffi, lltype
-from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+from rpython.rtyper.lltypesystem import rffi
 from pypy.module.cpyext.test.test_api import BaseApiTest
-from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref
+from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref, decref
+from pypy.module.cpyext.methodobject import PyClassMethod_New
 from pypy.module.cpyext.funcobject import (
-    PyFunctionObject, PyCodeObject, CODE_FLAGS)
-from pypy.interpreter.function import Function, Method
+    PyFunctionObject, PyCodeObject, CODE_FLAGS, PyMethod_Function,
+    PyMethod_Self, PyMethod_Class, PyMethod_New, PyFunction_GetCode,
+    PyCode_NewEmpty, PyCode_GetNumFree)
+from pypy.interpreter.function import Function
 from pypy.interpreter.pycode import PyCode
 
 globals().update(CODE_FLAGS)
 
 class TestFunctionObject(BaseApiTest):
-    def test_function(self, space, api):
+    def test_function(self, space):
         w_function = space.appexec([], """():
             def f(): pass
             return f
@@ -19,10 +21,10 @@
         assert (from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is
                 space.gettypeobject(Function.typedef))
         assert "f" == space.unwrap(
-           from_ref(space, rffi.cast(PyFunctionObject, ref).c_func_name))
-        api.Py_DecRef(ref)
+            from_ref(space, rffi.cast(PyFunctionObject, ref).c_func_name))
+        decref(space, ref)
 
-    def test_method(self, space, api):
+    def test_method(self, space):
         w_method = space.appexec([], """():
             class C(list):
                 def method(self): pass
@@ -33,30 +35,30 @@
         w_self = space.getattr(w_method, space.wrap("im_self"))
         w_class = space.getattr(w_method, space.wrap("im_class"))
 
-        assert space.is_w(api.PyMethod_Function(w_method), w_function)
-        assert space.is_w(api.PyMethod_Self(w_method), w_self)
-        assert space.is_w(api.PyMethod_Class(w_method), w_class)
+        assert space.is_w(PyMethod_Function(space, w_method), w_function)
+        assert space.is_w(PyMethod_Self(space, w_method), w_self)
+        assert space.is_w(PyMethod_Class(space, w_method), w_class)
 
-        w_method2 = api.PyMethod_New(w_function, w_self, w_class)
+        w_method2 = PyMethod_New(space, w_function, w_self, w_class)
         assert space.eq_w(w_method, w_method2)
 
-    def test_getcode(self, space, api):
+    def test_getcode(self, space):
         w_function = space.appexec([], """():
             def func(x, y, z): return x
             return func
         """)
-        w_code = api.PyFunction_GetCode(w_function)
+        w_code = PyFunction_GetCode(space, w_function)
         assert w_code.co_name == "func"
 
         ref = make_ref(space, w_code)
         assert (from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is
                 space.gettypeobject(PyCode.typedef))
         assert "func" == space.unwrap(
-           from_ref(space, rffi.cast(PyCodeObject, ref).c_co_name))
+            from_ref(space, rffi.cast(PyCodeObject, ref).c_co_name))
         assert 3 == rffi.cast(PyCodeObject, ref).c_co_argcount
-        api.Py_DecRef(ref)
+        decref(space, ref)
 
-    def test_co_flags(self, space, api):
+    def test_co_flags(self, space):
         def get_flags(signature, body="pass"):
             w_code = space.appexec([], """():
                 def func(%s): %s
@@ -64,7 +66,7 @@
             """ % (signature, body))
             ref = make_ref(space, w_code)
             co_flags = rffi.cast(PyCodeObject, ref).c_co_flags
-            api.Py_DecRef(ref)
+            decref(space, ref)
             return co_flags
         assert get_flags("x") == CO_NESTED | CO_OPTIMIZED | CO_NEWLOCALS
         assert get_flags("x", "exec x") == CO_NESTED | CO_NEWLOCALS
@@ -72,29 +74,29 @@
         assert get_flags("x, **kw") & CO_VARKEYWORDS
         assert get_flags("x", "yield x") & CO_GENERATOR
 
-    def test_newcode(self, space, api):
+    def test_newcode(self, space):
         filename = rffi.str2charp('filename')
         funcname = rffi.str2charp('funcname')
-        w_code = api.PyCode_NewEmpty(filename, funcname, 3)
+        w_code = PyCode_NewEmpty(space, filename, funcname, 3)
         assert w_code.co_filename == 'filename'
         assert w_code.co_firstlineno == 3
 
         ref = make_ref(space, w_code)
         assert "filename" == space.unwrap(
             from_ref(space, rffi.cast(PyCodeObject, ref).c_co_filename))
-        api.Py_DecRef(ref)
+        decref(space, ref)
         rffi.free_charp(filename)
         rffi.free_charp(funcname)
 
-    def test_getnumfree(self, space, api):
+    def test_getnumfree(self, space):
         w_function = space.appexec([], """():
             a = 5
             def method(x): return a, x
             return method
         """)
-        assert api.PyCode_GetNumFree(w_function.code) == 1
+        assert PyCode_GetNumFree(space, w_function.code) == 1
 
-    def test_classmethod(self, space, api):
+    def test_classmethod(self, space):
         w_function = space.appexec([], """():
             def method(x): return x
             return method
@@ -106,6 +108,7 @@
         space.setattr(w_class, space.wrap("method"), w_function)
         assert space.is_w(space.call_method(w_instance, "method"), w_instance)
         # now a classmethod
-        w_classmethod = api.PyClassMethod_New(w_function)
+        w_classmethod = PyClassMethod_New(space, w_function)
         space.setattr(w_class, space.wrap("classmethod"), w_classmethod)
-        assert space.is_w(space.call_method(w_instance, "classmethod"), 
w_class)
+        assert space.is_w(
+            space.call_method(w_instance, "classmethod"), w_class)
diff --git a/pypy/module/cpyext/test/test_import.py 
b/pypy/module/cpyext/test/test_import.py
--- a/pypy/module/cpyext/test/test_import.py
+++ b/pypy/module/cpyext/test/test_import.py
@@ -1,48 +1,51 @@
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+from pypy.module.cpyext.import_ import *
+from pypy.module.cpyext.import_ import (
+    _PyImport_AcquireLock, _PyImport_ReleaseLock)
 from rpython.rtyper.lltypesystem import rffi
 
 class TestImport(BaseApiTest):
-    def test_import(self, space, api):
-        stat = api.PyImport_Import(space.wrap("stat"))
+    def test_import(self, space):
+        stat = PyImport_Import(space, space.wrap("stat"))
         assert stat
         assert space.getattr(stat, space.wrap("S_IMODE"))
 
-    def test_addmodule(self, space, api):
+    def test_addmodule(self, space):
         with rffi.scoped_str2charp("sys") as modname:
-            w_sys = api.PyImport_AddModule(modname)
+            w_sys = PyImport_AddModule(space, modname)
         assert w_sys is space.sys
 
         with rffi.scoped_str2charp("foobar") as modname:
-            w_foobar = api.PyImport_AddModule(modname)
+            w_foobar = PyImport_AddModule(space, modname)
         assert space.str_w(space.getattr(w_foobar,
                                          space.wrap('__name__'))) == 'foobar'
 
-    def test_getmoduledict(self, space, api):
+    def test_getmoduledict(self, space):
         testmod = "_functools"
-        w_pre_dict = api.PyImport_GetModuleDict()
+        w_pre_dict = PyImport_GetModuleDict(space, )
         assert not space.contains_w(w_pre_dict, space.wrap(testmod))
 
         with rffi.scoped_str2charp(testmod) as modname:
-            w_module = api.PyImport_ImportModule(modname)
+            w_module = PyImport_ImportModule(space, modname)
             print w_module
             assert w_module
 
-        w_dict = api.PyImport_GetModuleDict()
+        w_dict = PyImport_GetModuleDict(space, )
         assert space.contains_w(w_dict, space.wrap(testmod))
 
-    def test_reload(self, space, api):
-        stat = api.PyImport_Import(space.wrap("stat"))
+    def test_reload(self, space):
+        stat = PyImport_Import(space, space.wrap("stat"))
         space.delattr(stat, space.wrap("S_IMODE"))
-        stat = api.PyImport_ReloadModule(stat)
+        stat = PyImport_ReloadModule(space, stat)
         assert space.getattr(stat, space.wrap("S_IMODE"))
 
-    def test_lock(self, space, api):
+    def test_lock(self, space):
         # "does not crash"
-        api._PyImport_AcquireLock()
-        api._PyImport_AcquireLock()
-        api._PyImport_ReleaseLock()
-        api._PyImport_ReleaseLock()
+        _PyImport_AcquireLock(space, )
+        _PyImport_AcquireLock(space, )
+        _PyImport_ReleaseLock(space, )
+        _PyImport_ReleaseLock(space, )
 
 
 class AppTestImportLogic(AppTestCpythonExtensionBase):
diff --git a/pypy/module/cpyext/test/test_intobject.py 
b/pypy/module/cpyext/test/test_intobject.py
--- a/pypy/module/cpyext/test/test_intobject.py
+++ b/pypy/module/cpyext/test/test_intobject.py
@@ -1,51 +1,52 @@
-from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.test.test_api import BaseApiTest, raises_w
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+from pypy.module.cpyext.intobject import (
+    PyInt_Check, PyInt_AsLong, PyInt_AS_LONG, PyInt_FromLong,
+    PyInt_AsUnsignedLong, PyInt_AsUnsignedLongMask,
+    PyInt_AsUnsignedLongLongMask)
 import sys
 
 class TestIntObject(BaseApiTest):
-    def test_intobject(self, space, api):
-        assert api.PyInt_Check(space.wrap(3))
-        assert api.PyInt_Check(space.w_True)
-        assert not api.PyInt_Check(space.wrap((1, 2, 3)))
+    def test_intobject(self, space):
+        assert PyInt_Check(space, space.wrap(3))
+        assert PyInt_Check(space, space.w_True)
+        assert not PyInt_Check(space, space.wrap((1, 2, 3)))
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to