[pypy-commit] pypy cpyext-injection: Yay, a test

arigo pypy.commits at gmail.com
Wed Oct 19 08:03:41 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: cpyext-injection
Changeset: r87870:a1e270ccbe1a
Date: 2016-10-19 14:02 +0200
http://bitbucket.org/pypy/pypy/changeset/a1e270ccbe1a/

Log:	Yay, a test

diff --git a/pypy/module/cpyext/test/injection.c b/pypy/module/cpyext/test/injection.c
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/injection.c
@@ -0,0 +1,130 @@
+#include "Python.h"
+
+typedef struct {
+    PyObject_HEAD
+    int foo;
+} mytype_object;
+
+
+static PyObject *
+mytype_item(mytype_object *o, Py_ssize_t i)
+{
+    return PyInt_FromLong(i + 42);
+}
+
+static PyObject *
+mytype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    return type->tp_alloc(type, 0);
+}
+
+static PySequenceMethods mytype_as_sequence = {
+    (lenfunc)0,                      /*sq_length*/
+    (binaryfunc)0,                   /*sq_concat*/
+    (ssizeargfunc)0,                 /*sq_repeat*/
+    (ssizeargfunc)mytype_item,       /*sq_item*/
+};
+
+static PyTypeObject mytype_type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "test_module.test_mytype",   /*tp_name*/
+    sizeof(mytype_object),       /*tp_size*/
+    0,                       /*tp_itemsize*/
+    /* methods */
+    0,                       /*tp_dealloc*/
+    0,                       /*tp_print*/
+    0,                       /*tp_getattr*/
+    0,                       /*tp_setattr*/
+    0,                       /*tp_compare*/
+    0,                       /*tp_repr*/
+    0,                       /*tp_as_number*/
+    &mytype_as_sequence,     /*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 | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    0,                       /*tp_doc*/
+    0,                       /*tp_traverse*/
+    0,                       /*tp_clear*/
+    0,                       /*tp_richcompare*/
+    0,                       /*tp_weaklistoffset*/
+    0,                       /*tp_iter*/
+    0,                       /*tp_iternext*/
+    0,                       /*tp_methods*/
+    0,                       /*tp_members*/
+    0,                       /*tp_getset*/
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    0,                                          /* tp_init */
+    PyType_GenericAlloc,                        /* tp_alloc */
+    mytype_new,                                 /* tp_new */
+    PyObject_Del,                               /* tp_free */
+};
+
+/* List of functions exported by this module */
+
+static PyMethodDef foo_functions[] = {
+    {NULL,        NULL}    /* Sentinel */
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    "injection",
+    "Module Doc",
+    -1,
+    foo_functions,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+};
+#define INITERROR return NULL
+
+/* Initialize this module. */
+#ifdef __GNUC__
+extern __attribute__((visibility("default")))
+#else
+extern __declspec(dllexport)
+#endif
+
+PyMODINIT_FUNC
+PyInit_foo(void)
+
+#else
+
+#define INITERROR return
+
+/* Initialize this module. */
+#ifdef __GNUC__
+extern __attribute__((visibility("default")))
+#else
+extern __declspec(dllexport)
+#endif
+
+PyMODINIT_FUNC
+initinjection(void)
+#endif
+{
+    PyObject *d;
+#if PY_MAJOR_VERSION >= 3
+    PyObject *module = PyModule_Create(&moduledef);
+#else
+    PyObject *module = Py_InitModule("injection", foo_functions);
+#endif
+    if (module == NULL)
+        INITERROR;
+
+    if (PyType_Ready(&mytype_type) < 0)
+        INITERROR;
+#if PY_MAJOR_VERSION >=3
+    return module;
+#endif
+}
diff --git a/pypy/module/cpyext/test/test_injection.py b/pypy/module/cpyext/test/test_injection.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/test_injection.py
@@ -0,0 +1,6 @@
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+
+
+class AppTestTypeObject(AppTestCpythonExtensionBase):
+    def test_module_exists(self):
+        module = self.import_module(name='injection')
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -456,7 +456,7 @@
     def __init__(self, space, pto):
         bases_w = space.fixedview(from_ref(space, pto.c_tp_bases))
         dict_w = {}
-        ...
+        inject_operators(space, dict_w, pto)
 
         add_operators(space, dict_w, pto)
         convert_method_defs(space, dict_w, pto.c_tp_methods, self)
@@ -964,3 +964,8 @@
     if w_obj.is_cpytype():
         w_obj.mutated(None)
 
+
+def inject_operators(space, dict_w, pto):
+    name = rffi.charp2str(pto.c_tp_name)
+    if name == 'test_module.test_mytype':
+        pass #xxx


More information about the pypy-commit mailing list