[pypy-svn] r75237 - in pypy/branch/cpyext-init-cleanup/pypy/module/cpyext: . test
afa at codespeak.net
afa at codespeak.net
Wed Jun 9 17:56:52 CEST 2010
Author: afa
Date: Wed Jun 9 17:56:49 2010
New Revision: 75237
Added:
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/gateway.py
Modified:
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/api.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/boolobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/classobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/complexobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/datetime.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/dictobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/eval.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/floatobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/funcobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/import_.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/intobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/iterator.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/listobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/longobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/mapping.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/methodobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/modsupport.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/number.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/object.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pyerrors.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pyobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pystate.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pythonrun.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/sequence.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/sliceobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/slotdefs.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/stringobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/structmember.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/stubsactive.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/sysmodule.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_api.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_borrow.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_cpyext.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_methodobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_translate.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/thread.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/tupleobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/typeobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/unicodeobject.py
pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/weakrefobject.py
Log:
Split the large api.py, and move cross-language functions calls into gateway.py
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/api.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/api.py Wed Jun 9 17:56:49 2010
@@ -13,10 +13,10 @@
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.translator.gensupp import NameManager
from pypy.tool.udir import udir
+from pypy.tool.sourcetools import func_with_new_name
from pypy.translator import platform
-from pypy.module.cpyext.state import State
-from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.interpreter.baseobjspace import W_Root, ObjSpace
+from pypy.interpreter.error import operationerrfmt
+from pypy.interpreter.baseobjspace import ObjSpace
from pypy.interpreter.gateway import unwrap_spec
from pypy.interpreter.nestedscope import Cell
from pypy.interpreter.module import Module
@@ -32,8 +32,6 @@
from pypy.module.exceptions import interp_exceptions
# CPython 2.4 compatibility
from py.builtin import BaseException
-from pypy.tool.sourcetools import func_with_new_name
-from pypy.rpython.lltypesystem.lloperation import llop
DEBUG_WRAPPER = True
@@ -112,43 +110,15 @@
def get_interpret(self, space):
raise NotImplementedError
-def copy_header_files():
- for name in ("pypy_decl.h", "pypy_macros.h"):
- udir.join(name).copy(interfaces_dir / name)
-
-_NOT_SPECIFIED = object()
-CANNOT_FAIL = object()
-
-# The same function can be called in three different contexts:
-# (1) from C code
-# (2) in the test suite, though the "api" object
-# (3) from RPython code, for example in the implementation of another function.
-#
-# In contexts (2) and (3), a function declaring a PyObject argument type will
-# receive a wrapped pypy object if the parameter name starts with 'w_', a
-# reference (= rffi pointer) otherwise; conversion is automatic. Context (2)
-# only allows calls with a wrapped object.
-#
-# Functions with a PyObject return type should return a wrapped object.
-#
-# Functions may raise exceptions. In context (3), the exception flows normally
-# through the calling function. In context (1) and (2), the exception is
-# caught; if it is an OperationError, it is stored in the thread state; other
-# exceptions generate a OperationError(w_SystemError); and the funtion returns
-# the error value specifed in the API.
-#
-
cpyext_namespace = NameManager('cpyext_')
class ApiFunction(BaseApiObject):
- def __init__(self, argtypes, restype, callable, error=_NOT_SPECIFIED,
- c_name=None):
+ def __init__(self, argtypes, restype, callable, error, c_name=None):
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 user code object
@@ -165,7 +135,7 @@
def get_llpointer(self, space):
"Returns a C function pointer"
- assert not we_are_translated()
+ assert not we_are_translated() # NOT_RPYTHON??
llh = getattr(self, '_llhelper', None)
if llh is None:
llh = llhelper(self.functype, self._get_wrapper(space))
@@ -181,6 +151,7 @@
def _get_wrapper(self, space):
wrapper = getattr(self, '_wrapper', None)
if wrapper is None:
+ from pypy.module.cpyext.gateway import make_wrapper
wrapper = make_wrapper(space, self.callable)
self._wrapper = wrapper
wrapper.relax_sig_check = True
@@ -188,114 +159,16 @@
wrapper.c_name = cpyext_namespace.uniquename(self.c_name)
return wrapper
-def cpython_api(argtypes, restype, error=_NOT_SPECIFIED, external=True):
- """
- Declares a function to be exported.
- - `argtypes`, `restype` are lltypes and describe the function signature.
- - `error` is the value returned when an applevel exception is raised. The
- special value 'CANNOT_FAIL' (also when restype is Void) turns an eventual
- exception into a wrapped SystemError. Unwrapped exceptions also cause a
- SytemError.
- - set `external` to False to get a C function pointer, but not exported by
- the API headers.
- """
- if error is _NOT_SPECIFIED:
- if restype is PyObject:
- error = lltype.nullptr(restype.TO)
- elif restype is lltype.Void:
- error = CANNOT_FAIL
- if type(error) is int:
- error = rffi.cast(restype, error)
-
- def decorate(func):
- func_name = func.func_name
- if external:
- c_name = None
- else:
- c_name = func_name
- api_function = ApiFunction(argtypes, restype, func, error, c_name=c_name)
- func.api_func = api_function
-
- if external:
- assert func_name not in FUNCTIONS, (
- "%s already registered" % func_name)
-
- if error is _NOT_SPECIFIED:
- raise ValueError("function %s has no return value for exceptions"
- % func)
- def make_unwrapper(catch_exception):
- names = api_function.argnames
- types_names_enum_ui = unrolling_iterable(enumerate(
- zip(api_function.argtypes,
- [tp_name.startswith("w_") for tp_name in names])))
-
- @specialize.ll()
- def unwrapper(space, *args):
- from pypy.module.cpyext.pyobject import Py_DecRef
- from pypy.module.cpyext.pyobject import make_ref, from_ref
- from pypy.module.cpyext.pyobject import BorrowPair
- newargs = ()
- to_decref = []
- assert len(args) == len(api_function.argtypes)
- for i, (ARG, is_wrapped) in types_names_enum_ui:
- input_arg = args[i]
- if is_PyObject(ARG) and not is_wrapped:
- # build a reference
- if input_arg is None:
- arg = lltype.nullptr(PyObject.TO)
- elif isinstance(input_arg, W_Root):
- ref = make_ref(space, input_arg)
- to_decref.append(ref)
- arg = rffi.cast(ARG, ref)
- else:
- arg = input_arg
- elif is_PyObject(ARG) and is_wrapped:
- # convert to a wrapped object
- if input_arg is None:
- arg = input_arg
- elif isinstance(input_arg, W_Root):
- arg = input_arg
- else:
- arg = from_ref(space,
- rffi.cast(PyObject, input_arg))
- else:
- arg = input_arg
- newargs += (arg, )
- try:
- try:
- res = func(space, *newargs)
- except OperationError, e:
- if not catch_exception:
- raise
- if not hasattr(api_function, "error_value"):
- raise
- state = space.fromcache(State)
- state.set_exception(e)
- if is_PyObject(restype):
- return None
- else:
- return api_function.error_value
- if res is None:
- return None
- elif isinstance(res, BorrowPair):
- return res.w_borrowed
- else:
- return res
- finally:
- for arg in to_decref:
- Py_DecRef(space, arg)
- unwrapper.func = func
- unwrapper.api_func = api_function
- unwrapper._always_inline_ = True
- return unwrapper
-
- unwrapper_catch = make_unwrapper(True)
- unwrapper_raise = make_unwrapper(False)
- if external:
- FUNCTIONS[func_name] = api_function
- INTERPLEVEL_API[func_name] = unwrapper_catch # used in tests
- return unwrapper_raise # used in 'normal' RPython code.
- return decorate
+def FUNCTION_declare(name, api_func):
+ assert name not in FUNCTIONS, "%s already registered" % (name,)
+ FUNCTIONS[name] = api_func
+
+def INTERPLEVEL_declare(name, obj):
+ INTERPLEVEL_API[name] = obj
+
+def copy_header_files():
+ for name in ("pypy_decl.h", "pypy_macros.h"):
+ udir.join(name).copy(interfaces_dir / name)
def cpython_struct(name, fields, forward=None):
configname = name.replace(' ', '__')
@@ -549,17 +422,12 @@
PyVarObject = lltype.Ptr(PyVarObjectStruct)
PyObjectP = rffi.CArrayPtr(PyObject)
- at specialize.memo()
-def is_PyObject(TYPE):
- if not isinstance(TYPE, lltype.Ptr):
- return False
- return hasattr(TYPE.TO, 'c_ob_refcnt') and hasattr(TYPE.TO, 'c_ob_type')
-
def configure_types():
for name, TYPE in rffi_platform.configure(CConfig).iteritems():
if name in TYPES:
TYPES[name].become(TYPE)
+
def build_type_checkers(type_name, cls=None):
"""
Builds two api functions: Py_XxxCheck() and Py_XxxCheckExact().
@@ -591,101 +459,13 @@
w_type = get_w_type(space)
return space.is_w(w_obj_type, w_type)
+ from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
check = cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)(
func_with_new_name(check, check_name))
check_exact = cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)(
func_with_new_name(check_exact, check_name + "Exact"))
return check, check_exact
-pypy_debug_catch_fatal_exception = rffi.llexternal('pypy_debug_catch_fatal_exception', [], lltype.Void)
-
-# Make the wrapper for the cases (1) and (2)
-def make_wrapper(space, callable):
- "NOT_RPYTHON"
- names = callable.api_func.argnames
- argtypes_enum_ui = unrolling_iterable(enumerate(zip(callable.api_func.argtypes,
- [name.startswith("w_") for name in names])))
- fatal_value = callable.api_func.restype._defl()
-
- @specialize.ll()
- def wrapper(*args):
- from pypy.module.cpyext.pyobject import make_ref, from_ref
- from pypy.module.cpyext.pyobject import BorrowPair
- # we hope that malloc removal removes the newtuple() that is
- # inserted exactly here by the varargs specializer
- llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py
- rffi.stackcounter.stacks_counter += 1
- retval = fatal_value
- boxed_args = ()
- try:
- if not we_are_translated() and DEBUG_WRAPPER:
- print >>sys.stderr, callable,
- assert len(args) == len(callable.api_func.argtypes)
- for i, (typ, is_wrapped) in argtypes_enum_ui:
- arg = args[i]
- if is_PyObject(typ) and is_wrapped:
- if arg:
- arg_conv = from_ref(space, rffi.cast(PyObject, arg))
- else:
- arg_conv = None
- else:
- arg_conv = arg
- boxed_args += (arg_conv, )
- state = space.fromcache(State)
- try:
- result = callable(space, *boxed_args)
- if not we_are_translated() and DEBUG_WRAPPER:
- print >>sys.stderr, " DONE"
- except OperationError, e:
- failed = True
- state.set_exception(e)
- except BaseException, e:
- failed = True
- if not we_are_translated():
- message = repr(e)
- import traceback
- traceback.print_exc()
- else:
- message = str(e)
- state.set_exception(OperationError(space.w_SystemError,
- space.wrap(message)))
- else:
- failed = False
-
- if failed:
- error_value = callable.api_func.error_value
- if error_value is CANNOT_FAIL:
- raise SystemError("The function '%s' was not supposed to fail"
- % (callable.__name__,))
- retval = error_value
-
- elif is_PyObject(callable.api_func.restype):
- if result is None:
- retval = make_ref(space, None)
- elif isinstance(result, BorrowPair):
- retval = result.get_ref(space)
- elif not rffi._isllptr(result):
- retval = rffi.cast(callable.api_func.restype,
- make_ref(space, result))
- else:
- retval = result
- elif callable.api_func.restype is not lltype.Void:
- retval = rffi.cast(callable.api_func.restype, result)
- except Exception, e:
- if not we_are_translated():
- import traceback
- traceback.print_exc()
- print str(e)
- # we can't do much here, since we're in ctypes, swallow
- else:
- print str(e)
- pypy_debug_catch_fatal_exception()
- rffi.stackcounter.stacks_counter -= 1
- return retval
- callable._always_inline_ = True
- wrapper.__name__ = "wrapper for %r" % (callable, )
- return wrapper
-
def setup_init_functions(eci):
init_buffer = rffi.llexternal('init_bufferobject', [], lltype.Void, compilation_info=eci)
init_pycobject = rffi.llexternal('init_pycobject', [], lltype.Void, compilation_info=eci)
@@ -948,6 +728,8 @@
initfunctype = lltype.Ptr(lltype.FuncType([], lltype.Void))
@unwrap_spec(ObjSpace, str, str)
def load_extension_module(space, path, name):
+ from pypy.module.cpyext.state import State
+ from pypy.module.cpyext.gateway import generic_cpy_call
state = space.fromcache(State)
state.package_context = name
try:
@@ -974,113 +756,3 @@
finally:
state.package_context = None
- at specialize.ll()
-def generic_cpy_call(space, func, *args):
- FT = lltype.typeOf(func).TO
- return make_generic_cpy_call(FT, True, False)(space, func, *args)
-
- at specialize.ll()
-def generic_cpy_call_dont_decref(space, func, *args):
- FT = lltype.typeOf(func).TO
- return make_generic_cpy_call(FT, False, False)(space, func, *args)
-
- at specialize.ll()
-def generic_cpy_call_expect_null(space, func, *args):
- FT = lltype.typeOf(func).TO
- return make_generic_cpy_call(FT, True, True)(space, func, *args)
-
- at specialize.memo()
-def make_generic_cpy_call(FT, decref_args, expect_null):
- from pypy.module.cpyext.pyobject import make_ref, from_ref, Py_DecRef
- from pypy.module.cpyext.pyobject import RefcountState
- from pypy.module.cpyext.pyerrors import PyErr_Occurred
- unrolling_arg_types = unrolling_iterable(enumerate(FT.ARGS))
- RESULT_TYPE = FT.RESULT
-
- # copied and modified from rffi.py
- # We need tons of care to ensure that no GC operation and no
- # exception checking occurs in call_external_function.
- argnames = ', '.join(['a%d' % i for i in range(len(FT.ARGS))])
- source = py.code.Source("""
- def call_external_function(funcptr, %(argnames)s):
- # NB. it is essential that no exception checking occurs here!
- res = funcptr(%(argnames)s)
- return res
- """ % locals())
- miniglobals = {'__name__': __name__, # for module name propagation
- }
- exec source.compile() in miniglobals
- call_external_function = miniglobals['call_external_function']
- call_external_function._dont_inline_ = True
- call_external_function._annspecialcase_ = 'specialize:ll'
- call_external_function._gctransformer_hint_close_stack_ = True
- call_external_function = func_with_new_name(call_external_function,
- 'ccall_' + name)
- # don't inline, as a hack to guarantee that no GC pointer is alive
- # anywhere in call_external_function
-
- @specialize.ll()
- def generic_cpy_call(space, func, *args):
- boxed_args = ()
- to_decref = []
- assert len(args) == len(FT.ARGS)
- for i, ARG in unrolling_arg_types:
- arg = args[i]
- if is_PyObject(ARG):
- if arg is None:
- boxed_args += (lltype.nullptr(PyObject.TO),)
- elif isinstance(arg, W_Root):
- ref = make_ref(space, arg)
- boxed_args += (ref,)
- if decref_args:
- to_decref.append(ref)
- else:
- boxed_args += (arg,)
- else:
- boxed_args += (arg,)
-
- try:
- # create a new container for borrowed references
- state = space.fromcache(RefcountState)
- old_container = state.swap_borrow_container(None)
- try:
- # Call the function
- result = call_external_function(func, *boxed_args)
- finally:
- state.swap_borrow_container(old_container)
-
- if is_PyObject(RESULT_TYPE):
- if result is None:
- ret = result
- elif isinstance(result, W_Root):
- ret = result
- else:
- ret = from_ref(space, result)
- # The object reference returned from a C function
- # that is called from Python must be an owned reference
- # - ownership is transferred from the function to its caller.
- if result:
- Py_DecRef(space, result)
-
- # Check for exception consistency
- has_error = PyErr_Occurred(space) is not None
- has_result = ret is not None
- if has_error and has_result:
- raise OperationError(space.w_SystemError, space.wrap(
- "An exception was set, but function returned a value"))
- elif not expect_null and not has_error and not has_result:
- raise OperationError(space.w_SystemError, space.wrap(
- "Function returned a NULL result without setting an exception"))
-
- if has_error:
- state = space.fromcache(State)
- state.check_and_raise_exception()
-
- return ret
- return result
- finally:
- if decref_args:
- for ref in to_decref:
- Py_DecRef(space, ref)
- return generic_cpy_call
-
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/boolobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/boolobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/boolobject.py Wed Jun 9 17:56:49 2010
@@ -1,6 +1,7 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import (cpython_api, PyObject, CANNOT_FAIL,
- build_type_checkers)
+from pypy.module.cpyext.gateway import (
+ cpython_api, CANNOT_FAIL)
+from pypy.module.cpyext.api import PyObject, build_type_checkers
# Inheriting from bool isn't actually possible.
PyBool_Check = build_type_checkers("Bool")[1]
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/classobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/classobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/classobject.py Wed Jun 9 17:56:49 2010
@@ -1,10 +1,12 @@
from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
from pypy.module.cpyext.api import (
- PyObjectFields, CANNOT_FAIL,
- cpython_api, bootstrap_function, cpython_struct, build_type_checkers)
-from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref, Py_DecRef, make_typedescr
+ PyObjectFields, bootstrap_function, cpython_struct, build_type_checkers)
+from pypy.module.cpyext.pyobject import (
+ PyObject, make_ref, from_ref, Py_DecRef, make_typedescr)
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
-from pypy.module.__builtin__.interp_classobj import W_ClassObject, W_InstanceObject
+from pypy.module.__builtin__.interp_classobj import (
+ W_ClassObject, W_InstanceObject)
PyClass_Check, PyClass_CheckExact = build_type_checkers("Class", W_ClassObject)
PyInstance_Check, PyInstance_CheckExact = build_type_checkers("Instance", W_InstanceObject)
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/complexobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/complexobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/complexobject.py Wed Jun 9 17:56:49 2010
@@ -1,6 +1,7 @@
from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.module.cpyext.api import (
- cpython_api, cpython_struct, PyObject, build_type_checkers)
+from pypy.module.cpyext.gateway import cpython_api
+from pypy.module.cpyext.api import cpython_struct, build_type_checkers
+from pypy.module.cpyext.pyobject import PyObject
from pypy.module.cpyext.pyerrors import PyErr_BadArgument
from pypy.module.cpyext.floatobject import PyFloat_AsDouble
from pypy.objspace.std.complexobject import W_ComplexObject
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/datetime.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/datetime.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/datetime.py Wed Jun 9 17:56:49 2010
@@ -1,7 +1,7 @@
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.module.cpyext.pyobject import PyObject, make_ref
-from pypy.module.cpyext.api import (
- cpython_api, CANNOT_FAIL, cpython_struct, PyObjectFields)
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.api import cpython_struct, PyObjectFields
from pypy.module.cpyext.import_ import PyImport_Import
from pypy.module.cpyext.typeobject import PyTypeObjectPtr
from pypy.interpreter.error import OperationError
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/dictobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/dictobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/dictobject.py Wed Jun 9 17:56:49 2010
@@ -1,9 +1,9 @@
from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
from pypy.module.cpyext.api import (
- cpython_api, CANNOT_FAIL, build_type_checkers, Py_ssize_t,
- Py_ssize_tP, CONST_STRING)
-from pypy.module.cpyext.pyobject import PyObject, PyObjectP, borrow_from
-from pypy.module.cpyext.pyobject import RefcountState
+ build_type_checkers, Py_ssize_t, Py_ssize_tP, CONST_STRING)
+from pypy.module.cpyext.pyobject import (
+ PyObject, PyObjectP, borrow_from, RefcountState)
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
from pypy.interpreter.error import OperationError
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/eval.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/eval.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/eval.py Wed Jun 9 17:56:49 2010
@@ -1,7 +1,8 @@
from pypy.interpreter.error import OperationError
from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
from pypy.module.cpyext.api import (
- cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, fread, feof, Py_ssize_tP)
+ CONST_STRING, FILEP, fread, feof, Py_ssize_tP)
from pypy.module.cpyext.pyobject import PyObject, borrow_from
from pypy.module.cpyext.pyerrors import PyErr_SetFromErrno
from pypy.module.__builtin__ import compiling
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/floatobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/floatobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/floatobject.py Wed Jun 9 17:56:49 2010
@@ -1,6 +1,6 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import (CANNOT_FAIL, cpython_api, PyObject,
- build_type_checkers)
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.api import PyObject, build_type_checkers
from pypy.interpreter.error import OperationError
PyFloat_Check, PyFloat_CheckExact = build_type_checkers("Float")
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/funcobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/funcobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/funcobject.py Wed Jun 9 17:56:49 2010
@@ -1,7 +1,7 @@
from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.gateway import cpython_api, generic_cpy_call
from pypy.module.cpyext.api import (
- PyObjectFields, generic_cpy_call,
- cpython_api, bootstrap_function, cpython_struct, build_type_checkers)
+ cpython_struct, build_type_checkers, PyObjectFields, bootstrap_function)
from pypy.module.cpyext.pyobject import (
PyObject, make_ref, from_ref, Py_DecRef, make_typedescr, borrow_from)
from pypy.interpreter.function import Function, Method
Added: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/gateway.py
==============================================================================
--- (empty file)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/gateway.py Wed Jun 9 17:56:49 2010
@@ -0,0 +1,343 @@
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.error import OperationError
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rpython.lltypesystem.lloperation import llop
+from pypy.rlib.objectmodel import specialize, we_are_translated
+from pypy.module.cpyext.api import (
+ ApiFunction, FUNCTION_declare, INTERPLEVEL_declare, PyObject)
+from pypy.module.cpyext.state import State
+from pypy.rlib.unroll import unrolling_iterable
+import sys
+import py
+
+# The same function can be called in three different contexts:
+# (1) from C code
+# (2) in the test suite, though the "api" object
+# (3) from RPython code, for example in the implementation of another function.
+#
+# In contexts (2) and (3), a function declaring a PyObject argument type will
+# receive a wrapped pypy object if the parameter name starts with 'w_', a
+# reference (= rffi pointer) otherwise; conversion is automatic. Context (2)
+# only allows calls with a wrapped object.
+#
+# Functions with a PyObject return type should return a wrapped object.
+#
+# Functions may raise exceptions. In context (3), the exception flows normally
+# through the calling function. In context (1) and (2), the exception is
+# caught; if it is an OperationError, it is stored in the thread state; other
+# exceptions generate a OperationError(w_SystemError); and the funtion returns
+# the error value specifed in the API.
+#
+
+DEBUG_WRAPPER = True
+
+_NOT_SPECIFIED = object()
+CANNOT_FAIL = object()
+
+pypy_debug_catch_fatal_exception = rffi.llexternal('pypy_debug_catch_fatal_exception', [], lltype.Void)
+
+ at specialize.memo()
+def is_PyObject(TYPE):
+ if not isinstance(TYPE, lltype.Ptr):
+ return False
+ return hasattr(TYPE.TO, 'c_ob_refcnt') and hasattr(TYPE.TO, 'c_ob_type')
+
+def cpython_api(argtypes, restype, error=_NOT_SPECIFIED, external=True):
+ """
+ Declares a function to be exported.
+ - `argtypes`, `restype` are lltypes and describe the function signature.
+ - `error` is the value returned when an applevel exception is raised. The
+ special value 'CANNOT_FAIL' (also when restype is Void) turns an eventual
+ exception into a wrapped SystemError. Unwrapped exceptions also cause a
+ SytemError.
+ - set `external` to False to get a C function pointer, but not exported by
+ the API headers.
+ """
+ if error is _NOT_SPECIFIED:
+ if restype is PyObject:
+ error = lltype.nullptr(restype.TO)
+ elif restype is lltype.Void:
+ error = CANNOT_FAIL
+ if type(error) is int:
+ error = rffi.cast(restype, error)
+
+ def decorate(func):
+ func_name = func.func_name
+ if external:
+ c_name = None
+ else:
+ c_name = func_name
+ api_function = ApiFunction(argtypes, restype, func, error, c_name=c_name)
+ func.api_func = api_function
+
+ if error is _NOT_SPECIFIED:
+ raise ValueError("function %s has no return value for exceptions"
+ % func)
+ def make_unwrapper(catch_exception):
+ names = api_function.argnames
+ types_names_enum_ui = unrolling_iterable(enumerate(
+ zip(api_function.argtypes,
+ [tp_name.startswith("w_") for tp_name in names])))
+
+ @specialize.ll()
+ def unwrapper(space, *args):
+ from pypy.module.cpyext.pyobject import Py_DecRef
+ from pypy.module.cpyext.pyobject import make_ref, from_ref
+ from pypy.module.cpyext.pyobject import BorrowPair
+ newargs = ()
+ to_decref = []
+ assert len(args) == len(api_function.argtypes)
+ for i, (ARG, is_wrapped) in types_names_enum_ui:
+ input_arg = args[i]
+ if is_PyObject(ARG) and not is_wrapped:
+ # build a reference
+ if input_arg is None:
+ arg = lltype.nullptr(PyObject.TO)
+ elif isinstance(input_arg, W_Root):
+ ref = make_ref(space, input_arg)
+ to_decref.append(ref)
+ arg = rffi.cast(ARG, ref)
+ else:
+ arg = input_arg
+ elif is_PyObject(ARG) and is_wrapped:
+ # convert to a wrapped object
+ if input_arg is None:
+ arg = input_arg
+ elif isinstance(input_arg, W_Root):
+ arg = input_arg
+ else:
+ arg = from_ref(space,
+ rffi.cast(PyObject, input_arg))
+ else:
+ arg = input_arg
+ newargs += (arg, )
+ try:
+ try:
+ res = func(space, *newargs)
+ except OperationError, e:
+ if not catch_exception:
+ raise
+ state = space.fromcache(State)
+ state.set_exception(e)
+ if is_PyObject(restype):
+ return None
+ else:
+ if api_function.error_value is _NOT_SPECIFIED:
+ raise
+ return api_function.error_value
+ if res is None:
+ return None
+ elif isinstance(res, BorrowPair):
+ return res.w_borrowed
+ else:
+ return res
+ finally:
+ for arg in to_decref:
+ Py_DecRef(space, arg)
+ unwrapper.func = func
+ unwrapper.api_func = api_function
+ unwrapper._always_inline_ = True
+ return unwrapper
+
+ unwrapper_catch = make_unwrapper(True)
+ unwrapper_raise = make_unwrapper(False)
+ if external:
+ FUNCTION_declare(func_name, api_function)
+ INTERPLEVEL_declare(func_name, unwrapper_catch) # used in tests
+ return unwrapper_raise # used in 'normal' RPython code.
+ return decorate
+
+# Make the wrapper for the cases (1) and (2)
+def make_wrapper(space, callable):
+ "NOT_RPYTHON"
+ names = callable.api_func.argnames
+ argtypes_enum_ui = unrolling_iterable(enumerate(zip(callable.api_func.argtypes,
+ [name.startswith("w_") for name in names])))
+ fatal_value = callable.api_func.restype._defl()
+
+ @specialize.ll()
+ def wrapper(*args):
+ from pypy.module.cpyext.pyobject import make_ref, from_ref
+ from pypy.module.cpyext.pyobject import BorrowPair
+ # we hope that malloc removal removes the newtuple() that is
+ # inserted exactly here by the varargs specializer
+ llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py
+ rffi.stackcounter.stacks_counter += 1
+ retval = fatal_value
+ boxed_args = ()
+ try:
+ if not we_are_translated() and DEBUG_WRAPPER:
+ print >>sys.stderr, callable,
+ assert len(args) == len(callable.api_func.argtypes)
+ for i, (typ, is_wrapped) in argtypes_enum_ui:
+ arg = args[i]
+ if is_PyObject(typ) and is_wrapped:
+ if arg:
+ arg_conv = from_ref(space, rffi.cast(PyObject, arg))
+ else:
+ arg_conv = None
+ else:
+ arg_conv = arg
+ boxed_args += (arg_conv, )
+ state = space.fromcache(State)
+ try:
+ result = callable(space, *boxed_args)
+ if not we_are_translated() and DEBUG_WRAPPER:
+ print >>sys.stderr, " DONE"
+ except OperationError, e:
+ failed = True
+ state.set_exception(e)
+ except BaseException, e:
+ failed = True
+ if not we_are_translated():
+ message = repr(e)
+ import traceback
+ traceback.print_exc()
+ else:
+ message = str(e)
+ state.set_exception(OperationError(space.w_SystemError,
+ space.wrap(message)))
+ else:
+ failed = False
+
+ if failed:
+ error_value = callable.api_func.error_value
+ if error_value is CANNOT_FAIL:
+ raise SystemError("The function '%s' was not supposed to fail"
+ % (callable.__name__,))
+ retval = error_value
+
+ elif is_PyObject(callable.api_func.restype):
+ if result is None:
+ retval = make_ref(space, None)
+ elif isinstance(result, BorrowPair):
+ retval = result.get_ref(space)
+ elif not rffi._isllptr(result):
+ retval = rffi.cast(callable.api_func.restype,
+ make_ref(space, result))
+ else:
+ retval = result
+ elif callable.api_func.restype is not lltype.Void:
+ retval = rffi.cast(callable.api_func.restype, result)
+ except Exception, e:
+ if not we_are_translated():
+ import traceback
+ traceback.print_exc()
+ print str(e)
+ # we can't do much here, since we're in ctypes, swallow
+ else:
+ print str(e)
+ pypy_debug_catch_fatal_exception()
+ rffi.stackcounter.stacks_counter -= 1
+ return retval
+ callable._always_inline_ = True
+ wrapper.__name__ = "wrapper for %r" % (callable, )
+ return wrapper
+
+ at specialize.ll()
+def generic_cpy_call(space, func, *args):
+ FT = lltype.typeOf(func).TO
+ return make_generic_cpy_call(FT, True, False)(space, func, *args)
+
+ at specialize.ll()
+def generic_cpy_call_dont_decref(space, func, *args):
+ FT = lltype.typeOf(func).TO
+ return make_generic_cpy_call(FT, False, False)(space, func, *args)
+
+ at specialize.ll()
+def generic_cpy_call_expect_null(space, func, *args):
+ FT = lltype.typeOf(func).TO
+ return make_generic_cpy_call(FT, True, True)(space, func, *args)
+
+ at specialize.memo()
+def make_generic_cpy_call(FT, decref_args, expect_null):
+ from pypy.module.cpyext.pyobject import make_ref, from_ref, Py_DecRef
+ from pypy.module.cpyext.pyobject import RefcountState
+ from pypy.module.cpyext.pyerrors import PyErr_Occurred
+ unrolling_arg_types = unrolling_iterable(enumerate(FT.ARGS))
+ RESULT_TYPE = FT.RESULT
+
+ # copied and modified from rffi.py
+ # We need tons of care to ensure that no GC operation and no
+ # exception checking occurs in call_external_function.
+ argnames = ', '.join(['a%d' % i for i in range(len(FT.ARGS))])
+ source = py.code.Source("""
+ def call_cpyext_external_function(funcptr, %(argnames)s):
+ # NB. it is essential that no exception checking occurs here!
+ res = funcptr(%(argnames)s)
+ return res
+ """ % locals())
+ miniglobals = {'__name__': __name__, # for module name propagation
+ }
+ exec source.compile() in miniglobals
+ call_external_function = miniglobals['call_cpyext_external_function']
+ call_external_function._dont_inline_ = True
+ call_external_function._annspecialcase_ = 'specialize:ll'
+ call_external_function._gctransformer_hint_close_stack_ = True
+ # don't inline, as a hack to guarantee that no GC pointer is alive
+ # anywhere in call_external_function
+
+ @specialize.ll()
+ def generic_cpy_call(space, func, *args):
+ boxed_args = ()
+ to_decref = []
+ assert len(args) == len(FT.ARGS)
+ for i, ARG in unrolling_arg_types:
+ arg = args[i]
+ if is_PyObject(ARG):
+ if arg is None:
+ boxed_args += (lltype.nullptr(PyObject.TO),)
+ elif isinstance(arg, W_Root):
+ ref = make_ref(space, arg)
+ boxed_args += (ref,)
+ if decref_args:
+ to_decref.append(ref)
+ else:
+ boxed_args += (arg,)
+ else:
+ boxed_args += (arg,)
+
+ try:
+ # create a new container for borrowed references
+ state = space.fromcache(RefcountState)
+ old_container = state.swap_borrow_container(None)
+ try:
+ # Call the function
+ result = call_external_function(func, *boxed_args)
+ finally:
+ state.swap_borrow_container(old_container)
+
+ if is_PyObject(RESULT_TYPE):
+ if result is None:
+ ret = result
+ elif isinstance(result, W_Root):
+ ret = result
+ else:
+ ret = from_ref(space, result)
+ # The object reference returned from a C function
+ # that is called from Python must be an owned reference
+ # - ownership is transferred from the function to its caller.
+ if result:
+ Py_DecRef(space, result)
+
+ # Check for exception consistency
+ has_error = PyErr_Occurred(space) is not None
+ has_result = ret is not None
+ if has_error and has_result:
+ raise OperationError(space.w_SystemError, space.wrap(
+ "An exception was set, but function returned a value"))
+ elif not expect_null and not has_error and not has_result:
+ raise OperationError(space.w_SystemError, space.wrap(
+ "Function returned a NULL result without setting an exception"))
+
+ if has_error:
+ state = space.fromcache(State)
+ state.check_and_raise_exception()
+
+ return ret
+ return result
+ finally:
+ if decref_args:
+ for ref in to_decref:
+ Py_DecRef(space, ref)
+ return generic_cpy_call
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/import_.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/import_.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/import_.py Wed Jun 9 17:56:49 2010
@@ -1,6 +1,6 @@
from pypy.interpreter import module
-from pypy.module.cpyext.api import (
- generic_cpy_call, cpython_api, PyObject, CONST_STRING)
+from pypy.module.cpyext.gateway import cpython_api, generic_cpy_call
+from pypy.module.cpyext.api import PyObject, CONST_STRING
from pypy.rpython.lltypesystem import rffi
from pypy.interpreter.error import OperationError
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/intobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/intobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/intobject.py Wed Jun 9 17:56:49 2010
@@ -1,8 +1,7 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import (cpython_api, PyObject, CANNOT_FAIL,
- build_type_checkers, Py_ssize_t)
-
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.api import PyObject, Py_ssize_t, build_type_checkers
PyInt_Check, PyInt_CheckExact = build_type_checkers("Int")
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/iterator.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/iterator.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/iterator.py Wed Jun 9 17:56:49 2010
@@ -1,6 +1,7 @@
from pypy.interpreter.error import OperationError
-from pypy.module.cpyext.api import (generic_cpy_call, cpython_api, PyObject,
- CANNOT_FAIL)
+from pypy.module.cpyext.gateway import (
+ generic_cpy_call, cpython_api, CANNOT_FAIL)
+from pypy.module.cpyext.pyobject import PyObject
import pypy.module.__builtin__.operation as operation
from pypy.rpython.lltypesystem import rffi
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/listobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/listobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/listobject.py Wed Jun 9 17:56:49 2010
@@ -1,7 +1,7 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import (cpython_api, CANNOT_FAIL, Py_ssize_t,
- build_type_checkers)
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.api import Py_ssize_t, build_type_checkers
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
from pypy.module.cpyext.pyobject import Py_DecRef, PyObject, borrow_from
from pypy.objspace.std.listobject import W_ListObject
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/longobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/longobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/longobject.py Wed Jun 9 17:56:49 2010
@@ -1,6 +1,7 @@
from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.module.cpyext.api import (cpython_api, PyObject, build_type_checkers,
- CONST_STRING, ADDR)
+from pypy.module.cpyext.gateway import cpython_api
+from pypy.module.cpyext.api import (
+ PyObject, CONST_STRING, ADDR, build_type_checkers)
from pypy.objspace.std.longobject import W_LongObject
from pypy.interpreter.error import OperationError
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/mapping.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/mapping.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/mapping.py Wed Jun 9 17:56:49 2010
@@ -1,6 +1,6 @@
from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.module.cpyext.api import (
- cpython_api, CANNOT_FAIL, CONST_STRING, Py_ssize_t)
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.api import CONST_STRING, Py_ssize_t
from pypy.module.cpyext.pyobject import PyObject
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/methodobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/methodobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/methodobject.py Wed Jun 9 17:56:49 2010
@@ -6,12 +6,14 @@
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.function import BuiltinFunction, Method, StaticMethod
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.pyobject import (PyObject, from_ref, make_ref,
- make_typedescr, Py_DecRef)
+from pypy.module.cpyext.pyobject import (
+ PyObject, from_ref, make_ref, make_typedescr, Py_DecRef)
+from pypy.module.cpyext.gateway import cpython_api, generic_cpy_call
from pypy.module.cpyext.api import (
- generic_cpy_call, cpython_api, PyObject, cpython_struct, METH_KEYWORDS,
- METH_O, CONST_STRING, METH_CLASS, METH_STATIC, METH_COEXIST, METH_NOARGS,
- METH_VARARGS, build_type_checkers, PyObjectFields, bootstrap_function)
+ PyObject, cpython_struct, PyObjectFields, bootstrap_function,
+ build_type_checkers, METH_KEYWORDS, METH_O, METH_CLASS,
+ METH_STATIC, METH_COEXIST, METH_NOARGS, METH_VARARGS,
+ CONST_STRING)
from pypy.module.cpyext.pyerrors import PyErr_Occurred
from pypy.rlib.objectmodel import we_are_translated
from pypy.objspace.std.tupleobject import W_TupleObject
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/modsupport.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/modsupport.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/modsupport.py Wed Jun 9 17:56:49 2010
@@ -1,6 +1,7 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import cpython_api, cpython_struct, \
- METH_STATIC, METH_CLASS, METH_COEXIST, CANNOT_FAIL, CONST_STRING
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.api import (
+ cpython_struct, METH_STATIC, METH_CLASS, METH_COEXIST, CONST_STRING)
from pypy.module.cpyext.pyobject import PyObject, borrow_from
from pypy.interpreter.module import Module
from pypy.module.cpyext.methodobject import (
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/number.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/number.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/number.py Wed Jun 9 17:56:49 2010
@@ -1,5 +1,6 @@
from pypy.interpreter.error import OperationError
-from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, Py_ssize_t
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.api import Py_ssize_t
from pypy.module.cpyext.pyobject import PyObject
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.tool.sourcetools import func_with_new_name
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/object.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/object.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/object.py Wed Jun 9 17:56:49 2010
@@ -1,8 +1,10 @@
from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.gateway import (
+ cpython_api, generic_cpy_call, CANNOT_FAIL)
from pypy.module.cpyext.api import (
- cpython_api, generic_cpy_call, CANNOT_FAIL, Py_ssize_t, Py_ssize_tP,
- PyVarObject, Py_TPFLAGS_HEAPTYPE, Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT,
- Py_GE, CONST_STRING, FILEP, fwrite)
+ Py_ssize_t, Py_ssize_tP, PyVarObject, CONST_STRING,
+ Py_TPFLAGS_HEAPTYPE, Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE,
+ FILEP, fwrite)
from pypy.module.cpyext.pyobject import (
PyObject, PyObjectP, create_ref, from_ref, Py_IncRef, Py_DecRef,
track_reference, get_typedescr, RefcountState)
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pyerrors.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pyerrors.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pyerrors.py Wed Jun 9 17:56:49 2010
@@ -2,7 +2,8 @@
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.interpreter.error import OperationError
-from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, CONST_STRING
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.api import CONST_STRING
from pypy.module.exceptions.interp_exceptions import W_RuntimeWarning
from pypy.module.cpyext.pyobject import (
PyObject, PyObjectP, make_ref, Py_DecRef, borrow_from)
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pyobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pyobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pyobject.py Wed Jun 9 17:56:49 2010
@@ -2,9 +2,11 @@
from pypy.interpreter.baseobjspace import W_Root, SpaceCache
from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.gateway import (
+ cpython_api, CANNOT_FAIL)
from pypy.module.cpyext.api import (
- cpython_api, bootstrap_function, PyObject, PyObjectP, ADDR,
- CANNOT_FAIL, Py_TPFLAGS_HEAPTYPE, PyTypeObjectPtr)
+ bootstrap_function, PyObject, PyObjectP, ADDR,
+ Py_TPFLAGS_HEAPTYPE, PyTypeObjectPtr)
from pypy.module.cpyext.state import State
from pypy.objspace.std.typeobject import W_TypeObject
from pypy.rlib.objectmodel import specialize, we_are_translated
@@ -382,7 +384,7 @@
obj.c_ob_refcnt = 1
def _Py_Dealloc(space, obj):
- from pypy.module.cpyext.api import generic_cpy_call_dont_decref
+ from pypy.module.cpyext.gateway import generic_cpy_call_dont_decref
pto = obj.c_ob_type
#print >>sys.stderr, "Calling dealloc slot", pto.c_tp_dealloc, "of", obj, \
# "'s type which is", rffi.charp2str(pto.c_tp_name)
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pystate.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pystate.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pystate.py Wed Jun 9 17:56:49 2010
@@ -1,5 +1,6 @@
-from pypy.module.cpyext.api import cpython_api, generic_cpy_call, CANNOT_FAIL,\
- cpython_struct
+from pypy.module.cpyext.gateway import (
+ cpython_api, generic_cpy_call, CANNOT_FAIL)
+from pypy.module.cpyext.api import cpython_struct
from pypy.rpython.lltypesystem import rffi, lltype
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pythonrun.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pythonrun.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/pythonrun.py Wed Jun 9 17:56:49 2010
@@ -1,5 +1,5 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
@cpython_api([], rffi.INT_real, error=CANNOT_FAIL)
def Py_IsInitialized(space):
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/sequence.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/sequence.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/sequence.py Wed Jun 9 17:56:49 2010
@@ -1,7 +1,7 @@
from pypy.interpreter.error import OperationError
-from pypy.module.cpyext.api import (
- cpython_api, CANNOT_FAIL, CONST_STRING, Py_ssize_t)
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.api import CONST_STRING, Py_ssize_t
from pypy.module.cpyext.pyobject import PyObject, borrow_from
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.objspace.std import listobject, tupleobject
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/sliceobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/sliceobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/sliceobject.py Wed Jun 9 17:56:49 2010
@@ -1,7 +1,8 @@
from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
from pypy.module.cpyext.api import (
- cpython_api, cpython_struct, bootstrap_function, build_type_checkers,
- CANNOT_FAIL, Py_ssize_t, Py_ssize_tP, PyObjectFields)
+ cpython_struct, build_type_checkers, bootstrap_function,
+ Py_ssize_t, Py_ssize_tP, PyObjectFields)
from pypy.module.cpyext.pyobject import (
Py_DecRef, PyObject, make_ref, make_typedescr)
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/slotdefs.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/slotdefs.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/slotdefs.py Wed Jun 9 17:56:49 2010
@@ -1,7 +1,9 @@
import re
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import generic_cpy_call, cpython_api, PyObject
+from pypy.module.cpyext.gateway import (
+ cpython_api, generic_cpy_call, generic_cpy_call_expect_null)
+from pypy.module.cpyext.pyobject import PyObject
from pypy.module.cpyext.typeobjectdefs import (
unaryfunc, wrapperfunc, ternaryfunc, PyTypeObjectPtr, binaryfunc,
getattrfunc, setattrofunc, lenfunc, ssizeargfunc, ssizessizeargfunc,
@@ -165,7 +167,6 @@
return generic_cpy_call(space, func_target, w_self, start, end)
def wrap_next(space, w_self, w_args, func):
- from pypy.module.cpyext.api import generic_cpy_call_expect_null
func_target = rffi.cast(iternextfunc, func)
check_num_args(space, w_args, 0)
w_res = generic_cpy_call_expect_null(space, func_target, w_self)
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/stringobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/stringobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/stringobject.py Wed Jun 9 17:56:49 2010
@@ -1,7 +1,8 @@
from pypy.interpreter.error import OperationError
from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.gateway import cpython_api
from pypy.module.cpyext.api import (
- cpython_api, cpython_struct, bootstrap_function, build_type_checkers,
+ cpython_struct, build_type_checkers, bootstrap_function,
PyObjectFields, Py_ssize_t, CONST_STRING)
from pypy.module.cpyext.pyobject import (
PyObject, PyObjectP, Py_DecRef, make_ref, from_ref, track_reference,
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/structmember.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/structmember.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/structmember.py Wed Jun 9 17:56:49 2010
@@ -2,7 +2,8 @@
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.module.cpyext import structmemberdefs
-from pypy.module.cpyext.api import ADDR, PyObjectP, cpython_api
+from pypy.module.cpyext.api import ADDR, PyObjectP
+from pypy.module.cpyext.gateway import cpython_api
from pypy.module.cpyext.intobject import PyInt_AsLong, PyInt_AsUnsignedLong
from pypy.module.cpyext.pyerrors import PyErr_Occurred
from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, from_ref, make_ref
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/stubsactive.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/stubsactive.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/stubsactive.py Wed Jun 9 17:56:49 2010
@@ -1,5 +1,6 @@
from pypy.module.cpyext.pyobject import PyObject
-from pypy.module.cpyext.api import cpython_api, Py_ssize_t, CANNOT_FAIL, CConfig
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.api import Py_ssize_t, CConfig
from pypy.module.cpyext.object import FILEP
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.module.cpyext.pystate import PyThreadState, PyInterpreterState
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/sysmodule.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/sysmodule.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/sysmodule.py Wed Jun 9 17:56:49 2010
@@ -1,6 +1,7 @@
from pypy.interpreter.error import OperationError
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import CANNOT_FAIL, cpython_api, CONST_STRING
+from pypy.module.cpyext.gateway import CANNOT_FAIL, cpython_api
+from pypy.module.cpyext.api import CONST_STRING
from pypy.module.cpyext.pyobject import PyObject, borrow_from
@cpython_api([CONST_STRING], PyObject, error=CANNOT_FAIL)
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_api.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_api.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_api.py Wed Jun 9 17:56:49 2010
@@ -1,18 +1,19 @@
from pypy.conftest import gettestobjspace
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.interpreter.baseobjspace import W_Root
+from pypy.module.cpyext.api import INTERPLEVEL_API
from pypy.module.cpyext.state import State
-from pypy.module.cpyext import api
+from pypy.module.cpyext.gateway import cpython_api
+from pypy.module.cpyext.pyobject import PyObject
from pypy.module.cpyext.test.test_cpyext import freeze_refcnts, LeakCheckingTest
-PyObject = api.PyObject
from pypy.interpreter.error import OperationError
from pypy.module.cpyext.state import State
import os
- at api.cpython_api([PyObject], lltype.Void)
+ at cpython_api([PyObject], lltype.Void)
def PyPy_GetWrapped(space, w_arg):
assert isinstance(w_arg, W_Root)
- at api.cpython_api([PyObject], lltype.Void)
+ at cpython_api([PyObject], lltype.Void)
def PyPy_GetReference(space, arg):
assert lltype.typeOf(arg) == PyObject
@@ -36,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)
def raises(self, space, api, expected_exc, f, *args):
if not callable(f):
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_borrow.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_borrow.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_borrow.py Wed Jun 9 17:56:49 2010
@@ -31,6 +31,7 @@
g = PyTuple_GetItem(t, 0); // borrows reference again
printf("Refcnt4: %i\\n", f->ob_refcnt);
printf("COMPARE: %i\\n", f == g);
+ fflush(stdout);
Py_DECREF(t);
Py_RETURN_TRUE;
"""),
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_cpyext.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_cpyext.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_cpyext.py Wed Jun 9 17:56:49 2010
@@ -11,17 +11,18 @@
from pypy.translator.gensupp import uniquemodulename
from pypy.tool.udir import udir
from pypy.module.cpyext import api
+from pypy.module.cpyext.gateway import cpython_api
from pypy.module.cpyext.state import State
from pypy.module.cpyext.pyobject import RefcountState
from pypy.module.cpyext.pyobject import Py_DecRef, InvalidPointerException
from pypy.translator.goal import autopath
from pypy.lib.identity_dict import identity_dict
- at api.cpython_api([], api.PyObject)
+ at cpython_api([], api.PyObject)
def PyPy_Crash1(space):
1/0
- at api.cpython_api([], lltype.Signed, error=-1)
+ at cpython_api([], lltype.Signed, error=-1)
def PyPy_Crash2(space):
1/0
@@ -533,6 +534,7 @@
Py_DECREF(true);
Py_DECREF(true);
fprintf(stderr, "REFCNT %i %i\\n", refcnt, refcnt_after);
+ fflush(stderr);
return PyBool_FromLong(refcnt_after == refcnt+2 && refcnt < 3);
}
static PyObject* foo_bar(PyObject* self, PyObject *args)
@@ -549,6 +551,7 @@
refcnt_after = true->ob_refcnt;
Py_DECREF(tup);
fprintf(stderr, "REFCNT2 %i %i\\n", refcnt, refcnt_after);
+ fflush(stderr);
return PyBool_FromLong(refcnt_after == refcnt);
}
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_methodobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_methodobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_methodobject.py Wed Jun 9 17:56:49 2010
@@ -73,7 +73,7 @@
"""
def func(space, w_self, w_args):
return space.w_None
- c_func = ApiFunction([PyObject, PyObject], PyObject, func)
+ c_func = ApiFunction([PyObject, PyObject], PyObject, func, error=None)
func.api_func = c_func
ml = lltype.malloc(PyMethodDef, flavor='raw', zero=True)
namebuf = rffi.str2charp('func')
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_translate.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_translate.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/test/test_translate.py Wed Jun 9 17:56:49 2010
@@ -1,6 +1,6 @@
from pypy.translator.c.test.test_genc import compile
-import pypy.module.cpyext.api
-from pypy.module.cpyext.api import cpython_api
+import pypy.module.cpyext.gateway
+from pypy.module.cpyext.gateway import cpython_api
from pypy.rpython.annlowlevel import llhelper
from pypy.rpython.lltypesystem import lltype
from pypy.rlib.objectmodel import specialize
@@ -15,7 +15,7 @@
def wrapper():
return func(space)
return wrapper
- monkeypatch.setattr(pypy.module.cpyext.api, 'make_wrapper', make_wrapper)
+ monkeypatch.setattr(pypy.module.cpyext.gateway, 'make_wrapper', make_wrapper)
@specialize.memo()
def get_tp_function(space, typedef):
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/thread.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/thread.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/thread.py Wed Jun 9 17:56:49 2010
@@ -1,6 +1,6 @@
from pypy.module.thread import ll_thread
-from pypy.module.cpyext.api import CANNOT_FAIL, cpython_api
+from pypy.module.cpyext.gateway import CANNOT_FAIL, cpython_api
from pypy.rpython.lltypesystem import rffi
@cpython_api([], rffi.LONG, error=CANNOT_FAIL)
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/tupleobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/tupleobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/tupleobject.py Wed Jun 9 17:56:49 2010
@@ -1,9 +1,9 @@
from pypy.interpreter.error import OperationError
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import (cpython_api, Py_ssize_t, CANNOT_FAIL,
- build_type_checkers)
-from pypy.module.cpyext.pyobject import (PyObject, PyObjectP, Py_DecRef,
- borrow_from, make_ref, from_ref)
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
+from pypy.module.cpyext.api import Py_ssize_t, build_type_checkers
+from pypy.module.cpyext.pyobject import (
+ PyObject, PyObjectP, Py_DecRef, borrow_from, make_ref, from_ref)
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
from pypy.objspace.std.tupleobject import W_TupleObject
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/typeobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/typeobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/typeobject.py Wed Jun 9 17:56:49 2010
@@ -6,11 +6,13 @@
from pypy.interpreter.baseobjspace import DescrMismatch
from pypy.objspace.std.typeobject import W_TypeObject, _CPYTYPE
from pypy.interpreter.typedef import GetSetProperty
+from pypy.module.cpyext.gateway import (
+ cpython_api, generic_cpy_call, CANNOT_FAIL)
from pypy.module.cpyext.api import (
- cpython_api, cpython_struct, bootstrap_function, Py_ssize_t,
- generic_cpy_call, Py_TPFLAGS_READY, Py_TPFLAGS_READYING,
- Py_TPFLAGS_HEAPTYPE, METH_VARARGS, METH_KEYWORDS, CANNOT_FAIL,
- PyBufferProcs, build_type_checkers)
+ cpython_struct, build_type_checkers, bootstrap_function,
+ Py_ssize_t, PyBufferProcs, Py_TPFLAGS_READY, Py_TPFLAGS_READYING,
+ Py_TPFLAGS_HEAPTYPE, METH_VARARGS, METH_KEYWORDS)
+
from pypy.module.cpyext.pyobject import (
PyObject, make_ref, create_ref, from_ref, get_typedescr, make_typedescr,
track_reference, RefcountState, borrow_from)
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/unicodeobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/unicodeobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/unicodeobject.py Wed Jun 9 17:56:49 2010
@@ -1,10 +1,10 @@
from pypy.interpreter.error import OperationError
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.module.unicodedata import unicodedb_4_1_0 as unicodedb
+from pypy.module.cpyext.gateway import cpython_api, CANNOT_FAIL
from pypy.module.cpyext.api import (
- CANNOT_FAIL, Py_ssize_t, build_type_checkers, cpython_api,
- bootstrap_function, PyObjectFields, cpython_struct, CONST_STRING,
- CONST_WSTRING)
+ cpython_struct, build_type_checkers, bootstrap_function,
+ PyObjectFields, Py_ssize_t, CONST_STRING, CONST_WSTRING)
from pypy.module.cpyext.pyerrors import PyErr_BadArgument
from pypy.module.cpyext.pyobject import PyObject, from_ref, make_typedescr
from pypy.module.sys.interp_encoding import setdefaultencoding
Modified: pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/weakrefobject.py
==============================================================================
--- pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/weakrefobject.py (original)
+++ pypy/branch/cpyext-init-cleanup/pypy/module/cpyext/weakrefobject.py Wed Jun 9 17:56:49 2010
@@ -1,4 +1,4 @@
-from pypy.module.cpyext.api import cpython_api
+from pypy.module.cpyext.gateway import cpython_api
from pypy.module.cpyext.pyobject import PyObject, borrow_from
from pypy.module._weakref.interp__weakref import W_Weakref
More information about the Pypy-commit
mailing list