1 // A module written to the raw Python/C API.
2 module rawexample;
3 
4 import deimos.python.Python;
5 import std.stdio;
6 import core.runtime;
7 
8 static PyTypeObject Base_type;
9 static PyTypeObject Derived_type;
10 
11 struct Base_object {
12     mixin PyObject_HEAD;
13 }
14 
15 struct Derived_object {
16     mixin PyObject_HEAD;
17 }
18 
19 extern(C)
20 PyObject* Base_foo(PyObject* self, PyObject* args) {
21     writefln("Base.foo");
22     return Py_INCREF(Py_None());
23 }
24 
25 extern(C)
26 PyObject* Base_bar(PyObject* self, PyObject* args) {
27     writefln("Base.bar");
28     return Py_INCREF(Py_None());
29 }
30 
31 PyMethodDef[] Base_methods = [
32     {"foo", &Base_foo, METH_VARARGS, ""},
33     {"bar", &Base_bar, METH_VARARGS, ""},
34     {null, null, 0, null}
35 ];
36 
37 extern(C)
38 PyObject* Derived_bar(PyObject* self, PyObject* args) {
39     writefln("Derived.bar");
40     return Py_INCREF(Py_None());
41 }
42 
43 PyMethodDef[] Derived_methods = [
44     {"bar", &Derived_bar, METH_VARARGS, ""},
45     {null, null, 0, null}
46 ];
47 
48 extern(C)
49 PyObject* hello(PyObject* self, PyObject* args) {
50     writefln("Hello, world!");
51     return Py_INCREF(Py_None());
52 }
53 
54 PyMethodDef[] example_methods = [
55     {"hello", &hello, METH_VARARGS, ""},
56     {null, null, 0, null}
57 ];
58 
59 version(Python_3_0_Or_Later) {
60     PyModuleDef rawmodule = {
61         // in lieu of PyModuleDef_HEAD_INIT
62         m_base: {
63             ob_base: {
64                 ob_refcnt:1,
65                 ob_type:null,
66             },
67             m_init:null,
68             m_index:0,
69             m_copy:null
70         },
71         m_name: "example",
72         m_doc: null,
73         m_size: -1,
74     };
75 }
76 
77 version(Python_3_0_Or_Later) {
78     extern(C)
79     export PyObject* PyInit_example () {
80         rt_init();
81         rawmodule.m_methods = example_methods.ptr;
82         PyObject* m = PyModule_Create(&rawmodule);
83 
84         Py_SET_TYPE(&Base_type, &PyType_Type);
85         Base_type.tp_basicsize = Base_object.sizeof;
86         Base_type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
87         Base_type.tp_methods = Base_methods.ptr;
88         Base_type.tp_name = "example.Base";
89         Base_type.tp_new = &PyType_GenericNew;
90         PyType_Ready(&Base_type);
91         Py_INCREF(cast(PyObject*)&Base_type);
92         PyModule_AddObject(m, "Base", cast(PyObject*)&Base_type);
93 
94         Py_SET_TYPE(&Derived_type, &PyType_Type);
95         Derived_type.tp_basicsize = Derived_object.sizeof;
96         Derived_type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
97         Derived_type.tp_methods = Derived_methods.ptr;
98         Derived_type.tp_name = "example.Derived";
99         Derived_type.tp_new = &PyType_GenericNew;
100         Derived_type.tp_base = &Base_type;
101         PyType_Ready(&Derived_type);
102         Py_INCREF(cast(PyObject*)&Derived_type);
103         PyModule_AddObject(m, "Derived", cast(PyObject*)&Derived_type);
104 
105         return m;
106     }
107 }else{
108     extern(C)
109     export void initexample() {
110         rt_init();
111         PyObject* m = Py_INCREF(Py_InitModule("example", example_methods.ptr));
112 
113         Py_SET_TYPE(&Base_type, &PyType_Type);
114         Base_type.tp_basicsize = Base_object.sizeof;
115         Base_type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
116         Base_type.tp_methods = Base_methods.ptr;
117         Base_type.tp_name = "example.Base";
118         Base_type.tp_new = &PyType_GenericNew;
119         PyType_Ready(&Base_type);
120         Py_INCREF(cast(PyObject*)&Base_type);
121         PyModule_AddObject(m, "Base", cast(PyObject*)&Base_type);
122 
123         Py_SET_TYPE(&Derived_type, &PyType_Type);
124         Derived_type.tp_basicsize = Derived_object.sizeof;
125         Derived_type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
126         Derived_type.tp_methods = Derived_methods.ptr;
127         Derived_type.tp_name = "example.Derived";
128         Derived_type.tp_new = &PyType_GenericNew;
129         Derived_type.tp_base = &Base_type;
130         PyType_Ready(&Derived_type);
131         Py_INCREF(cast(PyObject*)&Derived_type);
132         PyModule_AddObject(m, "Derived", cast(PyObject*)&Derived_type);
133     }
134 }
135