[pypy-svn] r75192 - in pypy/trunk/pypy/module/cpyext: . include test
afa at codespeak.net
afa at codespeak.net
Tue Jun 8 14:58:56 CEST 2010
Author: afa
Date: Tue Jun 8 14:58:54 2010
New Revision: 75192
Modified:
pypy/trunk/pypy/module/cpyext/api.py
pypy/trunk/pypy/module/cpyext/datetime.py
pypy/trunk/pypy/module/cpyext/include/datetime.h
pypy/trunk/pypy/module/cpyext/test/test_datetime.py
Log:
Add the PyDateTime_CAPI structure, that holds common types from the datetime module.
2 caveats:
- the datetime module is now pre-loaded in pypy-c
- api.py really needs some refactoring.
Modified: pypy/trunk/pypy/module/cpyext/api.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/api.py (original)
+++ pypy/trunk/pypy/module/cpyext/api.py Tue Jun 8 14:58:54 2010
@@ -315,6 +315,7 @@
'_Py_TrueStruct#': ('PyObject*', 'space.w_True'),
'_Py_ZeroStruct#': ('PyObject*', 'space.w_False'),
'_Py_NotImplementedStruct#': ('PyObject*', 'space.w_NotImplemented'),
+ 'PyDateTimeAPI': ('PyDateTime_CAPI*', 'cpyext.datetime.build_datetime_api(space)'),
}
FORWARD_DECLS = []
INIT_FUNCTIONS = []
@@ -360,7 +361,9 @@
def get_structtype_for_ctype(ctype):
from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr
- return {"PyObject*": PyObject, "PyTypeObject*": PyTypeObjectPtr}[ctype]
+ from pypy.module.cpyext.datetime import PyDateTime_CAPI
+ return {"PyObject*": PyObject, "PyTypeObject*": PyTypeObjectPtr,
+ "PyDateTime_CAPI*": lltype.Ptr(PyDateTime_CAPI)}[ctype]
PyTypeObject = lltype.ForwardReference()
PyTypeObjectPtr = lltype.Ptr(PyTypeObject)
@@ -506,13 +509,14 @@
% (callable.__name__,))
retval = error_value
- elif callable.api_func.restype is PyObject:
+ 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 = make_ref(space, result)
+ retval = rffi.cast(callable.api_func.restype,
+ make_ref(space, result))
else:
retval = result
elif callable.api_func.restype is not lltype.Void:
@@ -612,8 +616,10 @@
for name, (typ, expr) in GLOBALS.iteritems():
if "#" in name:
continue
- if name.startswith('PyExc_'):
- global_objects.append('%s %s;' % (typ[:-1], '_' + name))
+ if typ == 'PyDateTime_CAPI*':
+ global_objects.append('%s _%s;' % (typ, name))
+ elif name.startswith('PyExc_'):
+ global_objects.append('%s _%s;' % (typ[:-1], name))
else:
global_objects.append('%s %s = NULL;' % (typ, name))
global_code = '\n'.join(global_objects)
@@ -653,7 +659,13 @@
name = name.replace('Py', 'PyPy')
if isptr:
ptr = ctypes.c_void_p.in_dll(bridge, name)
- ptr.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, w_obj)),
+ if typ == 'PyObject*':
+ value = make_ref(space, w_obj)
+ elif typ == 'PyDateTime_CAPI*':
+ value = w_obj
+ else:
+ assert False, "Unknown static pointer: %s %s" % (typ, name)
+ ptr.value = ctypes.cast(ll2ctypes.lltype2ctypes(value),
ctypes.c_void_p).value
elif typ in ('PyObject*', 'PyTypeObject*'):
if name.startswith('PyPyExc_'):
@@ -804,6 +816,9 @@
elif name.startswith('PyExc_'):
structs.append('extern PyTypeObject _%s;' % (name,))
structs.append('PyObject* %s = (PyObject*)&_%s;' % (name, name))
+ elif typ == 'PyDateTime_CAPI*':
+ structs.append('extern %s _%s;' % (typ[:-1], name))
+ structs.append('%s %s = &_%s;' % (typ, name, name))
struct_file.write('\n'.join(structs))
eci = ExternalCompilationInfo(
@@ -853,7 +868,13 @@
name = '_' + name
from pypy.module import cpyext
w_obj = eval(expr)
- struct_ptr = make_ref(space, w_obj)
+ if typ in ('PyObject*', 'PyTypeObject*'):
+ struct_ptr = make_ref(space, w_obj)
+ elif typ == 'PyDateTime_CAPI*':
+ struct_ptr = w_obj
+ name = '_' + name
+ else:
+ assert False, "Unknown static data: %s %s" % (typ, name)
struct = rffi.cast(get_structtype_for_ctype(typ), struct_ptr)._obj
struct._compilation_info = eci
export_struct(name, struct)
@@ -946,7 +967,7 @@
assert len(args) == len(FT.ARGS)
for i, ARG in unrolling_arg_types:
arg = args[i]
- if ARG is PyObject:
+ if is_PyObject(ARG):
if arg is None:
boxed_args += (lltype.nullptr(PyObject.TO),)
elif isinstance(arg, W_Root):
@@ -969,7 +990,7 @@
finally:
state.swap_borrow_container(old_container)
- if RESULT_TYPE is PyObject:
+ if is_PyObject(RESULT_TYPE):
if result is None:
ret = result
elif isinstance(result, W_Root):
Modified: pypy/trunk/pypy/module/cpyext/datetime.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/datetime.py (original)
+++ pypy/trunk/pypy/module/cpyext/datetime.py Tue Jun 8 14:58:54 2010
@@ -1,14 +1,42 @@
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.pyobject import PyObject
+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.import_ import PyImport_Import
+from pypy.module.cpyext.typeobject import PyTypeObjectPtr
from pypy.interpreter.error import OperationError
from pypy.tool.sourcetools import func_renamer
# API import function
- at cpython_api([], lltype.Void)
+PyDateTime_CAPI = cpython_struct(
+ 'PyDateTime_CAPI',
+ (('DateType', PyTypeObjectPtr),
+ ('DateTimeType', PyTypeObjectPtr),
+ ('TimeType', PyTypeObjectPtr),
+ ('DeltaType', PyTypeObjectPtr),
+ ))
+
+def build_datetime_api(space):
+ w_datetime = PyImport_Import(space, space.wrap("datetime"))
+ datetimeAPI = lltype.malloc(PyDateTime_CAPI, flavor='raw')
+
+ w_type = space.getattr(w_datetime, space.wrap("date"))
+ datetimeAPI.c_DateType = rffi.cast(
+ PyTypeObjectPtr, make_ref(space, w_type))
+ w_type = space.getattr(w_datetime, space.wrap("datetime"))
+ datetimeAPI.c_DateTimeType = rffi.cast(
+ PyTypeObjectPtr, make_ref(space, w_type))
+ w_type = space.getattr(w_datetime, space.wrap("time"))
+ datetimeAPI.c_TimeType = rffi.cast(
+ PyTypeObjectPtr, make_ref(space, w_type))
+ w_type = space.getattr(w_datetime, space.wrap("timedelta"))
+ datetimeAPI.c_DeltaType = rffi.cast(
+ PyTypeObjectPtr, make_ref(space, w_type))
+
+ return datetimeAPI
+
+ at cpython_api([], PyObject)
def _PyDateTime_Import(space):
return
Modified: pypy/trunk/pypy/module/cpyext/include/datetime.h
==============================================================================
--- pypy/trunk/pypy/module/cpyext/include/datetime.h (original)
+++ pypy/trunk/pypy/module/cpyext/include/datetime.h Tue Jun 8 14:58:54 2010
@@ -4,6 +4,16 @@
extern "C" {
#endif
+/* Define structure for C API. */
+typedef struct {
+ /* type objects */
+ PyTypeObject *DateType;
+ PyTypeObject *DateTimeType;
+ PyTypeObject *TimeType;
+ PyTypeObject *DeltaType;
+} PyDateTime_CAPI;
+
+PyAPI_DATA(PyDateTime_CAPI*) PyDateTimeAPI;
#define PyDateTime_IMPORT _PyDateTime_Import()
typedef struct {
Modified: pypy/trunk/pypy/module/cpyext/test/test_datetime.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/test_datetime.py (original)
+++ pypy/trunk/pypy/module/cpyext/test/test_datetime.py Tue Jun 8 14:58:54 2010
@@ -79,3 +79,21 @@
w_date = api.PyDateTime_FromTimestamp(w_args)
date = datetime.datetime.fromtimestamp(0)
assert space.unwrap(space.str(w_date)) == str(date)
+
+class AppTestDatetime(AppTestCpythonExtensionBase):
+ def test_CAPI(self):
+ module = self.import_extension('foo', [
+ ("get_types", "METH_NOARGS",
+ """
+ return PyTuple_Pack(4,
+ PyDateTimeAPI->DateType,
+ PyDateTimeAPI->DateTimeType,
+ PyDateTimeAPI->TimeType,
+ PyDateTimeAPI->DeltaType);
+ """),
+ ])
+ import datetime
+ assert module.get_types() == (datetime.date,
+ datetime.datetime,
+ datetime.time,
+ datetime.timedelta)
More information about the Pypy-commit
mailing list