fazekasgy@31
|
1 /*
|
fazekasgy@31
|
2
|
fazekasgy@31
|
3 Type safe conversion utilities from Python types to C/C++ types,
|
fazekasgy@31
|
4 mainly using Py/C API macros.
|
fazekasgy@31
|
5
|
fazekasgy@31
|
6 */
|
fazekasgy@31
|
7
|
fazekasgy@31
|
8 #ifndef _PY_TYPE_INTERFACE_H_
|
fazekasgy@31
|
9 #define _PY_TYPE_INTERFACE_H_
|
fazekasgy@31
|
10 #include <Python.h>
|
fazekasgy@32
|
11 #ifdef HAVE_NUMPY
|
fazekasgy@32
|
12 #include "arrayobject.h"
|
fazekasgy@32
|
13 #endif
|
fazekasgy@31
|
14 #include "PyExtensionModule.h"
|
fazekasgy@31
|
15 #include <vector>
|
fazekasgy@31
|
16 #include <queue>
|
fazekasgy@31
|
17 #include <string>
|
fazekasgy@32
|
18 #include "vamp-sdk/Plugin.h"
|
fazekasgy@31
|
19 //#include <typeinfo>
|
fazekasgy@31
|
20
|
fazekasgy@31
|
21
|
fazekasgy@31
|
22 using std::cerr;
|
fazekasgy@31
|
23 using std::endl;
|
fazekasgy@31
|
24
|
fazekasgy@31
|
25 namespace o {
|
fazekasgy@31
|
26 enum eOutDescriptors {
|
fazekasgy@31
|
27 not_found,
|
fazekasgy@31
|
28 identifier,
|
fazekasgy@31
|
29 name,
|
fazekasgy@31
|
30 description,
|
fazekasgy@31
|
31 unit,
|
fazekasgy@31
|
32 hasFixedBinCount,
|
fazekasgy@31
|
33 binCount,
|
fazekasgy@31
|
34 binNames,
|
fazekasgy@31
|
35 hasKnownExtents,
|
fazekasgy@31
|
36 minValue,
|
fazekasgy@31
|
37 maxValue,
|
fazekasgy@31
|
38 isQuantized,
|
fazekasgy@31
|
39 quantizeStep,
|
fazekasgy@31
|
40 sampleType,
|
fazekasgy@31
|
41 sampleRate,
|
fazekasgy@31
|
42 hasDuration,
|
fazekasgy@31
|
43 endNode
|
fazekasgy@31
|
44 };
|
fazekasgy@31
|
45 }
|
fazekasgy@31
|
46
|
fazekasgy@31
|
47 namespace p {
|
fazekasgy@31
|
48 enum eParmDescriptors {
|
fazekasgy@31
|
49 not_found,
|
fazekasgy@31
|
50 identifier,
|
fazekasgy@31
|
51 name,
|
fazekasgy@31
|
52 description,
|
fazekasgy@31
|
53 unit,
|
fazekasgy@31
|
54 minValue,
|
fazekasgy@31
|
55 maxValue,
|
fazekasgy@31
|
56 defaultValue,
|
fazekasgy@31
|
57 isQuantized,
|
fazekasgy@31
|
58 quantizeStep
|
fazekasgy@31
|
59 };
|
fazekasgy@31
|
60 }
|
fazekasgy@31
|
61
|
fazekasgy@31
|
62 enum eSampleTypes {
|
fazekasgy@31
|
63 OneSamplePerStep,
|
fazekasgy@31
|
64 FixedSampleRate,
|
fazekasgy@31
|
65 VariableSampleRate
|
fazekasgy@31
|
66 };
|
fazekasgy@31
|
67
|
fazekasgy@31
|
68 enum eFeatureFields {
|
fazekasgy@31
|
69 unknown,
|
fazekasgy@31
|
70 hasTimestamp,
|
fazekasgy@31
|
71 timeStamp,
|
fazekasgy@31
|
72 hasDuration,
|
fazekasgy@31
|
73 duration,
|
fazekasgy@31
|
74 values,
|
fazekasgy@31
|
75 label
|
fazekasgy@31
|
76 };
|
fazekasgy@31
|
77
|
fazekasgy@31
|
78 /* C++ mapping of PyNone Type*/
|
cannam@33
|
79 struct NoneType {};
|
fazekasgy@31
|
80
|
fazekasgy@31
|
81 class PyTypeInterface
|
fazekasgy@31
|
82 {
|
fazekasgy@31
|
83 public:
|
fazekasgy@31
|
84 PyTypeInterface();
|
fazekasgy@31
|
85 ~PyTypeInterface();
|
fazekasgy@31
|
86
|
fazekasgy@31
|
87 // Data
|
fazekasgy@31
|
88 class ValueError
|
fazekasgy@31
|
89 {
|
fazekasgy@31
|
90 public:
|
fazekasgy@31
|
91 ValueError() {}
|
fazekasgy@31
|
92 ValueError(std::string m, bool s) : message(m),strict(s) {}
|
fazekasgy@31
|
93 std::string location;
|
fazekasgy@31
|
94 std::string message;
|
fazekasgy@31
|
95 bool strict;
|
fazekasgy@31
|
96 std::string get() const { return message + "\nLocation: " + location + "\n";}
|
fazekasgy@31
|
97 void print() const { cerr << get(); }
|
fazekasgy@31
|
98 };
|
fazekasgy@31
|
99
|
fazekasgy@31
|
100 // Utilities
|
fazekasgy@31
|
101 void setStrictTypingFlag(bool b) {m_strict = b;}
|
fazekasgy@31
|
102 const ValueError &lastError() const;
|
fazekasgy@31
|
103 ValueError getError() const;
|
fazekasgy@31
|
104 std::string PyValue_Get_TypeName(PyObject*) const;
|
fazekasgy@31
|
105 bool initMaps() const;
|
fazekasgy@31
|
106
|
fazekasgy@31
|
107 // Basic type conversion: Python to C++
|
fazekasgy@31
|
108 float PyValue_To_Float(PyObject*) const;
|
fazekasgy@31
|
109 size_t PyValue_To_Size_t(PyObject*) const;
|
fazekasgy@31
|
110 bool PyValue_To_Bool(PyObject*) const;
|
fazekasgy@31
|
111 std::string PyValue_To_String(PyObject*) const;
|
fazekasgy@31
|
112 // int PyValue_To_Int(PyObject*) const;
|
fazekasgy@31
|
113
|
fazekasgy@31
|
114 // C++ to Python
|
fazekasgy@31
|
115 PyObject *PyValue_From_CValue(const char*) const;
|
fazekasgy@31
|
116 PyObject *PyValue_From_CValue(const std::string& x) const { return PyValue_From_CValue(x.c_str()); }
|
fazekasgy@31
|
117 PyObject *PyValue_From_CValue(size_t) const;
|
fazekasgy@31
|
118 PyObject *PyValue_From_CValue(double) const;
|
fazekasgy@31
|
119 PyObject *PyValue_From_CValue(float x) const { return PyValue_From_CValue((double)x); }
|
fazekasgy@31
|
120 PyObject *PyValue_From_CValue(bool) const;
|
fazekasgy@31
|
121
|
fazekasgy@31
|
122 // Sequence types
|
fazekasgy@31
|
123 std::vector<std::string> PyValue_To_StringVector (PyObject*) const;
|
fazekasgy@31
|
124 std::vector<float> PyValue_To_FloatVector (PyObject*) const;
|
fazekasgy@32
|
125 std::vector<float> PyList_To_FloatVector (PyObject*) const;
|
fazekasgy@31
|
126
|
fazekasgy@31
|
127 // Numpy types
|
fazekasgy@32
|
128 #ifdef HAVE_NUMPY
|
fazekasgy@32
|
129 std::vector<float> PyArray_To_FloatVector (PyObject *pyValue) const;
|
fazekasgy@32
|
130 #endif
|
fazekasgy@31
|
131
|
fazekasgy@31
|
132
|
fazekasgy@31
|
133 /* Template functions */
|
fazekasgy@31
|
134
|
fazekasgy@31
|
135
|
fazekasgy@32
|
136 /// Common wrappers to set values in Vamp API structs. (to be used in template functions)
|
fazekasgy@31
|
137 void SetValue(Vamp::Plugin::OutputDescriptor& od, std::string& key, PyObject* pyValue) const;
|
fazekasgy@31
|
138 void SetValue(Vamp::Plugin::ParameterDescriptor& od, std::string& key, PyObject* pyValue) const;
|
fazekasgy@31
|
139 bool SetValue(Vamp::Plugin::Feature& od, std::string& key, PyObject* pyValue) const;
|
fazekasgy@31
|
140 PyObject* GetDescriptor_As_Dict(PyObject* pyValue) const
|
fazekasgy@31
|
141 {
|
fazekasgy@31
|
142 if PyFeature_CheckExact(pyValue) return PyFeature_AS_DICT(pyValue);
|
fazekasgy@31
|
143 if PyOutputDescriptor_CheckExact(pyValue) return PyOutputDescriptor_AS_DICT(pyValue);
|
fazekasgy@31
|
144 if PyParameterDescriptor_CheckExact(pyValue) return PyParameterDescriptor_AS_DICT(pyValue);
|
fazekasgy@31
|
145 return NULL;
|
fazekasgy@31
|
146 }
|
fazekasgy@31
|
147
|
fazekasgy@31
|
148
|
fazekasgy@31
|
149 template<typename RET>
|
cannam@33
|
150 RET PyValue_To_VampDescriptor(PyObject* pyValue) const
|
fazekasgy@31
|
151 //returns e.g. Vamp::Plugin::OutputDescriptor or Vamp::Plugin::Feature
|
fazekasgy@31
|
152 {
|
fazekasgy@31
|
153 PyObject* pyDict;
|
fazekasgy@31
|
154
|
fazekasgy@31
|
155 // Descriptors encoded as dicts
|
fazekasgy@31
|
156 pyDict = GetDescriptor_As_Dict(pyValue);
|
fazekasgy@31
|
157 if (!pyDict) pyDict = pyValue;
|
fazekasgy@31
|
158
|
fazekasgy@31
|
159 // TODO: support full mapping protocol as fallback.
|
fazekasgy@31
|
160 if (!PyDict_Check(pyDict)) {
|
fazekasgy@31
|
161 setValueError("Error while converting descriptor or feature object.\nThe value is neither a dictionary nor a Vamp Feature or Descriptor type.",m_strict);
|
fazekasgy@31
|
162 return RET();
|
fazekasgy@31
|
163 }
|
fazekasgy@31
|
164
|
fazekasgy@31
|
165 Py_ssize_t pyPos = 0;
|
fazekasgy@31
|
166 PyObject *pyKey, *pyDictValue;
|
fazekasgy@31
|
167 initMaps();
|
fazekasgy@31
|
168 RET rd;
|
fazekasgy@31
|
169
|
fazekasgy@31
|
170 //Python Dictionary Iterator:
|
fazekasgy@31
|
171 while (PyDict_Next(pyDict, &pyPos, &pyKey, &pyDictValue))
|
fazekasgy@31
|
172 {
|
fazekasgy@31
|
173 std::string key = PyValue_To_String(pyKey);
|
fazekasgy@31
|
174 SetValue(rd,key,pyDictValue);
|
fazekasgy@31
|
175 if (m_error) {
|
fazekasgy@31
|
176 _lastError().location += "parameter: '" + key + "'";//"' descriptor: '" + rd.identifier + "'";
|
fazekasgy@31
|
177 }
|
fazekasgy@31
|
178 }
|
fazekasgy@31
|
179 if (!m_errorQueue.empty()) m_error = true;
|
fazekasgy@31
|
180 return rd;
|
fazekasgy@31
|
181 }
|
fazekasgy@31
|
182
|
fazekasgy@31
|
183 /// Convert a sequence (tipically list) of PySomething to
|
fazekasgy@31
|
184 /// OutputList,ParameterList or FeatureList
|
fazekasgy@31
|
185 template<typename RET,typename ELEM> //<OutputList> <OutputDescriptor>
|
cannam@33
|
186
|
cannam@33
|
187 RET PyValue_To_VampList(PyObject* pyList) const
|
fazekasgy@31
|
188 {
|
fazekasgy@31
|
189 // Vamp::Plugin::OutputList list;
|
fazekasgy@31
|
190 // Vamp::Plugin::OutputDescriptor od;
|
fazekasgy@31
|
191 RET list;
|
fazekasgy@31
|
192 ELEM element;
|
fazekasgy@31
|
193
|
fazekasgy@31
|
194 // Type checking
|
fazekasgy@31
|
195 if (! PyList_Check(pyList) ) {
|
fazekasgy@31
|
196 Py_CLEAR(pyList);
|
fazekasgy@31
|
197 // cerr << "ERROR: In Python plugin [" << m_class << "::" << method
|
fazekasgy@31
|
198 // << "] Expected List return type." << endl;
|
fazekasgy@31
|
199 return list;
|
fazekasgy@31
|
200 }
|
fazekasgy@31
|
201
|
fazekasgy@31
|
202 //This reference will be borrowed
|
fazekasgy@31
|
203 PyObject *pyDict;
|
fazekasgy@31
|
204
|
fazekasgy@31
|
205 //Parse Output List
|
fazekasgy@31
|
206 for (Py_ssize_t i = 0; i < PyList_GET_SIZE(pyList); ++i) {
|
fazekasgy@31
|
207 //Get i-th Vamp output descriptor (Borrowed Reference)
|
fazekasgy@31
|
208 pyDict = PyList_GET_ITEM(pyList,i);
|
fazekasgy@31
|
209 element = PyValue_To_VampDescriptor<ELEM>(pyDict);
|
fazekasgy@31
|
210 // Check for empty Feature/Descriptor as before?
|
fazekasgy@31
|
211 list.push_back(element);
|
fazekasgy@31
|
212 }
|
fazekasgy@31
|
213 return list;
|
fazekasgy@31
|
214 }
|
fazekasgy@31
|
215
|
fazekasgy@32
|
216 /// Convert DTYPE type 1D NumpyArray to std::vector<RET>
|
fazekasgy@32
|
217 template<typename RET, typename DTYPE>
|
cannam@33
|
218 std::vector<RET> PyArray_Convert(char* raw_data_ptr, long length) const
|
fazekasgy@32
|
219 {
|
fazekasgy@32
|
220 std::vector<RET> rValue;
|
fazekasgy@32
|
221 DTYPE* data = (DTYPE*) raw_data_ptr;
|
fazekasgy@32
|
222 for (long i = 0; i<length; ++i){
|
fazekasgy@32
|
223 #ifdef _DEBUG
|
fazekasgy@32
|
224 cerr << "value: " << (RET)data[i] << endl;
|
fazekasgy@32
|
225 #endif
|
fazekasgy@32
|
226 rValue.push_back((RET)data[i]);
|
fazekasgy@32
|
227 }
|
fazekasgy@32
|
228 return rValue;
|
fazekasgy@32
|
229 }
|
fazekasgy@31
|
230
|
fazekasgy@31
|
231 //Vamp specific types
|
fazekasgy@31
|
232
|
fazekasgy@31
|
233 Vamp::Plugin::FeatureSet PyValue_To_FeatureSet(PyObject*) const;
|
fazekasgy@31
|
234 inline void PyValue_To_rValue(PyObject *pyValue, Vamp::Plugin::FeatureSet &r) const
|
fazekasgy@31
|
235 { r = this->PyValue_To_FeatureSet(pyValue); }
|
fazekasgy@31
|
236
|
fazekasgy@31
|
237 Vamp::RealTime::RealTime PyValue_To_RealTime(PyObject*) const;
|
fazekasgy@31
|
238 inline void PyValue_To_rValue(PyObject *pyValue, Vamp::RealTime::RealTime &r) const
|
fazekasgy@31
|
239 { r = this->PyValue_To_RealTime(pyValue); }
|
fazekasgy@31
|
240
|
fazekasgy@31
|
241
|
fazekasgy@31
|
242 /* Overloaded PyValue_To_rValue() to support generic functions */
|
fazekasgy@31
|
243 inline void PyValue_To_rValue(PyObject *pyValue, float &defValue) const
|
fazekasgy@31
|
244 { float tmp = this->PyValue_To_Float(pyValue);
|
fazekasgy@31
|
245 if(!m_error) defValue = tmp; }
|
fazekasgy@31
|
246 inline void PyValue_To_rValue(PyObject *pyValue, size_t &defValue) const
|
fazekasgy@31
|
247 { size_t tmp = this->PyValue_To_Size_t(pyValue);
|
fazekasgy@31
|
248 if(!m_error) defValue = tmp; }
|
fazekasgy@31
|
249 inline void PyValue_To_rValue(PyObject *pyValue, bool &defValue) const
|
fazekasgy@31
|
250 { bool tmp = this->PyValue_To_Bool(pyValue);
|
fazekasgy@31
|
251 if(!m_error) defValue = tmp; }
|
fazekasgy@31
|
252 inline void PyValue_To_rValue(PyObject *pyValue, std::string &defValue) const
|
fazekasgy@31
|
253 { std::string tmp = this->PyValue_To_String(pyValue);
|
fazekasgy@31
|
254 if(!m_error) defValue = tmp; }
|
fazekasgy@31
|
255 /*used by templates where we expect no return value, if there is one it will be ignored*/
|
fazekasgy@31
|
256 inline void PyValue_To_rValue(PyObject *pyValue, NoneType &defValue) const
|
fazekasgy@31
|
257 { if (m_strict && pyValue != Py_None)
|
fazekasgy@32
|
258 setValueError("Strict conversion error: Expected 'None' type.",m_strict);
|
fazekasgy@31
|
259 }
|
fazekasgy@31
|
260
|
fazekasgy@31
|
261 /* convert sequence types to Vamp List types */
|
fazekasgy@31
|
262 inline void PyValue_To_rValue(PyObject *pyValue, Vamp::Plugin::OutputList &r) const
|
fazekasgy@31
|
263 { r = this->PyValue_To_VampList<Vamp::Plugin::OutputList,Vamp::Plugin::OutputDescriptor>(pyValue); }
|
fazekasgy@31
|
264 inline void PyValue_To_rValue(PyObject *pyValue, Vamp::Plugin::ParameterList &r) const
|
fazekasgy@31
|
265 { r = this->PyValue_To_VampList<Vamp::Plugin::ParameterList,Vamp::Plugin::ParameterDescriptor>(pyValue); }
|
fazekasgy@31
|
266 inline void PyValue_To_rValue(PyObject *pyValue, Vamp::Plugin::FeatureList &r) const
|
fazekasgy@31
|
267 { r = this->PyValue_To_VampList<Vamp::Plugin::FeatureList,Vamp::Plugin::Feature>(pyValue); }
|
fazekasgy@31
|
268
|
fazekasgy@31
|
269 /// this is only needed for RealTime->Frame conversion
|
fazekasgy@31
|
270 void setInputSampleRate(float inputSampleRate)
|
fazekasgy@31
|
271 { m_inputSampleRate = (unsigned int) inputSampleRate; }
|
fazekasgy@31
|
272
|
fazekasgy@31
|
273 private:
|
fazekasgy@31
|
274 bool m_strict;
|
fazekasgy@31
|
275 ValueError m_noError;
|
fazekasgy@31
|
276 mutable bool m_error;
|
fazekasgy@31
|
277 mutable ValueError& m_lastError;
|
fazekasgy@31
|
278 mutable std::queue<ValueError> m_errorQueue;
|
fazekasgy@31
|
279 // we only use it for RealTime conversion which requires unsigned int
|
fazekasgy@31
|
280 unsigned int m_inputSampleRate;
|
fazekasgy@31
|
281
|
fazekasgy@31
|
282 void setValueError(std::string,bool) const;
|
fazekasgy@31
|
283 ValueError& _lastError() const;
|
fazekasgy@31
|
284
|
fazekasgy@31
|
285 /* Overloaded _convert(), bypasses error checking to avoid doing it twice in internals. */
|
fazekasgy@31
|
286 inline void _convert(PyObject *pyValue,float &r) const
|
fazekasgy@31
|
287 { r = PyValue_To_Float(pyValue); }
|
fazekasgy@31
|
288 inline void _convert(PyObject *pyValue,size_t &r) const
|
fazekasgy@31
|
289 { r = PyValue_To_Size_t(pyValue); }
|
fazekasgy@31
|
290 inline void _convert(PyObject *pyValue,bool &r) const
|
fazekasgy@31
|
291 { r = PyValue_To_Bool(pyValue); }
|
fazekasgy@31
|
292 inline void _convert(PyObject *pyValue,std::string &r) const
|
fazekasgy@31
|
293 { r = PyValue_To_String(pyValue); }
|
fazekasgy@31
|
294 inline void _convert(PyObject *pyValue,std::vector<std::string> &r) const
|
fazekasgy@31
|
295 { r = PyValue_To_StringVector(pyValue); }
|
fazekasgy@31
|
296 inline void _convert(PyObject *pyValue,std::vector<float> &r) const
|
fazekasgy@31
|
297 { r = PyValue_To_FloatVector(pyValue); }
|
fazekasgy@31
|
298 inline void _convert(PyObject *pyValue,Vamp::RealTime::RealTime &r) const
|
fazekasgy@31
|
299 { r = PyValue_To_RealTime(pyValue); }
|
fazekasgy@31
|
300
|
fazekasgy@31
|
301 public:
|
fazekasgy@31
|
302 const bool& error;
|
fazekasgy@31
|
303
|
fazekasgy@31
|
304 };
|
fazekasgy@31
|
305
|
fazekasgy@32
|
306 #ifdef NUMPY_REFERENCE
|
fazekasgy@32
|
307 /// This should be all we need to compile without direct dependency,
|
fazekasgy@32
|
308 /// but we don't do that. (it may not work on some platforms)
|
fazekasgy@32
|
309 typedef struct {
|
fazekasgy@32
|
310 int two; /* contains the integer 2 -- simple sanity check */
|
fazekasgy@32
|
311 int nd; /* number of dimensions */
|
fazekasgy@32
|
312 char typekind; /* kind in array --- character code of typestr */
|
fazekasgy@32
|
313 int itemsize; /* size of each element */
|
fazekasgy@32
|
314 int flags; /* flags indicating how the data should be interpreted */
|
fazekasgy@32
|
315 /* must set ARR_HAS_DESCR bit to validate descr */
|
fazekasgy@32
|
316 Py_intptr_t *shape; /* A length-nd array of shape information */
|
fazekasgy@32
|
317 Py_intptr_t *strides; /* A length-nd array of stride information */
|
fazekasgy@32
|
318 void *data; /* A pointer to the first element of the array */
|
fazekasgy@32
|
319 PyObject *descr; /* NULL or data-description (same as descr key */
|
fazekasgy@32
|
320 /* of __array_interface__) -- must set ARR_HAS_DESCR */
|
fazekasgy@32
|
321 /* flag or this will be ignored. */
|
fazekasgy@32
|
322 } PyArrayInterface;
|
fazekasgy@32
|
323
|
fazekasgy@32
|
324 typedef struct PyArrayObject {
|
fazekasgy@32
|
325 PyObject_HEAD
|
fazekasgy@32
|
326 char *data; /* pointer to raw data buffer */
|
fazekasgy@32
|
327 int nd; /* number of dimensions, also called ndim */
|
fazekasgy@32
|
328 npy_intp *dimensions; /* size in each dimension */
|
fazekasgy@32
|
329 npy_intp *strides; /* bytes to jump to get to the
|
fazekasgy@32
|
330 next element in each dimension */
|
fazekasgy@32
|
331 PyObject *base; /* This object should be decref'd
|
fazekasgy@32
|
332 upon deletion of array */
|
fazekasgy@32
|
333 /* For views it points to the original array */
|
fazekasgy@32
|
334 /* For creation from buffer object it points
|
fazekasgy@32
|
335 to an object that shold be decref'd on
|
fazekasgy@32
|
336 deletion */
|
fazekasgy@32
|
337 /* For UPDATEIFCOPY flag this is an array
|
fazekasgy@32
|
338 to-be-updated upon deletion of this one */
|
fazekasgy@32
|
339 PyArray_Descr *descr; /* Pointer to type structure */
|
fazekasgy@32
|
340 int flags; /* Flags describing array -- see below*/
|
fazekasgy@32
|
341 PyObject *weakreflist; /* For weakreferences */
|
fazekasgy@32
|
342 } PyArrayObject;
|
fazekasgy@32
|
343
|
fazekasgy@32
|
344 typedef struct _PyArray_Descr {
|
fazekasgy@32
|
345 PyObject_HEAD
|
fazekasgy@32
|
346 PyTypeObject *typeobj; /* the type object representing an
|
fazekasgy@32
|
347 instance of this type -- should not
|
fazekasgy@32
|
348 be two type_numbers with the same type
|
fazekasgy@32
|
349 object. */
|
fazekasgy@32
|
350 char kind; /* kind for this type */
|
fazekasgy@32
|
351 char type; /* unique-character representing this type */
|
fazekasgy@32
|
352 char byteorder; /* '>' (big), '<' (little), '|'
|
fazekasgy@32
|
353 (not-applicable), or '=' (native). */
|
fazekasgy@32
|
354 char hasobject; /* non-zero if it has object arrays
|
fazekasgy@32
|
355 in fields */
|
fazekasgy@32
|
356 int type_num; /* number representing this type */
|
fazekasgy@32
|
357 int elsize; /* element size for this type */
|
fazekasgy@32
|
358 int alignment; /* alignment needed for this type */
|
fazekasgy@32
|
359 struct _arr_descr \
|
fazekasgy@32
|
360 *subarray; /* Non-NULL if this type is
|
fazekasgy@32
|
361 is an array (C-contiguous)
|
fazekasgy@32
|
362 of some other type
|
fazekasgy@32
|
363 */
|
fazekasgy@32
|
364 PyObject *fields; /* The fields dictionary for this type */
|
fazekasgy@32
|
365 /* For statically defined descr this
|
fazekasgy@32
|
366 is always Py_None */
|
fazekasgy@32
|
367
|
fazekasgy@32
|
368 PyObject *names; /* An ordered tuple of field names or NULL
|
fazekasgy@32
|
369 if no fields are defined */
|
fazekasgy@32
|
370
|
fazekasgy@32
|
371 PyArray_ArrFuncs *f; /* a table of functions specific for each
|
fazekasgy@32
|
372 basic data descriptor */
|
fazekasgy@32
|
373 } PyArray_Descr;
|
fazekasgy@32
|
374
|
fazekasgy@32
|
375 enum NPY_TYPES { NPY_BOOL=0,
|
fazekasgy@32
|
376 NPY_BYTE, NPY_UBYTE,
|
fazekasgy@32
|
377 NPY_SHORT, NPY_USHORT,
|
fazekasgy@32
|
378 NPY_INT, NPY_UINT,
|
fazekasgy@32
|
379 NPY_LONG, NPY_ULONG,
|
fazekasgy@32
|
380 NPY_LONGLONG, NPY_ULONGLONG,
|
fazekasgy@32
|
381 NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE,
|
fazekasgy@32
|
382 NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE,
|
fazekasgy@32
|
383 NPY_OBJECT=17,
|
fazekasgy@32
|
384 NPY_STRING, NPY_UNICODE,
|
fazekasgy@32
|
385 NPY_VOID,
|
fazekasgy@32
|
386 NPY_NTYPES,
|
fazekasgy@32
|
387 NPY_NOTYPE,
|
fazekasgy@32
|
388 NPY_CHAR, /* special flag */
|
fazekasgy@32
|
389 NPY_USERDEF=256 /* leave room for characters */
|
fazekasgy@32
|
390 };
|
fazekasgy@32
|
391 #endif /*NUMPY_REFERENCE*/
|
cannam@33
|
392 #endif
|