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