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 }