Changeset 113
- Timestamp:
- 07/05/07 16:51:15 (5 years ago)
- Files:
-
- trunk/examples/arraytest (added)
- trunk/examples/arraytest/arraytest.d (added)
- trunk/examples/arraytest/readme.txt (added)
- trunk/examples/arraytest/setup.py (added)
- trunk/examples/arraytest/test.py (added)
- trunk/html_doc/class_wrapping.html (modified) (1 diff)
- trunk/html_doc/conversion.html (modified) (1 diff)
- trunk/html_doc/index.html (modified) (1 diff)
- trunk/html_doc/install.html (modified) (1 diff)
- trunk/html_doc/struct_wrapping.html (modified) (1 diff)
- trunk/infrastructure/pyd/class_wrap.d (modified) (4 diffs)
- trunk/infrastructure/pyd/func_wrap.d (modified) (1 diff)
- trunk/infrastructure/pyd/make_object.d (modified) (7 diffs)
- trunk/raw_html/class_wrapping.html (modified) (1 diff)
- trunk/raw_html/conversion.html (modified) (1 diff)
- trunk/raw_html/struct_wrapping.html (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/html_doc/class_wrapping.html
r102 r113 59 59 60 60 <dt><code>struct Init(<span class="t_arg">C</span> ...);</code></dt> 61 <dd>This allows you to expose the class's constructors to Python. If the class provides a zero-argument constructor, there is no need to specify it; it is always available. Each element of <span class="t_arg">C</span> should be a function type. Each function type should correspond to a constructor. (That is, the arguments to the function type should be the same as the arguments to the class constructor. The return type is ignored.) There is an additional limitation at this time: No two constructors may have the same number of arguments. Pyd will always attempt to call the first constructor with the right number of arguments. If you wish to support a constructor with default arguments, you must specify each possible constructor call as a different template argument to this function. The examples show a few uses of the <code>init</code> function.</dd> 61 <dd>This allows you to expose the class's constructors to Python. If the class provides a zero-argument constructor, there is no need to specify it; it is always available. Each element of <span class="t_arg">C</span> should be a function type. Each function type should correspond to a constructor. (That is, the arguments to the function type should be the same as the arguments to the class constructor. The return type is ignored.) There is an additional limitation at this time: No two constructors may have the same number of arguments. Pyd will always attempt to call the first constructor with the right number of arguments. If you wish to support a constructor with default arguments, you must specify each possible constructor call as a different template argument to this function. The examples show a few uses of <code>Init</code>.</dd> 62 63 <dt><code>struct Repr(alias <span class="t_arg">fn</span>);</code></dt> 64 <dd>This allows you to expose a member function of the class as the Python type's <code>__repr__</code> function. The member function must have the signature <code>char[] function()</code>.</dd> 62 65 63 66 <dt><code>struct Iter(<span class="t_arg">iter_t</span>);</code></dt> trunk/html_doc/conversion.html
r86 r113 70 70 <tr><td><a href="class_wrapping.html">Wrapped class</a></td> <td>Wrapped class</td></tr> 71 71 <tr><td>Any callable</td> <td>delegate</td> </tr> 72 <tr><td>Any iterable</td> <td>dynamic array</td> </tr> 72 73 <tr><td>str</td> <td>char[]</td> </tr> 73 74 <tr><td>complex</td> <td>cdouble</td> </tr> trunk/html_doc/index.html
r105 r113 34 34 <p>Pyd includes the <code>meta.Nameof</code> package by Don Clugston. The source files meta.Nameof and meta.Demangle are copyright © 2005-2006 Don Clugston.</p> 35 35 36 <p>Pyd's Trac page can be found <a href="http://dsource.org/projects/pyd/wiki /">here</a>.</p>36 <p>Pyd's Trac page can be found <a href="http://dsource.org/projects/pyd/wiki">here</a>.</p> 37 37 38 38 <p>A simple "hello, world" module might look like this:</p> trunk/html_doc/install.html
r109 r113 32 32 <p>Pyd requires Python 2.4 or newer and the latest version of DMD (on Windows) or GDC (on Linux). At the time of this writing, those versions are DMD 1.00 and GDC 0.21.</p> 33 33 34 <p>Pyd is supported on Windows using the <a href="http://digitalmars.com/d ">DMD</a> compiler and on Linux using <a href="http://dgcc.sourceforge.net/">GDC</a>. Support for Derek Parnell's <code>bud</code> is also planned.</p>34 <p>Pyd is supported on Windows using the <a href="http://digitalmars.com/d/index.html">DMD</a> compiler and on Linux using <a href="http://dgcc.sourceforge.net/">GDC</a>. Support for Derek Parnell's <code>bud</code> is also planned.</p> 35 35 36 36 <p>Release Candidate 1 of Pyd is available on dsource:</p> trunk/html_doc/struct_wrapping.html
r102 r113 55 55 <dd>This wraps a property. It is the same <code>Property</code> struct template used to <a href="class_wrapping.html">wrap class properties</a>.</dd> 56 56 57 <dt><code>struct Repr(alias <span class="t_arg">fn</span>);</code></dt> 58 <dd>This allows you to expose a member function of the struct as the Python type's <code>__repr__</code> function. The member function must have the signature <code>char[] function()</code>. It is the same <code>Repr</code> struct template used when <a href="class_wrapping.html">wrapping classes</a>.</dd> 59 57 60 <dt><code>struct Iter(<span class="t_arg">iter_t</span>);</code></dt> 58 61 <dd>This allows the user to specify a different overload of opApply than the default. (The default is always the one that is lexically first.) It is the same <code>Iter</code> struct template used in <a href="class_wrapping.html">class wrapping</a>.</dd> trunk/infrastructure/pyd/class_wrap.d
r110 r113 177 177 void wrapped_dealloc(PyObject* self) { 178 178 exception_catcher(delegate void() { 179 WrapPyObject_SetObj(self, null);179 WrapPyObject_SetObj(self, cast(T)null); 180 180 self.ob_type.tp_free(self); 181 181 }); … … 183 183 } 184 184 185 template wrapped_repr(T ) {185 template wrapped_repr(T, alias fn) { 186 186 alias wrapped_class_object!(T) wrap_object; 187 187 /// The default repr method calls the class's toString. 188 188 extern(C) 189 PyObject* repr(PyObject* _self) { 190 return exception_catcher({ 191 wrap_object* self = cast(wrap_object*)_self; 192 char[] repr = objToStr(self.d_obj); 193 return _py(repr); 189 PyObject* repr(PyObject* self) { 190 return exception_catcher(delegate PyObject*() { 191 return method_wrap!(T, fn, char[] function()).func(self, null); 194 192 }); 195 193 } … … 430 428 431 429 /** 430 Wraps a method as the class's __repr__ in Python. 431 */ 432 struct Repr(alias fn) { 433 static void call(T, shim)() { 434 alias wrapped_class_type!(T) type; 435 type.tp_repr = &wrapped_repr!(T, fn).repr; 436 } 437 template shim(uint i) { 438 const char[] shim = ""; 439 } 440 } 441 442 /** 432 443 Wraps the constructors of the class. 433 444 … … 722 733 alias wrapped_class_type!(T) type; 723 734 wrapped_object* self = cast(wrapped_object*)_self; 724 if (!is_wrapped!(T) || self is null || (is(T : Object) && cast(T)cast(Object) self.d_objis null)) {735 if (!is_wrapped!(T) || self is null || (is(T : Object) && cast(T)cast(Object)(self.d_obj) is null)) { 725 736 throw new Exception("Error extracting D object from Python object..."); 726 737 } trunk/infrastructure/pyd/func_wrap.d
r110 r113 233 233 return null; 234 234 } 235 C instance = (cast(wrapped_class_object!(C)*)self).d_obj;235 C instance = WrapPyObject_AsObject!(C)(self);//(cast(wrapped_class_object!(C)*)self).d_obj; 236 236 if (instance is null) { 237 237 PyErr_SetString(PyExc_ValueError, "Wrapped class instance is null!"); trunk/infrastructure/pyd/make_object.d
r100 r113 94 94 return PyComplex_FromDoubles(t.re, t.im); 95 95 } else static if (is(T : char[])) { 96 if (t is null) { 97 Py_INCREF(Py_None); 98 return Py_None; 99 } 96 100 return PyString_FromString((t ~ \0).ptr); 97 101 } else static if (is(T : wchar[])) { 102 if (t is null) { 103 Py_INCREF(Py_None); 104 return Py_None; 105 } 98 106 return PyUnicode_FromWideChar(t, t.length); 99 107 // Converts any array (static or dynamic) to a Python list 100 108 } else static if (isArray!(T) || isStaticArray!(T)) { 109 if (t is null) { 110 Py_INCREF(Py_None); 111 return Py_None; 112 } 101 113 PyObject* lst = PyList_New(t.length); 102 114 PyObject* temp; … … 114 126 // Converts any associative array to a Python dict 115 127 } else static if (isAA!(T)) { 128 if (t is null) { 129 Py_INCREF(Py_None); 130 return Py_None; 131 } 116 132 PyObject* dict = PyDict_New(); 117 133 PyObject* ktemp, vtemp; … … 137 153 return dict; 138 154 } else static if (is(T == delegate) || is(T == function)) { 155 if (t is null) { 156 Py_INCREF(Py_None); 157 return Py_None; 158 } 139 159 PydWrappedFunc_Ready!(T)(); 140 160 return WrapPyObject_FromObject(t); 141 161 } else static if (is(T : PydObject)) { 162 if (t is null) { 163 Py_INCREF(Py_None); 164 return Py_None; 165 } 142 166 PyObject* temp = t.ptr(); 143 167 Py_INCREF(temp); … … 145 169 // Convert wrapped type of a PyObject* 146 170 } else static if (is(T == class)) { 171 if (t is null) { 172 Py_INCREF(Py_None); 173 return Py_None; 174 } 147 175 // But only if it actually is a wrapped type. :-) 148 176 PyTypeObject** type = t.classinfo in wrapped_classes; … … 161 189 } else static if (is(typeof(*t) == struct)) { 162 190 if (is_wrapped!(T)) { 191 if (t is null) { 192 Py_INCREF(Py_None); 193 return Py_None; 194 } 163 195 return WrapPyObject_FromObject(t); 164 196 } … … 248 280 // We can only convert to a class if it has been wrapped, and of course 249 281 // we can only convert the object if it is the wrapped type. 250 if (is_wrapped!(T) && cast(T)((cast(wrapped_class_object!(Object)*)o).d_obj) !is null) { 282 if ( 283 is_wrapped!(T) && 284 PyObject_IsInstance(o, cast(PyObject*)&wrapped_class_type!(T)) && 285 cast(T)((cast(wrapped_class_object!(Object)*)o).d_obj) !is null 286 ) { 251 287 return WrapPyObject_AsObject!(T)(o); 252 288 } … … 297 333 if (result is null) handle_exception(); 298 334 return .toString(result).dup; 335 } else static if (is(T E : E[])) { 336 // Dynamic arrays 337 PyObject* iter = PyObject_GetIter(o); 338 if (iter is null) { 339 PyErr_Clear(); 340 could_not_convert!(T)(o); 341 } 342 scope(exit) Py_DECREF(iter); 343 int len = PyObject_Length(o); 344 if (len == -1) { 345 PyErr_Clear(); 346 could_not_convert!(T)(o); 347 } 348 T array; 349 array.length = len; 350 int i = 0; 351 PyObject* item = PyIter_Next(iter); 352 while (item) { 353 try { 354 array[i] = d_type!(E)(item); 355 } catch(PydConversionException e) { 356 Py_DECREF(item); 357 // We re-throw the original conversion exception, rather than 358 // complaining about being unable to convert to an array. The 359 // partially constructed array is left to the GC. 360 throw e; 361 } 362 ++i; 363 Py_DECREF(item); 364 item = PyIter_Next(iter); 365 } 366 return array; 299 367 } else static if (is(cdouble : T)) { 300 368 double real_ = PyComplex_RealAsDouble(o); trunk/raw_html/class_wrapping.html
r102 r113 43 43 44 44 <dt><code>struct Init(<span class="t_arg">C</span> ...);</code></dt> 45 <dd>This allows you to expose the class's constructors to Python. If the class provides a zero-argument constructor, there is no need to specify it; it is always available. Each element of <span class="t_arg">C</span> should be a function type. Each function type should correspond to a constructor. (That is, the arguments to the function type should be the same as the arguments to the class constructor. The return type is ignored.) There is an additional limitation at this time: No two constructors may have the same number of arguments. Pyd will always attempt to call the first constructor with the right number of arguments. If you wish to support a constructor with default arguments, you must specify each possible constructor call as a different template argument to this function. The examples show a few uses of the <code>init</code> function.</dd> 45 <dd>This allows you to expose the class's constructors to Python. If the class provides a zero-argument constructor, there is no need to specify it; it is always available. Each element of <span class="t_arg">C</span> should be a function type. Each function type should correspond to a constructor. (That is, the arguments to the function type should be the same as the arguments to the class constructor. The return type is ignored.) There is an additional limitation at this time: No two constructors may have the same number of arguments. Pyd will always attempt to call the first constructor with the right number of arguments. If you wish to support a constructor with default arguments, you must specify each possible constructor call as a different template argument to this function. The examples show a few uses of <code>Init</code>.</dd> 46 47 <dt><code>struct Repr(alias <span class="t_arg">fn</span>);</code></dt> 48 <dd>This allows you to expose a member function of the class as the Python type's <code>__repr__</code> function. The member function must have the signature <code>char[] function()</code>.</dd> 46 49 47 50 <dt><code>struct Iter(<span class="t_arg">iter_t</span>);</code></dt> trunk/raw_html/conversion.html
r62 r113 54 54 <tr><td><a href="class_wrapping.html">Wrapped class</a></td> <td>Wrapped class</td></tr> 55 55 <tr><td>Any callable</td> <td>delegate</td> </tr> 56 <tr><td>Any iterable</td> <td>dynamic array</td> </tr> 56 57 <tr><td>str</td> <td>char[]</td> </tr> 57 58 <tr><td>complex</td> <td>cdouble</td> </tr> trunk/raw_html/struct_wrapping.html
r102 r113 39 39 <dd>This wraps a property. It is the same <code>Property</code> struct template used to <a href="class_wrapping.html">wrap class properties</a>.</dd> 40 40 41 <dt><code>struct Repr(alias <span class="t_arg">fn</span>);</code></dt> 42 <dd>This allows you to expose a member function of the struct as the Python type's <code>__repr__</code> function. The member function must have the signature <code>char[] function()</code>. It is the same <code>Repr</code> struct template used when <a href="class_wrapping.html">wrapping classes</a>.</dd> 43 41 44 <dt><code>struct Iter(<span class="t_arg">iter_t</span>);</code></dt> 42 45 <dd>This allows the user to specify a different overload of opApply than the default. (The default is always the one that is lexically first.) It is the same <code>Iter</code> struct template used in <a href="class_wrapping.html">class wrapping</a>.</dd>
