1 /**
2    D code for contract tests verifying creation of PythonClass instances.
3  */
4 module contract.pyclass;
5 
6 
7 import python.raw;
8 import python.cooked;
9 import python.type;
10 
11 
12 extern(C):
13 
14 
15 package PyObject* pyclass_int_double_struct(PyObject* self, PyObject *args) {
16 
17     if(PyTuple_Size(args) != 2) {
18         PyErr_SetString(PyExc_TypeError, &"Wrong number of arguments"[0]);
19         return null;
20     }
21 
22     auto arg0 = PyTuple_GetItem(args, 0);
23     if(arg0 is null) {
24         PyErr_SetString(PyExc_TypeError, &"Could not get first argument"[0]);
25         return null;
26     }
27 
28     auto arg1 = PyTuple_GetItem(args, 1);
29     if(arg1 is null) {
30         PyErr_SetString(PyExc_TypeError, &"Could not get first argument"[0]);
31         return null;
32     }
33 
34     static struct SimpleStruct {
35         int i;
36         double d;
37     }
38 
39     auto darg0 = cast(int) PyLong_AsLong(arg0);
40     auto darg1 = PyFloat_AsDouble(arg1);
41     auto struct_ = SimpleStruct(darg0, darg1);
42 
43     return pythonClass(struct_);
44 }
45 
46 
47 package PyObject* pyclass_string_list_struct(PyObject* self, PyObject *args) {
48     if(PyTuple_Size(args) != 1) {
49         PyErr_SetString(PyExc_TypeError, &"Wrong number of arguments"[0]);
50         return null;
51     }
52 
53     auto arg = PyTuple_GetItem(args, 0);
54     if(arg is null) {
55         PyErr_SetString(PyExc_TypeError, &"Could not get first argument"[0]);
56         return null;
57     }
58 
59     if(!pyListCheck(arg)) {
60         PyErr_SetString(PyExc_TypeError, &"Argument not a list"[0]);
61         return null;
62     }
63 
64     char[][] strings;
65 
66     foreach(i; 0 .. PyList_Size(arg)) {
67 
68         auto item = PyList_GetItem(arg, i);
69         if(pyUnicodeCheck(item)) item = pyObjectUnicode(item);
70 
71         if(!pyUnicodeCheck(item)) {
72             PyErr_SetString(PyExc_TypeError, &"All arguments must be strings"[0]);
73             return null;
74         }
75 
76         auto unicode = pyUnicodeAsUtf8String(item);
77         if(!unicode) {
78             PyErr_SetString(PyExc_TypeError, &"Could not decode UTF8"[0]);
79             return null;
80         }
81 
82         const length = pyUnicodeGetSize(item);
83         auto ptr = pyBytesAsString(unicode);
84         auto str = ptr is null ? null : ptr[0 .. length];
85 
86         strings ~= str;
87     }
88 
89     static struct StringsStruct {
90         string[] strings;
91     }
92 
93     return pythonClass(StringsStruct(cast(string[]) strings));
94 }
95 
96 
97 package PyObject* pyclass_twice_struct(PyObject* self, PyObject *args) {
98     if(PyTuple_Size(args) != 1) {
99         PyErr_SetString(PyExc_TypeError, &"Wrong number of arguments"[0]);
100         return null;
101     }
102 
103     auto arg = PyTuple_GetItem(args, 0);
104     if(arg is null) {
105         PyErr_SetString(PyExc_TypeError, &"Could not get first argument"[0]);
106         return null;
107     }
108 
109     const darg = cast(int) PyLong_AsLong(arg);
110 
111     static struct TwiceStruct {
112         int i;
113         int twice() @safe @nogc pure nothrow const {
114             return i * 2;
115         }
116     }
117 
118     return pythonClass(TwiceStruct(darg));
119 }
120 
121 
122 package PyObject* pyclass_thrice_struct(PyObject* self, PyObject *args) {
123     if(PyTuple_Size(args) != 1) {
124         PyErr_SetString(PyExc_TypeError, &"Wrong number of arguments"[0]);
125         return null;
126     }
127 
128     auto arg = PyTuple_GetItem(args, 0);
129     if(arg is null) {
130         PyErr_SetString(PyExc_TypeError, &"Could not get first argument"[0]);
131         return null;
132     }
133 
134     const darg = PyFloat_AsDouble(arg);
135 
136     static struct ThriceStruct {
137         double d;
138 
139         double thrice() @safe @nogc pure nothrow const {
140             return d * 3;
141         }
142 
143         double quadruple() @safe @nogc pure nothrow const {
144             return d * 4;
145         }
146     }
147 
148     return pythonClass(ThriceStruct(darg));
149 }
150 
151 
152 package PyObject* pyclass_void_struct(PyObject* self, PyObject *args) {
153 
154     static struct VoidStruct {
155         int i = 42;
156 
157         void setValue(int i) {
158             this.i = i;
159         }
160     }
161 
162     return pythonClass(VoidStruct());
163 }