[pypy-svn] r72470 - in pypy/trunk/pypy/module/cpyext: . include test
xoraxax at codespeak.net
xoraxax at codespeak.net
Sat Mar 20 19:42:37 CET 2010
Author: xoraxax
Date: Sat Mar 20 19:42:35 2010
New Revision: 72470
Added:
pypy/trunk/pypy/module/cpyext/include/descrobject.h
pypy/trunk/pypy/module/cpyext/include/object.h
pypy/trunk/pypy/module/cpyext/include/stringobject.h
pypy/trunk/pypy/module/cpyext/object.py
pypy/trunk/pypy/module/cpyext/stringobject.py
pypy/trunk/pypy/module/cpyext/test/foo.c
pypy/trunk/pypy/module/cpyext/test/test_typeobject.py
pypy/trunk/pypy/module/cpyext/typeobject.py
Modified:
pypy/trunk/pypy/module/cpyext/__init__.py
pypy/trunk/pypy/module/cpyext/api.py
pypy/trunk/pypy/module/cpyext/include/Python.h
Log:
Intermediary checkin, added foo.c which is a simple module with a type object, added pytypeobject and dependencies to the header files.
Modified: pypy/trunk/pypy/module/cpyext/__init__.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/__init__.py (original)
+++ pypy/trunk/pypy/module/cpyext/__init__.py Sat Mar 20 19:42:35 2010
@@ -31,4 +31,6 @@
import pypy.module.cpyext.pythonrun
import pypy.module.cpyext.macros
import pypy.module.cpyext.pyerrors
+import pypy.module.cpyext.typeobject
+import pypy.module.cpyext.object
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 Sat Mar 20 19:42:35 2010
@@ -14,6 +14,7 @@
from pypy.module.cpyext.state import State
from pypy.interpreter.error import OperationError
+Py_ssize_t = lltype.Signed
include_dirs = [
py.path.local(autopath.pypydir).join('module', 'cpyext', 'include'),
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 Sat Mar 20 19:42:35 2010
@@ -1,9 +1,12 @@
#ifndef Py_PYTHON_H
#define Py_PYTHON_H
-typedef struct _object {
- long refcnt;
-} PyObject;
+#include <inttypes.h>
+#include <stdint.h>
+typedef long Py_ssize_t;
+#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
+
+#include "object.h"
extern PyObject *PyPy_None;
#define Py_None PyPy_None
@@ -17,5 +20,7 @@
#include "modsupport.h"
#include "pythonrun.h"
#include "pyerrors.h"
+#include "stringobject.h"
+#include "descrobject.h"
#endif
Added: pypy/trunk/pypy/module/cpyext/include/descrobject.h
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/module/cpyext/include/descrobject.h Sat Mar 20 19:42:35 2010
@@ -0,0 +1,15 @@
+#ifndef Py_DESCROBJECT_H
+#define Py_DESCROBJECT_H
+typedef PyObject *(*getter)(PyObject *, void *);
+typedef int (*setter)(PyObject *, PyObject *, void *);
+
+typedef struct PyGetSetDef {
+ char *name;
+ getter get;
+ setter set;
+ char *doc;
+ void *closure;
+} PyGetSetDef;
+
+
+#endif
Added: pypy/trunk/pypy/module/cpyext/include/object.h
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/module/cpyext/include/object.h Sat Mar 20 19:42:35 2010
@@ -0,0 +1,381 @@
+#ifndef Py_OBJECT_H
+#define Py_OBJECT_H
+
+#include <stdio.h>
+
+typedef struct _object {
+ long refcnt;
+} PyObject;
+
+typedef void* Py_buffer;
+
+#define PyObject_HEAD \
+ long refcnt;
+
+#define PyObject_VAR_HEAD \
+ PyObject_HEAD \
+ Py_ssize_t ob_size; /* Number of items in variable part */
+
+#define PyObject_HEAD_INIT(type) \
+ 1, /* XXX type, */
+
+#define PyVarObject_HEAD_INIT(type, size) \
+ PyObject_HEAD_INIT(type) size,
+
+
+extern PyObject *PyPy_None;
+#define Py_None PyPy_None
+
+struct _typeobject;
+typedef void (*freefunc)(void *);
+typedef void (*destructor)(PyObject *);
+typedef int (*printfunc)(PyObject *, FILE *, int);
+typedef PyObject *(*getattrfunc)(PyObject *, char *);
+typedef PyObject *(*getattrofunc)(PyObject *, PyObject *);
+typedef int (*setattrfunc)(PyObject *, char *, PyObject *);
+typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *);
+typedef int (*cmpfunc)(PyObject *, PyObject *);
+typedef PyObject *(*reprfunc)(PyObject *);
+typedef long (*hashfunc)(PyObject *);
+typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
+typedef PyObject *(*getiterfunc) (PyObject *);
+typedef PyObject *(*iternextfunc) (PyObject *);
+typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *);
+typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *);
+typedef int (*initproc)(PyObject *, PyObject *, PyObject *);
+typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *);
+typedef PyObject *(*allocfunc)(struct _typeobject *, Py_ssize_t);
+
+typedef PyObject * (*unaryfunc)(PyObject *);
+typedef PyObject * (*binaryfunc)(PyObject *, PyObject *);
+typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
+typedef int (*inquiry)(PyObject *);
+typedef Py_ssize_t (*lenfunc)(PyObject *);
+typedef int (*coercion)(PyObject **, PyObject **);
+typedef PyObject *(*intargfunc)(PyObject *, int) Py_DEPRECATED(2.5);
+typedef PyObject *(*intintargfunc)(PyObject *, int, int) Py_DEPRECATED(2.5);
+typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t);
+typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t);
+typedef int(*intobjargproc)(PyObject *, int, PyObject *);
+typedef int(*intintobjargproc)(PyObject *, int, int, PyObject *);
+typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *);
+typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
+typedef int(*objobjargproc)(PyObject *, PyObject *, PyObject *);
+
+
+/* int-based buffer interface */
+typedef int (*getreadbufferproc)(PyObject *, int, void **);
+typedef int (*getwritebufferproc)(PyObject *, int, void **);
+typedef int (*getsegcountproc)(PyObject *, int *);
+typedef int (*getcharbufferproc)(PyObject *, int, char **);
+/* ssize_t-based buffer interface */
+typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **);
+typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **);
+typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *);
+typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **);
+
+typedef int (*objobjproc)(PyObject *, PyObject *);
+typedef int (*visitproc)(PyObject *, void *);
+typedef int (*traverseproc)(PyObject *, visitproc, void *);
+
+typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
+typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+
+typedef struct {
+ /* For numbers without flag bit Py_TPFLAGS_CHECKTYPES set, all
+ arguments are guaranteed to be of the object's type (modulo
+ coercion hacks -- i.e. if the type's coercion function
+ returns other types, then these are allowed as well). Numbers that
+ have the Py_TPFLAGS_CHECKTYPES flag bit set should check *both*
+ arguments for proper type and implement the necessary conversions
+ in the slot functions themselves. */
+
+ binaryfunc nb_add;
+ binaryfunc nb_subtract;
+ binaryfunc nb_multiply;
+ binaryfunc nb_divide;
+ binaryfunc nb_remainder;
+ binaryfunc nb_divmod;
+ ternaryfunc nb_power;
+ unaryfunc nb_negative;
+ unaryfunc nb_positive;
+ unaryfunc nb_absolute;
+ inquiry nb_nonzero;
+ unaryfunc nb_invert;
+ binaryfunc nb_lshift;
+ binaryfunc nb_rshift;
+ binaryfunc nb_and;
+ binaryfunc nb_xor;
+ binaryfunc nb_or;
+ coercion nb_coerce;
+ unaryfunc nb_int;
+ unaryfunc nb_long;
+ unaryfunc nb_float;
+ unaryfunc nb_oct;
+ unaryfunc nb_hex;
+ /* Added in release 2.0 */
+ binaryfunc nb_inplace_add;
+ binaryfunc nb_inplace_subtract;
+ binaryfunc nb_inplace_multiply;
+ binaryfunc nb_inplace_divide;
+ binaryfunc nb_inplace_remainder;
+ ternaryfunc nb_inplace_power;
+ binaryfunc nb_inplace_lshift;
+ binaryfunc nb_inplace_rshift;
+ binaryfunc nb_inplace_and;
+ binaryfunc nb_inplace_xor;
+ binaryfunc nb_inplace_or;
+
+ /* Added in release 2.2 */
+ /* The following require the Py_TPFLAGS_HAVE_CLASS flag */
+ binaryfunc nb_floor_divide;
+ binaryfunc nb_true_divide;
+ binaryfunc nb_inplace_floor_divide;
+ binaryfunc nb_inplace_true_divide;
+
+ /* Added in release 2.5 */
+ unaryfunc nb_index;
+} PyNumberMethods;
+
+typedef struct {
+ lenfunc sq_length;
+ binaryfunc sq_concat;
+ ssizeargfunc sq_repeat;
+ ssizeargfunc sq_item;
+ ssizessizeargfunc sq_slice;
+ ssizeobjargproc sq_ass_item;
+ ssizessizeobjargproc sq_ass_slice;
+ objobjproc sq_contains;
+ /* Added in release 2.0 */
+ binaryfunc sq_inplace_concat;
+ ssizeargfunc sq_inplace_repeat;
+} PySequenceMethods;
+
+typedef struct {
+ lenfunc mp_length;
+ binaryfunc mp_subscript;
+ objobjargproc mp_ass_subscript;
+} PyMappingMethods;
+
+typedef struct {
+ readbufferproc bf_getreadbuffer;
+ writebufferproc bf_getwritebuffer;
+ segcountproc bf_getsegcount;
+ charbufferproc bf_getcharbuffer;
+ getbufferproc bf_getbuffer;
+ releasebufferproc bf_releasebuffer;
+} PyBufferProcs;
+
+
+
+typedef struct _typeobject {
+ PyObject_VAR_HEAD
+ const char *tp_name; /* For printing, in format "<module>.<name>" */
+ Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */
+
+ /* Methods to implement standard operations */
+
+ destructor tp_dealloc;
+ printfunc tp_print;
+ getattrfunc tp_getattr;
+ setattrfunc tp_setattr;
+ cmpfunc tp_compare;
+ reprfunc tp_repr;
+
+ /* Method suites for standard classes */
+
+ PyNumberMethods *tp_as_number;
+ PySequenceMethods *tp_as_sequence;
+ PyMappingMethods *tp_as_mapping;
+
+ /* More standard operations (here for binary compatibility) */
+
+ hashfunc tp_hash;
+ ternaryfunc tp_call;
+ reprfunc tp_str;
+ getattrofunc tp_getattro;
+ setattrofunc tp_setattro;
+
+ /* Functions to access object as input/output buffer */
+ PyBufferProcs *tp_as_buffer;
+
+ /* Flags to define presence of optional/expanded features */
+ long tp_flags;
+
+ const char *tp_doc; /* Documentation string */
+
+ /* Assigned meaning in release 2.0 */
+ /* call function for all accessible objects */
+ traverseproc tp_traverse;
+
+ /* delete references to contained objects */
+ inquiry tp_clear;
+
+ /* Assigned meaning in release 2.1 */
+ /* rich comparisons */
+ richcmpfunc tp_richcompare;
+
+ /* weak reference enabler */
+ Py_ssize_t tp_weaklistoffset;
+
+ /* Added in release 2.2 */
+ /* Iterators */
+ getiterfunc tp_iter;
+ iternextfunc tp_iternext;
+
+ /* Attribute descriptor and subclassing stuff */
+ struct PyMethodDef *tp_methods;
+ struct PyMemberDef *tp_members;
+ struct PyGetSetDef *tp_getset;
+ struct _typeobject *tp_base;
+ PyObject *tp_dict;
+ descrgetfunc tp_descr_get;
+ descrsetfunc tp_descr_set;
+ Py_ssize_t tp_dictoffset;
+ initproc tp_init;
+ allocfunc tp_alloc;
+ newfunc tp_new;
+ freefunc tp_free; /* Low-level free-memory routine */
+ inquiry tp_is_gc; /* For PyObject_IS_GC */
+ PyObject *tp_bases;
+ PyObject *tp_mro; /* method resolution order */
+ PyObject *tp_cache;
+ PyObject *tp_subclasses;
+ PyObject *tp_weaklist;
+ destructor tp_del;
+
+ /* Type attribute cache version tag. Added in version 2.6 */
+ unsigned int tp_version_tag;
+
+} PyTypeObject;
+
+/*
+`Type flags (tp_flags)
+
+These flags are used to extend the type structure in a backwards-compatible
+fashion. Extensions can use the flags to indicate (and test) when a given
+type structure contains a new feature. The Python core will use these when
+introducing new functionality between major revisions (to avoid mid-version
+changes in the PYTHON_API_VERSION).
+
+Arbitration of the flag bit positions will need to be coordinated among
+all extension writers who publically release their extensions (this will
+be fewer than you might expect!)..
+
+Python 1.5.2 introduced the bf_getcharbuffer slot into PyBufferProcs.
+
+Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value.
+
+Code can use PyType_HasFeature(type_ob, flag_value) to test whether the
+given type object has a specified feature.
+
+NOTE: when building the core, Py_TPFLAGS_DEFAULT includes
+Py_TPFLAGS_HAVE_VERSION_TAG; outside the core, it doesn't. This is so
+that extensions that modify tp_dict of their own types directly don't
+break, since this was allowed in 2.5. In 3.0 they will have to
+manually remove this flag though!
+*/
+
+/* PyBufferProcs contains bf_getcharbuffer */
+#define Py_TPFLAGS_HAVE_GETCHARBUFFER (1L<<0)
+
+/* PySequenceMethods contains sq_contains */
+#define Py_TPFLAGS_HAVE_SEQUENCE_IN (1L<<1)
+
+/* This is here for backwards compatibility. Extensions that use the old GC
+ * API will still compile but the objects will not be tracked by the GC. */
+#define Py_TPFLAGS_GC 0 /* used to be (1L<<2) */
+
+/* PySequenceMethods and PyNumberMethods contain in-place operators */
+#define Py_TPFLAGS_HAVE_INPLACEOPS (1L<<3)
+
+/* PyNumberMethods do their own coercion */
+#define Py_TPFLAGS_CHECKTYPES (1L<<4)
+
+/* tp_richcompare is defined */
+#define Py_TPFLAGS_HAVE_RICHCOMPARE (1L<<5)
+
+/* Objects which are weakly referencable if their tp_weaklistoffset is >0 */
+#define Py_TPFLAGS_HAVE_WEAKREFS (1L<<6)
+
+/* tp_iter is defined */
+#define Py_TPFLAGS_HAVE_ITER (1L<<7)
+
+/* New members introduced by Python 2.2 exist */
+#define Py_TPFLAGS_HAVE_CLASS (1L<<8)
+
+/* Set if the type object is dynamically allocated */
+#define Py_TPFLAGS_HEAPTYPE (1L<<9)
+
+/* Set if the type allows subclassing */
+#define Py_TPFLAGS_BASETYPE (1L<<10)
+
+/* Set if the type is 'ready' -- fully initialized */
+#define Py_TPFLAGS_READY (1L<<12)
+
+/* Set while the type is being 'readied', to prevent recursive ready calls */
+#define Py_TPFLAGS_READYING (1L<<13)
+
+/* Objects support garbage collection (see objimp.h) */
+#define Py_TPFLAGS_HAVE_GC (1L<<14)
+
+/* These two bits are preserved for Stackless Python, next after this is 17 */
+#ifdef STACKLESS
+#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION (3L<<15)
+#else
+#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0
+#endif
+
+/* Objects support nb_index in PyNumberMethods */
+#define Py_TPFLAGS_HAVE_INDEX (1L<<17)
+
+/* Objects support type attribute cache */
+#define Py_TPFLAGS_HAVE_VERSION_TAG (1L<<18)
+#define Py_TPFLAGS_VALID_VERSION_TAG (1L<<19)
+
+/* Type is abstract and cannot be instantiated */
+#define Py_TPFLAGS_IS_ABSTRACT (1L<<20)
+
+/* Has the new buffer protocol */
+#define Py_TPFLAGS_HAVE_NEWBUFFER (1L<<21)
+
+/* These flags are used to determine if a type is a subclass. */
+#define Py_TPFLAGS_INT_SUBCLASS (1L<<23)
+#define Py_TPFLAGS_LONG_SUBCLASS (1L<<24)
+#define Py_TPFLAGS_LIST_SUBCLASS (1L<<25)
+#define Py_TPFLAGS_TUPLE_SUBCLASS (1L<<26)
+#define Py_TPFLAGS_STRING_SUBCLASS (1L<<27)
+#define Py_TPFLAGS_UNICODE_SUBCLASS (1L<<28)
+#define Py_TPFLAGS_DICT_SUBCLASS (1L<<29)
+#define Py_TPFLAGS_BASE_EXC_SUBCLASS (1L<<30)
+#define Py_TPFLAGS_TYPE_SUBCLASS (1L<<31)
+
+#define Py_TPFLAGS_DEFAULT_EXTERNAL ( \
+ Py_TPFLAGS_HAVE_GETCHARBUFFER | \
+ Py_TPFLAGS_HAVE_SEQUENCE_IN | \
+ Py_TPFLAGS_HAVE_INPLACEOPS | \
+ Py_TPFLAGS_HAVE_RICHCOMPARE | \
+ Py_TPFLAGS_HAVE_WEAKREFS | \
+ Py_TPFLAGS_HAVE_ITER | \
+ Py_TPFLAGS_HAVE_CLASS | \
+ Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \
+ Py_TPFLAGS_HAVE_INDEX | \
+ 0)
+#define Py_TPFLAGS_DEFAULT_CORE (Py_TPFLAGS_DEFAULT_EXTERNAL | \
+ Py_TPFLAGS_HAVE_VERSION_TAG)
+
+#define Py_TPFLAGS_DEFAULT Py_TPFLAGS_DEFAULT_EXTERNAL
+
+
+/* objimpl.h ----------------------------------------------*/
+
+PyObject * _PyObject_New(PyTypeObject *);
+// PyVarObject * _PyObject_NewVar(PyTypeObject *, Py_ssize_t);
+
+#define PyObject_New(type, typeobj) \
+ ( (type *) _PyObject_New(typeobj) )
+#define PyObject_NewVar(type, typeobj, n) \
+ ( (type *) _PyObject_NewVar((typeobj), (n)) )
+
+
+#endif
Added: pypy/trunk/pypy/module/cpyext/include/stringobject.h
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/module/cpyext/include/stringobject.h Sat Mar 20 19:42:35 2010
@@ -0,0 +1,15 @@
+
+/* String object interface */
+
+#ifndef Py_STRINGOBJECT_H
+#define Py_STRINGOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyObject * PyString_FromStringAndSize(const char *, Py_ssize_t);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Added: pypy/trunk/pypy/module/cpyext/object.py
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/module/cpyext/object.py Sat Mar 20 19:42:35 2010
@@ -0,0 +1,7 @@
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.api import cpython_api, PyObject, make_ref
+from pypy.module.cpyext.typeobject import PyTypeObjectPtr
+
+ at cpython_api([PyTypeObjectPtr], PyObject)
+def _PyObject_New(space, pto):
+ return space.wrap(42)
Added: pypy/trunk/pypy/module/cpyext/stringobject.py
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/module/cpyext/stringobject.py Sat Mar 20 19:42:35 2010
@@ -0,0 +1,13 @@
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, Py_ssize_t
+
+ at cpython_api([rffi.CCHARP, Py_ssize_t], PyObject)
+def PyString_FromStringAndSize(char_p, length):
+ l = []
+ i = 0
+ while length > 0:
+ l.append(cp[i])
+ i += 1
+ length -= 1
+ return "".join(l)
+
Added: pypy/trunk/pypy/module/cpyext/test/foo.c
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/module/cpyext/test/foo.c Sat Mar 20 19:42:35 2010
@@ -0,0 +1,142 @@
+#include "Python.h"
+
+typedef struct {
+ PyObject_HEAD
+ int foo; /* the context holder */
+} fooobject;
+
+static PyTypeObject footype;
+
+static fooobject *
+newfooobject(void)
+{
+ fooobject *foop;
+
+ foop = PyObject_New(fooobject, &footype);
+ if (foop == NULL)
+ return NULL;
+
+ foop->foo = 42;
+ return foop;
+}
+
+
+/* foo methods */
+
+static void
+foo_dealloc(fooobject *foop)
+{
+ PyObject_Del(foop);
+}
+
+
+/* foo methods-as-attributes */
+
+static PyObject *
+foo_copy(fooobject *self)
+{
+ fooobject *foop;
+
+ if ((foop = newfooobject()) == NULL)
+ return NULL;
+
+ foop->foo = self->foo;
+
+ return (PyObject *)foop;
+}
+
+
+static PyMethodDef foo_methods[] = {
+ {"copy", (PyCFunction)foo_copy, METH_NOARGS, NULL},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+foo_get_name(PyObject *self, void *closure)
+{
+ return PyString_FromStringAndSize("Foo Example", 11);
+}
+
+static PyGetSetDef foo_getseters[] = {
+ {"name",
+ (getter)foo_get_name, NULL,
+ NULL,
+ NULL},
+ {NULL} /* Sentinel */
+};
+
+
+static PyTypeObject footype = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "foo.foo", /*tp_name*/
+ sizeof(fooobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)foo_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ foo_methods, /*tp_methods*/
+ 0, /*tp_members*/
+ foo_getseters, /*tp_getset*/
+};
+
+
+/* foo functions */
+
+static PyObject *
+foo_new(PyObject *self, PyObject *args)
+{
+ fooobject *foop;
+
+ if ((foop = newfooobject()) == NULL) {
+ return NULL;
+ }
+
+ return (PyObject *)foop;
+}
+
+
+/* List of functions exported by this module */
+
+static PyMethodDef foo_functions[] = {
+ {"new", (PyCFunction)foo_new, METH_NOARGS, NULL},
+ {NULL, NULL} /* Sentinel */
+};
+
+
+/* Initialize this module. */
+
+void initfoo(void)
+{
+ PyObject *m, *d;
+
+ Py_TYPE(&footype) = &PyType_Type;
+ if (PyType_Ready(&footype) < 0)
+ return;
+ m = Py_InitModule("foo", foo_functions);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ PyDict_SetItemString(d, "fooType", (PyObject *)&footype);
+ /* No need to check the error here, the caller will do that */
+}
Added: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/module/cpyext/test/test_typeobject.py Sat Mar 20 19:42:35 2010
@@ -0,0 +1,12 @@
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+
+import py
+import sys
+
+class AppTestTypeObject(AppTestCpythonExtensionBase):
+ def test_typeobject(self):
+ skip("In progress")
+ import sys
+ module = self.import_module(name='foo')
+ assert 'foo' in sys.modules
+ assert module.new().name == "Foo Example"
Added: pypy/trunk/pypy/module/cpyext/typeobject.py
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/module/cpyext/typeobject.py Sat Mar 20 19:42:35 2010
@@ -0,0 +1,38 @@
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject
+from pypy.interpreter.module import Module
+from pypy.module.cpyext.methodobject import PyCFunction_NewEx
+
+PyCFunction = lltype.Ptr(lltype.FuncType([PyObject, PyObject], PyObject))
+
+PyTypeObject = cpython_struct(
+ "PyTypeObject",
+ [])
+PyTypeObjectPtr = lltype.Ptr(PyTypeObject)
+
+def PyImport_AddModule(space, name):
+ w_name = space.wrap(name)
+ w_mod = space.wrap(Module(space, w_name))
+
+ w_modules = space.sys.get('modules')
+ space.setitem(w_modules, w_name, w_mod)
+ return w_mod
+
+#@cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef)], lltype.Void)
+def Py_InitModule(space, name, methods):
+ modname = rffi.charp2str(name)
+ w_mod = PyImport_AddModule(space, modname)
+ 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)
+ flags = method.c_ml_flags
+ w_function = PyCFunction_NewEx(space, method, None, modname)
+ space.setattr(w_mod,
+ space.wrap(methodname),
+ w_function)
+ i = i + 1
More information about the Pypy-commit
mailing list