[pypy-svn] r72423 - in pypy/trunk/pypy/module/cpyext: . include test
afa at codespeak.net
afa at codespeak.net
Fri Mar 19 20:20:23 CET 2010
Author: afa
Date: Fri Mar 19 20:20:21 2010
New Revision: 72423
Added:
pypy/trunk/pypy/module/cpyext/floatobject.py (contents, props changed)
pypy/trunk/pypy/module/cpyext/include/floatobject.h
pypy/trunk/pypy/module/cpyext/include/methodobject.h
Modified:
pypy/trunk/pypy/module/cpyext/__init__.py
pypy/trunk/pypy/module/cpyext/api.py
pypy/trunk/pypy/module/cpyext/include/Python.h
pypy/trunk/pypy/module/cpyext/include/modsupport.h
pypy/trunk/pypy/module/cpyext/modsupport.py
pypy/trunk/pypy/module/cpyext/test/test_cpyext.py
Log:
Start to iterate over the PyMethodDef array,
this needed some support for "configure".
Next step: really expose the function object.
Modified: pypy/trunk/pypy/module/cpyext/__init__.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/__init__.py (original)
+++ pypy/trunk/pypy/module/cpyext/__init__.py Fri Mar 19 20:20:21 2010
@@ -27,7 +27,8 @@
space.wrap(state.api_lib))
# import these modules to register api functions by side-effect
+import pypy.module.cpyext.floatobject
import pypy.module.cpyext.modsupport
import pypy.module.cpyext.pythonrun
-
-
+from pypy.module.cpyext import api
+api.configure()
Modified: pypy/trunk/pypy/module/cpyext/api.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/api.py (original)
+++ pypy/trunk/pypy/module/cpyext/api.py Fri Mar 19 20:20:21 2010
@@ -1,10 +1,22 @@
from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rpython.tool import rffi_platform
from pypy.rpython.lltypesystem import ll2ctypes
from pypy.rpython.annlowlevel import llhelper
from pypy.translator.c.database import LowLevelDatabase
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.translator import platform
+import py, autopath
+
+include_dir = py.path.local(autopath.pypydir).join(
+ 'module', 'cpyext', 'include')
+
+class CConfig:
+ _compilation_info_ = ExternalCompilationInfo(
+ include_dirs=[include_dir],
+ includes=['Python.h']
+ )
+
class ApiFunction:
def __init__(self, argtypes, restype, callable):
self.argtypes = argtypes
@@ -18,14 +30,21 @@
return func
return decorate
-def cpython_struct(name):
- struct = rffi.CStruct('PyMethodDef')
- TYPES[name] = struct
- return struct
+def cpython_struct(name, fields):
+ setattr(CConfig, name, rffi_platform.Struct(name, fields))
+ forward = lltype.ForwardReference()
+ TYPES[name] = forward
+ return forward
FUNCTIONS = {}
TYPES = {}
+PyObject = cpython_struct('PyObject', [])
+
+def configure():
+ for name, TYPE in rffi_platform.configure(CConfig).iteritems():
+ TYPES[name].become(TYPE)
+
#_____________________________________________________
# Build the bridge DLL, Allow extension DLLs to call
# back into Pypy space functions
@@ -42,6 +61,7 @@
structindex[name] = len(structindex)
structmembers = '\n'.join(members)
struct_declaration_code = """\
+ #include <Python.h>
struct PyPyAPI {
%(members)s
} _pypyAPI;
@@ -67,6 +87,7 @@
# Build code and get pointer to the structure
eci = ExternalCompilationInfo(
+ include_dirs=[include_dir],
separate_module_sources=[code],
export_symbols=['pypyAPI'] + list(FUNCTIONS),
)
Added: pypy/trunk/pypy/module/cpyext/floatobject.py
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/module/cpyext/floatobject.py Fri Mar 19 20:20:21 2010
@@ -0,0 +1,6 @@
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.api import cpython_api, PyObject
+
+ at cpython_api([lltype.Float], lltype.Ptr(PyObject))
+def PyFloat_FromDouble(space, value):
+ return space.wrap(value)
Modified: pypy/trunk/pypy/module/cpyext/include/Python.h
==============================================================================
--- pypy/trunk/pypy/module/cpyext/include/Python.h (original)
+++ pypy/trunk/pypy/module/cpyext/include/Python.h Fri Mar 19 20:20:21 2010
@@ -1,7 +1,15 @@
#ifndef Py_PYTHON_H
#define Py_PYTHON_H
+typedef struct _object {
+ int __dummy;
+} PyObject;
+
#include <stdio.h>
+
+#include "floatobject.h"
+#include "methodobject.h"
+
#include "modsupport.h"
#include "pythonrun.h"
Added: pypy/trunk/pypy/module/cpyext/include/floatobject.h
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/module/cpyext/include/floatobject.h Fri Mar 19 20:20:21 2010
@@ -0,0 +1,16 @@
+
+/* Float object interface */
+
+#ifndef Py_FLOATOBJECT_H
+#define Py_FLOATOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+PyObject* PyFloat_FromDouble(double);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_FLOATOBJECT_H */
Added: pypy/trunk/pypy/module/cpyext/include/methodobject.h
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/module/cpyext/include/methodobject.h Fri Mar 19 20:20:21 2010
@@ -0,0 +1,36 @@
+
+/* Method object interface */
+
+#ifndef Py_METHODOBJECT_H
+#define Py_METHODOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
+typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *,
+ PyObject *);
+typedef PyObject *(*PyNoArgsFunction)(PyObject *);
+
+struct PyMethodDef {
+ const char *ml_name; /* The name of the built-in function/method */
+ PyCFunction ml_meth; /* The C function that implements it */
+ int ml_flags; /* Combination of METH_xxx flags, which mostly
+ describe the args expected by the C func */
+ const char *ml_doc; /* The __doc__ attribute, or NULL */
+};
+typedef struct PyMethodDef PyMethodDef;
+
+/* Flag passed to newmethodobject */
+#define METH_OLDARGS 0x0000
+#define METH_VARARGS 0x0001
+#define METH_KEYWORDS 0x0002
+/* METH_NOARGS and METH_O must not be combined with the flags above. */
+#define METH_NOARGS 0x0004
+#define METH_O 0x0008
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_METHODOBJECT_H */
Modified: pypy/trunk/pypy/module/cpyext/include/modsupport.h
==============================================================================
--- pypy/trunk/pypy/module/cpyext/include/modsupport.h (original)
+++ pypy/trunk/pypy/module/cpyext/include/modsupport.h Fri Mar 19 20:20:21 2010
@@ -1,2 +1,15 @@
-typedef struct PyMethodDef PyMethodDef;
+
+/* Module support interface */
+
+#ifndef Py_MODSUPPORT_H
+#define Py_MODSUPPORT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void Py_InitModule(const char* name, PyMethodDef* methods);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_MODSUPPORT_H */
Modified: pypy/trunk/pypy/module/cpyext/modsupport.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/modsupport.py (original)
+++ pypy/trunk/pypy/module/cpyext/modsupport.py Fri Mar 19 20:20:21 2010
@@ -2,7 +2,10 @@
from pypy.module.cpyext.api import cpython_api, cpython_struct
from pypy.interpreter.module import Module
-PyMethodDef = cpython_struct('PyMethodDef')
+PyMethodDef = cpython_struct(
+ 'PyMethodDef',
+ [('ml_name', rffi.CCHARP),
+ ])
def PyImport_AddModule(space, name):
w_name = space.wrap(name)
@@ -15,5 +18,15 @@
@cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef)], lltype.Void)
def Py_InitModule(space, name, methods):
name = rffi.charp2str(name)
- PyImport_AddModule(space, name)
- assert not methods # For the moment
+ w_mod = PyImport_AddModule(space, name)
+ methods = rffi.cast(rffi.CArrayPtr(PyMethodDef), methods)
+ if methods:
+ i = 0
+ while True:
+ method = methods[i]
+ if not method.c_ml_name: break
+ methodname = rffi.charp2str(method.c_ml_name)
+ space.setattr(w_mod,
+ space.wrap(methodname),
+ space.w_None) # XXX for the moment
+ i = i + 1
Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original)
+++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Fri Mar 19 20:20:21 2010
@@ -46,6 +46,9 @@
import ctypes
initfunc = ctypes.CDLL(mod)['init%s' % (name,)]
initfunc()
+ return self.space.getitem(
+ self.space.sys.get('modules'),
+ self.space.wrap(name))
def setup_method(self, func):
self.w_import_module = self.space.wrap(self.import_module)
@@ -65,3 +68,24 @@
"""
self.import_module(name='foo', init=init)
assert 'foo' in sys.modules
+
+ def test_export_function(self):
+ import sys
+ init = """
+ if (Py_IsInitialized())
+ Py_InitModule("foo", methods);
+ """
+ body = """
+ PyObject* foo_pi(PyObject* self, PyObject *args)
+ {
+ return PyFloat_FromDouble(3.14);
+ }
+ static PyMethodDef methods[] = {
+ { "return_pi", foo_pi, METH_NOARGS },
+ { NULL }
+ };
+ """
+ module = self.import_module(name='foo', init=init, body=body)
+ assert 'foo' in sys.modules
+ assert 'return_pi' in dir(module)
+ assert module.return_pi is None # XXX for the moment
More information about the Pypy-commit
mailing list