Changeset 45
- Timestamp:
- 11/19/06 20:08:43 (7 years ago)
- Files:
-
- trunk/dcompiler.py (modified) (6 diffs)
- trunk/examples/testdll/testdll.d (modified) (3 diffs)
- trunk/html_doc/basics.html (modified) (4 diffs)
- trunk/html_doc/celerid.html (modified) (2 diffs)
- trunk/html_doc/class_wrapping.html (modified) (3 diffs)
- trunk/html_doc/conversion.html (modified) (2 diffs)
- trunk/html_doc/credits.html (added)
- trunk/html_doc/dpyobject.html (modified) (2 diffs)
- trunk/html_doc/except_wrapping.html (modified) (2 diffs)
- trunk/html_doc/func_wrapping.html (modified) (2 diffs)
- trunk/html_doc/index.html (modified) (3 diffs)
- trunk/html_doc/install.html (added)
- trunk/infrastructure/meta/Apply.d (deleted)
- trunk/infrastructure/meta/Bind.d (deleted)
- trunk/infrastructure/meta/Default.d (modified) (4 diffs)
- trunk/infrastructure/meta/FuncMeta.d (deleted)
- trunk/infrastructure/meta/Instantiate.d (deleted)
- trunk/infrastructure/meta/Tuple.d (deleted)
- trunk/infrastructure/meta/Use.d (deleted)
- trunk/infrastructure/meta/VarArg.d (deleted)
- trunk/infrastructure/pyd/class_wrap.d (modified) (13 diffs)
- trunk/infrastructure/pyd/ctor_wrap.d (modified) (3 diffs)
- trunk/infrastructure/pyd/def.d (modified) (1 diff)
- trunk/infrastructure/pyd/dg_convert.d (modified) (2 diffs)
- trunk/infrastructure/pyd/dpyobject.d (modified) (1 diff)
- trunk/infrastructure/pyd/func_wrap.d (modified) (13 diffs)
- trunk/infrastructure/pyd/iteration.d (modified) (4 diffs)
- trunk/infrastructure/pyd/make_object.d (modified) (3 diffs)
- trunk/infrastructure/pyd/op_wrap.d (modified) (20 diffs)
- trunk/infrastructure/pyd/pyd.d (modified) (1 diff)
- trunk/infrastructure/python/2.4 (added)
- trunk/infrastructure/python/2.4/python.d (added)
- trunk/infrastructure/python/2.4/python24_digitalmars.lib (added)
- trunk/infrastructure/python/2.5 (added)
- trunk/infrastructure/python/2.5/python.d (added)
- trunk/infrastructure/python/2.5/python25_digitalmars.lib (added)
- trunk/infrastructure/python/headers (deleted)
- trunk/infrastructure/python/libs (deleted)
- trunk/pydmdvars.bat (modified) (1 diff)
- trunk/setup.py (modified) (3 diffs)
- trunk/version.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/dcompiler.py
r40 r45 32 32 'dpyobject.d', 33 33 'exception.d', 34 # 'ftype.d',35 34 'func_wrap.d', 36 35 'iteration.d', … … 38 37 'op_wrap.d', 39 38 'pyd.d', 40 # 'tuples.d',41 39 ] 42 40 … … 49 47 50 48 _metaFiles = [ 51 'Apply.d',52 'Bind.d',53 49 'Default.d', 54 50 'Demangle.d', 55 'FuncMeta.d',56 'Instantiate.d',57 51 'Nameof.d', 58 'Tuple.d',59 'Use.d',60 52 'Util.d', 61 'VarArg.d',62 53 ] 63 54 … … 153 144 # To sources, add the appropriate D header file python.d, as well as 154 145 # any platform-specific boilerplate. 155 pythonHeaderPath = os.path.join(_infraDir, 'python', 'headers', 'python.d')146 pythonHeaderPath = os.path.join(_infraDir, 'python', _pyVerXDotY, 'python.d') 156 147 # Add the python header's directory to the include path 157 148 includePathOpts += self._includeOpts 158 includePathOpts[-1] = includePathOpts[-1] % os.path.join(_infraDir, 'python', 'headers')149 includePathOpts[-1] = includePathOpts[-1] % os.path.join(_infraDir, 'python', _pyVerXDotY) 159 150 if not os.path.isfile(pythonHeaderPath): 160 151 raise DistutilsPlatformError('Required D translation of Python' … … 188 179 ) 189 180 sources.append(filePath) 190 # Add the infraDir to the include path for Pyd and ST181 # Add the infraDir to the include path for pyd, st, and meta. 191 182 includePathOpts += self._includeOpts 192 183 includePathOpts[-1] = includePathOpts[-1] % os.path.join(_infraDir) … … 451 442 # more convenient to distribute a pre-extracted .lib file to the 452 443 # users and spare them the need for the "Basic Utilities" package. 453 pythonDMDLibPath = _qp(os.path.join(_infraDir, 'python', 'libs',454 _pyVerXDotY,'python%s_digitalmars.lib' % _pyVerXY444 pythonDMDLibPath = _qp(os.path.join(_infraDir, 'python', _pyVerXDotY, 445 'python%s_digitalmars.lib' % _pyVerXY 455 446 )) 456 447 if not os.path.isfile(pythonDMDLibPath): trunk/examples/testdll/testdll.d
r44 r45 4 4 import pyd.pyd; 5 5 //import pyd.ftype; 6 import std.stdio ;6 import std.stdio, std.string; 7 7 8 import meta.Tuple;9 import meta.Apply;8 //import meta.Tuple; 9 //import meta.Apply; 10 10 11 11 void apply_test(int i, char[] s) { … … 14 14 15 15 void foo() { 16 /+ 16 17 alias Tuple!(int, char[]) T; 17 18 T t; … … 19 20 t.val!(1) = "Monkey"; 20 21 apply(&apply_test, t); 22 +/ 23 writefln("20 Monkey"); 21 24 } 22 25 trunk/html_doc/basics.html
r40 r45 11 11 <p><big>Contents</big></p> 12 12 <a class="nav" href="index.html">Main</a><br /> 13 <a class="nav" href="install.html">Installation</a><br /> 13 14 <a class="navcur" href="basics.html">The basics</a><br /> 14 15 <a class="nav" href="celerid.html">CeleriD</a><br /> … … 17 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 18 19 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> 19 <a class="nav" href="dpyobject.html">DPyObject</a> 20 <a class="nav" href="dpyobject.html">DPyObject</a><br /> 21 <a class="nav" href="credits.html">Credits</a> 20 22 </div> 21 23 … … 23 25 24 26 <h1>The basics</h1> 25 26 <h3>Installation and requirements</h3>27 28 <p>Pyd requires Python 2.4 or newer and the latest version of DMD.</p>29 30 <p>At the moment, Pyd is only supported on Windows using the <a href="http://digitalmars.com/d/index.html">DMD</a> compiler. GDC support has been written, but Pyd cannot yet be compiled with GDC (due to <a href="http://d.puremagic.com/issues/show_bug.cgi?id=311">this bug</a>). Once GDC support is available, Pyd should work on Linux. Support for Derek Parnell's Build is also planned.</p>31 32 <p>Because Pyd is still in development, it is only available via Subversion. The repository is located <a href="http://svn.dsource.org/projects/pyd/trunk">here</a>.</p>33 34 <p>Pyd installs itself as a Python package called <a href="celerid.html"><code>celerid</code></a>. Once you have downloaded the "trunk" directory, simply run <code>python setup.py install</code>, and the <code>celerid</code> directory will be created in Python's site-packages directory.</p>35 27 36 28 <h3>Module basics</h3> … … 60 52 61 53 <p>Due to the way in which Pyd implements function and class wrapping, any calls to <code>def</code> must occur <em>before</em> the call to <code>module_init</code>, and any calls to <code>finalize_class</code> must occur <em>after</em> the call. I know this seems like a rather arbitrary rule, but it is important. Calls to <code>def</code> in the wrong place will simply be ignored, and calls to <code>finalize_class</code> in the wrong place will throw an assert. (And this assert will cause the Python interpreter to crash. So be warned.)</p> 54 55 <p>It is important that no D exceptions escape from the init function. If you put any of your own code in the init function, be sure to guard it aginst exceptions. The <a href="except_wrapping.html">exception wrapping</a> facilities of Pyd provide some useful functions for this purpose.</p> 62 56 </div> 63 57 trunk/html_doc/celerid.html
r35 r45 11 11 <p><big>Contents</big></p> 12 12 <a class="nav" href="index.html">Main</a><br /> 13 <a class="nav" href="install.html">Installation</a><br /> 13 14 <a class="nav" href="basics.html">The basics</a><br /> 14 15 <a class="navcur" href="celerid.html">CeleriD</a><br /> … … 17 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 18 19 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> 19 <a class="nav" href="dpyobject.html">DPyObject</a> 20 <a class="nav" href="dpyobject.html">DPyObject</a><br /> 21 <a class="nav" href="credits.html">Credits</a> 20 22 </div> 21 23 trunk/html_doc/class_wrapping.html
r44 r45 11 11 <p><big>Contents</big></p> 12 12 <a class="nav" href="index.html">Main</a><br /> 13 <a class="nav" href="install.html">Installation</a><br /> 13 14 <a class="nav" href="basics.html">The basics</a><br /> 14 15 <a class="nav" href="celerid.html">CeleriD</a><br /> … … 17 18 <a class="navcur" href="class_wrapping.html">Class wrapping</a><br /> 18 19 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> 19 <a class="nav" href="dpyobject.html">DPyObject</a> 20 <a class="nav" href="dpyobject.html">DPyObject</a><br /> 21 <a class="nav" href="credits.html">Credits</a> 20 22 </div> 21 23 … … 47 49 </dd> 48 50 49 <dt><code>static void init(<span class="t_arg">C 1</span>, <span class="t_arg">C2</span>, <span class="t_arg">C3</span>, ..., <span class="t_arg">C<i>n</i></span>) ();</code></dt>50 <dd>This allows you to expose anywhere from zero to 10 of 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 of <span class="t_arg">C<i>n</i></span> should be a function type. Each function type should correspond to a constructor. (That is, the arguments to the function should be the same as 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>51 <dt><code>static void init(<span class="t_arg">C</span> ...) ();</code></dt> 52 <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 should be the same as 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> 51 53 52 54 <dt><code>static void iter(<span class="t_arg">iter_t</span>) ();</code></dt> trunk/html_doc/conversion.html
r35 r45 11 11 <p><big>Contents</big></p> 12 12 <a class="nav" href="index.html">Main</a><br /> 13 <a class="nav" href="install.html">Installation</a><br /> 13 14 <a class="nav" href="basics.html">The basics</a><br /> 14 15 <a class="nav" href="celerid.html">CeleriD</a><br /> … … 17 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 18 19 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> 19 <a class="nav" href="dpyobject.html">DPyObject</a> 20 <a class="nav" href="dpyobject.html">DPyObject</a><br /> 21 <a class="nav" href="credits.html">Credits</a> 20 22 </div> 21 23 trunk/html_doc/dpyobject.html
r35 r45 11 11 <p><big>Contents</big></p> 12 12 <a class="nav" href="index.html">Main</a><br /> 13 <a class="nav" href="install.html">Installation</a><br /> 13 14 <a class="nav" href="basics.html">The basics</a><br /> 14 15 <a class="nav" href="celerid.html">CeleriD</a><br /> … … 17 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 18 19 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> 19 <a class="navcur" href="dpyobject.html">DPyObject</a> 20 <a class="navcur" href="dpyobject.html">DPyObject</a><br /> 21 <a class="nav" href="credits.html">Credits</a> 20 22 </div> 21 23 trunk/html_doc/except_wrapping.html
r35 r45 11 11 <p><big>Contents</big></p> 12 12 <a class="nav" href="index.html">Main</a><br /> 13 <a class="nav" href="install.html">Installation</a><br /> 13 14 <a class="nav" href="basics.html">The basics</a><br /> 14 15 <a class="nav" href="celerid.html">CeleriD</a><br /> … … 17 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 18 19 <a class="navcur" href="except_wrapping.html">Exception wrapping</a><br /> 19 <a class="nav" href="dpyobject.html">DPyObject</a> 20 <a class="nav" href="dpyobject.html">DPyObject</a><br /> 21 <a class="nav" href="credits.html">Credits</a> 20 22 </div> 21 23 trunk/html_doc/func_wrapping.html
r41 r45 11 11 <p><big>Contents</big></p> 12 12 <a class="nav" href="index.html">Main</a><br /> 13 <a class="nav" href="install.html">Installation</a><br /> 13 14 <a class="nav" href="basics.html">The basics</a><br /> 14 15 <a class="nav" href="celerid.html">CeleriD</a><br /> … … 17 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 18 19 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> 19 <a class="nav" href="dpyobject.html">DPyObject</a> 20 <a class="nav" href="dpyobject.html">DPyObject</a><br /> 21 <a class="nav" href="credits.html">Credits</a> 20 22 </div> 21 23 trunk/html_doc/index.html
r44 r45 11 11 <p><big>Contents</big></p> 12 12 <a class="navcur" href="index.html">Main</a><br /> 13 <a class="nav" href="install.html">Installation</a><br /> 13 14 <a class="nav" href="basics.html">The basics</a><br /> 14 15 <a class="nav" href="celerid.html">CeleriD</a><br /> … … 17 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 18 19 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> 19 <a class="nav" href="dpyobject.html">DPyObject</a> 20 <a class="nav" href="dpyobject.html">DPyObject</a><br /> 21 <a class="nav" href="credits.html">Credits</a> 20 22 </div> 21 23 … … 23 25 24 26 <h1>Pyd</h1> 25 <p>Pyd is a library for the D programming language that wraps the raw <a href="http://docs.python.org/api/api.html">Python/C API</a> with a cleaner, simpler interface. It makes exposing raw D functions and classes to Python almost trivially simple. It bears certain similarities to <a href="http://www.boost.org/libs/python/doc/">Boost.Python</a>, and indeed Boost.Python is a major influence on Pyd. </p>27 <p>Pyd is a library for the D programming language that wraps the raw <a href="http://docs.python.org/api/api.html">Python/C API</a> with a cleaner, simpler interface. It makes exposing raw D functions and classes to Python almost trivially simple. It bears certain similarities to <a href="http://www.boost.org/libs/python/doc/">Boost.Python</a>, and indeed Boost.Python is a major influence on Pyd. Pyd was written by Kirk McDonald.</p> 26 28 27 <p>Pyd also comes with its own extension to Python's <a href="http://docs.python.org/dist/dist.html">distutils</a>, called <a href="celerid.html">CeleriD</a>, making the building of extension modules quite easy.</p> 29 <p>Pyd also comes with its own extension to Python's <a href="http://docs.python.org/dist/dist.html">distutils</a>, called <a href="celerid.html">CeleriD</a>, making the building of extension modules quite easy. CeleriD was originally written by David Rushby and is currently maintained by Kirk McDonald.</p> 30 31 <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> 32 33 <!-- Not documented, yet. 34 <p>Pyd includes its own metaprogramming library, <code>meta</code>, which was written by Tomasz Stachowiak, Don Clugston, and Kirk McDonald. The <code>meta</code> library is documented <a href="meta/index.html">here</a>.</code> 35 --> 28 36 29 37 <p>Pyd's Trac page can be found <a href="http://dsource.org/projects/pyd/wiki">here</a>.</p> trunk/infrastructure/meta/Default.d
r40 r45 4 4 module meta.Default; 5 5 6 private import meta.FuncMeta; 7 private import meta.Tuple; 8 private import meta.Nameof; 9 private import meta.Util; 6 private import std.traits; 7 private import std.typetuple; 10 8 11 9 /** … … 17 15 18 16 template firstArgsT(alias fn, uint args, fn_t = typeof(&fn)) { 19 alias Ret Type!(fn_t) R;20 alias funcDelegInfoT!(fn_t) Info;17 alias ReturnType!(fn_t) R; 18 alias ParameterTypeTuple!(fn_t) T; 21 19 22 // Shortcut for ArgType 23 template A(uint a) { 24 // The -1 is pointless; it dates from a time the function 25 // metaprogramming module was 1-indexed for function arguments. 26 alias Info.Meta.ArgType!(a-1) A; 27 } 28 29 static if (args == 0) { 30 R func() { 31 return fn(); 32 } 33 } else static if (args == 1) { 34 R func(A!(1) a1) { 35 return fn(a1); 36 } 37 } else static if (args == 2) { 38 R func(A!(1) a1, A!(2) a2) { 39 return fn(a1, a2); 40 } 41 } else static if (args == 3) { 42 R func(A!(1) a1, A!(2) a2, A!(3) a3) { 43 return fn(a1, a2, a3); 44 } 45 } else static if (args == 4) { 46 R func(A!(1) a1, A!(2) a2, A!(3) a3, A!(4) a4) { 47 return fn(a1, a2, a3, a4); 48 } 49 } else static if (args == 5) { 50 R func(A!(1) a1, A!(2) a2, A!(3) a3, A!(4) a4, A!(5) a5) { 51 return fn(a1, a2, a3, a4, a5); 52 } 53 } else static if (args == 6) { 54 R func(A!(1) a1, A!(2) a2, A!(3) a3, A!(4) a4, A!(5) a5, A!(6) a6) { 55 return fn(a1, a2, a3, a4, a5, a6); 56 } 57 } else static if (args == 7) { 58 R func(A!(1) a1, A!(2) a2, A!(3) a3, A!(4) a4, A!(5) a5, A!(6) a6, A!(7) a7) { 59 return fn(a1, a2, a3, a4, a5, a6, a7); 60 } 61 } else static if (args == 8) { 62 R func(A!(1) a1, A!(2) a2, A!(3) a3, A!(4) a4, A!(5) a5, A!(6) a6, A!(7) a7, A!(8) a8) { 63 return fn(a1, a2, a3, a4, a5, a6, a7, a8); 64 } 65 } else static if (args == 9) { 66 R func(A!(1) a1, A!(2) a2, A!(3) a3, A!(4) a4, A!(5) a5, A!(6) a6, A!(7) a7, A!(8) a8, A!(9) a9) { 67 return fn(a1, a2, a3, a4, a5, a6, a7, a8, a9); 68 } 69 } else static if (args == 10) { 70 R func(A!(1) a1, A!(2) a2, A!(3) a3, A!(4) a4, A!(5) a5, A!(6) a6, A!(7) a7, A!(8) a8, A!(9) a9, A!(10) a10) { 71 return fn(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); 20 R func(T[0 .. args] t) { 21 static if (is(R == void)) { 22 fn(t); 23 return; 24 } else { 25 return fn(t); 72 26 } 73 27 } 74 28 } 75 29 76 template defaultsTupleT(alias fn, uint MIN_ARGS, fn_t = typeof(&fn), uint current=MIN_ARGS, T = EmptyTuple) {77 alias funcDelegInfoT!(fn_t) Meta;78 const uint MAX_ARGS = Meta.numArgs;30 template defaultsTupleT(alias fn, uint MIN_ARGS, fn_t = typeof(&fn), uint current=MIN_ARGS, T ...) { 31 alias ParameterTypeTuple!(fn_t) Tu; 32 const uint MAX_ARGS = Tu.length; 79 33 static if (current > MAX_ARGS) { 80 34 alias T type; 81 35 } else { 82 alias defaultsTupleT!(fn, MIN_ARGS, fn_t, current+1, T.mix.appendT!(typeof(&firstArgs!(fn, current, fn_t)))).type type; 83 } 84 } 85 86 void loop(alias fn, fn_t, uint i, T)(T* t) { 87 static if (i < T.length) { 88 const uint args = funcDelegInfoT!(typeof(t.val!(i))).numArgs; 89 t.val!(i) = &firstArgs!(fn, args, fn_t); 90 loop!(fn, fn_t, i+1, T)(t); 36 alias defaultsTupleT!(fn, MIN_ARGS, fn_t, current+1, T, typeof(&firstArgs!(fn, current, fn_t))).type type; 91 37 } 92 38 } … … 96 42 calls to that function, as per its default arguments. 97 43 */ 98 defaultsTupleT!(fn, MIN_ARGS, fn_t).type defaultsTuple(alias fn, uint MIN_ARGS, fn_t = typeof(&fn)) () { 44 void defaultsTuple(alias fn, uint MIN_ARGS, fn_t = typeof(&fn)) ( 45 void delegate(defaultsTupleT!(fn, MIN_ARGS, fn_t).type) dg 46 ) { 99 47 alias defaultsTupleT!(fn, MIN_ARGS, fn_t).type T; 100 48 T t; 101 loop!(fn, fn_t, 0, T)(&t); 102 return t; 49 foreach(i, arg; t) { 50 t[i] = &firstArgs!(fn, ParameterTypeTuple!(typeof(t[i])).length, fn_t); 51 } 52 dg(t); 103 53 } 104 54 … … 125 75 126 76 template minArgsT(alias fn, fn_t = typeof(&fn)) { 127 alias funcDelegInfoT!(fn_t) Info;77 alias ParameterTypeTuple!(fn_t) T; 128 78 129 template A(uint i) { 130 alias Info.Meta.ArgType!(i) A; 131 } 132 133 A!(i) I(uint i)() { 134 return A!(i).init; 79 T[i] I(uint i)() { 80 return T[i].init; 135 81 } 136 82 trunk/infrastructure/pyd/class_wrap.d
r41 r45 34 34 35 35 import meta.Default; 36 import meta.FuncMeta;37 import meta.Tuple;38 36 import meta.Nameof; 39 37 40 38 import std.string; 39 import std.traits; 41 40 } 42 41 … … 61 60 /// The type object, an instance of PyType_Type 62 61 static PyTypeObject wrapped_class_type = { 63 1, 64 null, 62 1, /*ob_refcnt*/ 63 null, /*ob_type*/ 65 64 0, /*ob_size*/ 66 65 null, /*tp_name*/ … … 82 81 null, /*tp_setattro*/ 83 82 null, /*tp_as_buffer*/ 84 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/83 0, /*tp_flags*/ 85 84 null, /*tp_doc*/ 86 null, /* tp_traverse*/87 null, /* tp_clear*/88 null, /* tp_richcompare*/89 0, /* tp_weaklistoffset*/90 null, /* tp_iter*/91 null, /* tp_iternext*/92 null, /* tp_methods*/93 null, /* tp_members*/94 null, /* tp_getset*/95 null, /* tp_base*/96 null, /* tp_dict*/97 null, /* tp_descr_get*/98 null, /* tp_descr_set*/99 0, /* tp_dictoffset*/100 null, /* tp_init*/101 null, /* tp_alloc*/102 &wrapped_methods!(T).wrapped_new, /* tp_new*/103 null, /* tp_free*/104 null, /* tp_is_gc*/105 null, /* tp_bases*/106 null, /* tp_mro*/107 null, /* tp_cache*/108 null, /* tp_subclasses*/109 null, /* tp_weaklist*/110 null, /* tp_del*/85 null, /*tp_traverse*/ 86 null, /*tp_clear*/ 87 null, /*tp_richcompare*/ 88 0, /*tp_weaklistoffset*/ 89 null, /*tp_iter*/ 90 null, /*tp_iternext*/ 91 null, /*tp_methods*/ 92 null, /*tp_members*/ 93 null, /*tp_getset*/ 94 null, /*tp_base*/ 95 null, /*tp_dict*/ 96 null, /*tp_descr_get*/ 97 null, /*tp_descr_set*/ 98 0, /*tp_dictoffset*/ 99 null, /*tp_init*/ 100 null, /*tp_alloc*/ 101 &wrapped_methods!(T).wrapped_new, /*tp_new*/ 102 null, /*tp_free*/ 103 null, /*tp_is_gc*/ 104 null, /*tp_bases*/ 105 null, /*tp_mro*/ 106 null, /*tp_cache*/ 107 null, /*tp_subclasses*/ 108 null, /*tp_weaklist*/ 109 null, /*tp_del*/ 111 110 }; 112 111 } 112 113 // The set of all instances of this class that are passed into Python. Keeping 114 // references here in D is needed to keep the GC happy. The integer value is 115 // used to make this a sort of poor man's multiset. 116 template wrap_class_instances(T) { 117 int[T] wrap_class_instances; 118 } 119 120 /** 121 * A useful check for whether a given class has been wrapped. Mainly used by 122 * the conversion functions (see make_object.d), but possibly useful elsewhere. 123 */ 124 template is_wrapped(T) { 125 bool is_wrapped = false; 126 } 127 128 // The list of wrapped methods for this class. 129 template wrapped_method_list(T) { 130 PyMethodDef[] wrapped_method_list = [ 131 { null, null, 0, null } 132 ]; 133 } 134 135 // The list of wrapped properties for this class. 136 template wrapped_prop_list(T) { 137 static PyGetSetDef[] wrapped_prop_list = [ 138 { null, null, null, null, null } 139 ]; 140 } 141 142 ////////////////////// 143 // STANDARD METHODS // 144 ////////////////////// 113 145 114 146 /// Various wrapped methods … … 133 165 extern(C) 134 166 void wrapped_dealloc(PyObject* self) { 135 exception_catcher(delegate PyObject*() { 167 //exception_catcher(delegate PyObject*() { 168 try { 136 169 WrapPyObject_SetObj(self, null); 137 self.ob_type.tp_free(self); 138 return null; 139 }); 170 } catch { } 171 self.ob_type.tp_free(self); 172 return null; 173 //}); 140 174 } 141 175 } … … 154 188 } 155 189 156 ///157 template wrapped_init(T) {158 alias wrapped_class_object!(T) wrap_object;159 /// The default _init method calls the class's zero-argument constructor.160 extern(C)161 int init(PyObject* self, PyObject* args, PyObject* kwds) {162 return exception_catcher({163 WrapPyObject_SetObj(self, new T);164 return 0;165 });166 }167 }168 169 190 // This template gets an alias to a property and derives the types of the 170 191 // getter form and the setter form. It requires that the getter form return the … … 173 194 // This may be either the getter or the setter 174 195 alias typeof(&p) p_t; 175 alias funcDelegInfoT!(p_t) Info;196 alias ParameterTypeTuple!(p_t) Info; 176 197 // This means it's the getter 177 static if (Info. numArgs== 0) {198 static if (Info.length == 0) { 178 199 alias p_t getter_type; 179 200 // The setter may return void, or it may return the newly set attribute. 180 alias typeof(p(Ret Type!(p_t).init)) function(RetType!(p_t)) setter_type;201 alias typeof(p(ReturnType!(p_t).init)) function(ReturnType!(p_t)) setter_type; 181 202 // This means it's the setter 182 203 } else { 183 204 alias p_t setter_type; 184 alias Info .Meta.ArgType!(0)function() getter_type;205 alias Info[0] function() getter_type; 185 206 } 186 207 } … … 216 237 } 217 238 218 // The set of all instances of this class that are passed into Python. Keeping 219 // references here in D is needed to keep the GC happy. The integer value is 220 // used to make this a sort of poor man's multiset. 221 template wrap_class_instances(T) { 222 int[T] wrap_class_instances; 223 } 224 225 /** 226 * A useful check for whether a given class has been wrapped. Mainly used by 227 * the conversion functions (see make_object.d), but possibly useful elsewhere. 228 */ 229 template is_wrapped(T) { 230 bool is_wrapped = false; 231 } 232 233 // The list of wrapped methods for this class. 234 template wrapped_method_list(T) { 235 static PyMethodDef[] wrapped_method_list = [ 236 { null, null, 0, null } 237 ]; 238 } 239 240 // The list of wrapped properties for this class. 241 template wrapped_prop_list(T) { 242 static PyGetSetDef[] wrapped_prop_list = [ 243 { null, null, null, null, null } 244 ]; 245 } 239 ////////////////////////////// 240 // CLASS WRAPPING INTERFACE // 241 ////////////////////////////// 246 242 247 243 /** … … 321 317 * the same number of arguments. 322 318 */ 323 static void init(C 1=int, C2=int, C3=int, C4=int, C5=int, C6=int, C7=int, C8=int, C9=int, C10=int) () {319 static void init(C ...) () { 324 320 wrapped_class_type!(T).tp_init = 325 &wrapped_ctors!(T, Tuple!(C1, C2, C3, C4, C5, C6, C7, C8, C9, C10)).init_func;321 &wrapped_ctors!(T, C).init_func; 326 322 } 327 323 … … 367 363 368 364 assert(DPy_Module_p !is null, "Must initialize module before wrapping classes."); 369 char[] module_name = .toString(PyModule_GetName(DPy_Module_p)); 370 365 char[] module_name = toString(PyModule_GetName(DPy_Module_p)); 371 366 // Fill in missing values 372 type.ob_type = PyType_Type_p; 367 type.ob_type = PyType_Type_p(); 368 //type.tp_new = &(wrapped_methods!(T).wrapped_new); 369 //type.tp_dealloc = &(wrapped_methods!(T).wrapped_dealloc); 373 370 type.tp_basicsize = (wrapped_class_object!(T)).sizeof; 374 371 type.tp_doc = name ~ " objects" ~ \0; 372 type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; 375 373 //type.tp_new = &PyType_GenericNew; 376 type.tp_repr = &wrapped_repr!(T).repr;374 //type.tp_repr = &wrapped_repr!(T).repr; 377 375 type.tp_methods = wrapped_method_list!(T); 378 376 type.tp_name = module_name ~ "." ~ name ~ \0; … … 409 407 410 408 // If a ctor wasn't supplied, try the default. 411 if (type.tp_init is null) {412 type.tp_init = &wrapped_init!(T).init;413 }409 //if (type.tp_init is null) { 410 // type.tp_init = &wrapped_init!(T).init; 411 //} 414 412 if (PyType_Ready(&type) < 0) { 415 413 // XXX: This will probably crash the interpreter, as it isn't normally … … 422 420 wrapped_classes[typeid(T)] = true; 423 421 } 422 423 /////////////////////// 424 // PYD API FUNCTIONS // 425 /////////////////////// 424 426 425 427 /** … … 442 444 } 443 445 446 /** 447 * Returns the object contained in a Python wrapped type. 448 */ 444 449 T WrapPyObject_AsObject(T) (PyObject* _self) { 445 450 alias wrapped_class_object!(T) wrapped_object; … … 469 474 if (t !is null) wrap_class_instances!(T)[t]++; 470 475 } 476 trunk/infrastructure/pyd/ctor_wrap.d
r40 r45 28 28 private import pyd.make_object; 29 29 30 private import meta.Tuple; 31 private import meta.Bind; 32 private import meta.Instantiate; 30 private import std.traits; 33 31 34 template ctor_redirect(T) { 35 T call_ctor()() { 36 return new T(); 37 } 38 39 T call_ctor(T1)(T1 t1) { 40 return new T(t1); 41 } 42 43 T call_ctor(T1, T2)(T1 t1, T2 t2) { 44 return new T(t1, t2); 45 } 46 47 T call_ctor(T1, T2, T3)(T1 t1, T2 t2, T3 t3) { 48 return new T(t1, t2, t3); 49 } 50 51 T call_ctor(T1, T2, T3, T4)(T1 t1, T2 t2, T3 t3, T4 t4) { 52 return new T(t1, t2, t3, t4); 53 } 54 55 T call_ctor(T1, T2, T3, T4, T5)(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { 56 return new T(t1, t2, t3, t4, t5); 57 } 58 59 T call_ctor(T1, T2, T3, T4, T5, T6)(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { 60 return new T(t1, t2, t3, t4, t5, t6); 61 } 62 63 T call_ctor(T1, T2, T3, T4, T5, T6, T7)(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) { 64 return new T(t1, t2, t3, t4, t5, t6, t7); 65 } 66 67 T call_ctor(T1, T2, T3, T4, T5, T6, T7, T8)(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) { 68 return new T(t1, t2, t3, t4, t5, t6, t7, t8); 69 } 70 71 T call_ctor(T1, T2, T3, T4, T5, T6, T7, T8, T9)(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) { 72 return new T(t1, t2, t3, t4, t5, t6, t7, t8, t9); 73 } 74 75 T call_ctor(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10) { 76 return new T(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); 32 T call_ctor(T, Tu ...)(Tu t) { 33 return new T(t); 34 } 35 36 // The default __init__ method calls the class's zero-argument constructor. 37 template wrapped_init(T) { 38 alias wrapped_class_object!(T) wrap_object; 39 extern(C) 40 int init(PyObject* self, PyObject* args, PyObject* kwds) { 41 return exception_catcher({ 42 WrapPyObject_SetObj(self, new T); 43 return 0; 44 }); 77 45 } 78 46 } … … 81 49 // Tuples, which each describe a ctor of T, and uses them to wrap a Python 82 50 // tp_init function. 83 template wrapped_ctors(T, Tu) {51 template wrapped_ctors(T, C ...) { 84 52 alias wrapped_class_object!(T) wrap_object; 85 86 // The user can provide ctor footprints as either function pointer types87 // or as tuples. This converts either to a tuple.88 template ctorAsTuple(T) {89 static if (isTuple!(T))90 alias T ctorAsTuple;91 else static if (is(typeof(*T) == function))92 alias getFuncTuple!(T) ctorAsTuple;93 }94 95 // This loops through the passed Tuple type and extracts the actual ctor96 // types.97 template loop(uint current, NewTu = EmptyTuple) {98 static if (current == Tu.length || is(typeof(Tu.mix.val!(current))==int)) {99 alias NewTu type;100 } else {101 alias loop!(current+1, NewTu.mix.appendT!(ctorAsTuple!(typeof(Tu.mix.val!(current))))).type type;102 }103 }104 alias loop!(0).type Ctors;105 106 // Checks each element of the Ctors tuple against the number of arguments107 // passed in from Python. Then, it calls the ctor with the passed-in108 // arguments.109 int findAndCallCtor(uint current) (PyObject* self, PyObject* args, int argCount) {110 static if (current == Ctors.length) {111 // No match, handle error112 PyErr_SetString(PyExc_TypeError, "Unsupported number of constructor arguments.");113 return -1;114 } else {115 alias typeof(Ctors.mix.val!(current)) Ctor;116 if (Ctor.length == argCount) {117 alias instantiateTemplate!(ctor_redirect!(T).call_ctor, Ctor) fn;118 WrapPyObject_SetObj(self, py_call(&fn, args));119 return 0;120 } else {121 return findAndCallCtor!(current+1)(self, args, argCount);122 }123 }124 }125 53 126 54 extern(C) … … 136 64 } 137 65 } 138 return findAndCallCtor!(0) (self, args, len); 66 // find another Ctor 67 C c; 68 foreach(i, arg; c) { 69 alias ParameterTypeTuple!(typeof(arg)) Ctor; 70 if (Ctor.length == len) { 71 alias call_ctor!(T, ParameterTypeTuple!(typeof(arg))) fn; 72 WrapPyObject_SetObj(self, py_call(&fn, args)); 73 return 0; 74 } 75 } 76 // No ctor found 77 PyErr_SetString(PyExc_TypeError, "Unsupported number of constructor arguments."); 78 return -1; 139 79 }); 140 80 } trunk/infrastructure/pyd/def.d
r40 r45 24 24 private import python; 25 25 26 private import pyd.class_wrap;27 private import pyd.dg_convert;28 private import pyd.exception;29 26 private import pyd.func_wrap; 30 private import pyd.make_object;31 27 32 28 private import meta.Default; 33 29 private import meta.Nameof; 34 35 private import std.string;36 30 37 31 private trunk/infrastructure/pyd/dg_convert.d
r40 r45 22 22 23 23 /** 24 * This module contains some more or less dirty hacks for converting between25 * function and delegate types. Its contents are strictly for internal use26 * within Pyd.24 * This module used to contain some more or less dirty hacks for converting 25 * between function and delegate types. As of DMD 0.174, the language has 26 * built-in support for hacking apart delegates like this. Hooray! 27 27 */ 28 28 module pyd.dg_convert; 29 29 30 private import meta.FuncMeta;30 private import std.traits; 31 31 32 32 template fn_to_dgT(Fn) { 33 alias funcDelegInfoT!(Fn) Info; 34 const uint ARGS = Info.numArgs; 35 alias RetType!(Fn) Ret; 33 alias ParameterTypeTuple!(Fn) T; 34 alias ReturnType!(Fn) Ret; 36 35 37 template A(uint i) { 38 alias Info.Meta.ArgType!(i) A; 39 } 40 41 static if (ARGS == 0) { 42 alias Ret delegate() type; 43 } else static if (ARGS == 1) { 44 alias Ret delegate(A!(0)) type; 45 } else static if (ARGS == 2) { 46 alias Ret delegate(A!(0), A!(1)) type; 47 } else static if (ARGS == 3) { 48 alias Ret delegate(A!(0), A!(1), A!(2)) type; 49 } else static if (ARGS == 4) { 50 alias Ret delegate(A!(0), A!(1), A!(2), A!(3)) type; 51 } else static if (ARGS == 5) { 52 alias Ret delegate(A!(0), A!(1), A!(2), A!(3), A!(4)) type; 53 } else static if (ARGS == 6) { 54 alias Ret delegate(A!(0), A!(1), A!(2), A!(3), A!(4), A!(5)) type; 55 } else static if (ARGS == 7) { 56 alias Ret delegate(A!(0), A!(1), A!(2), A!(3), A!(4), A!(5), A!(6)) type; 57 } else static if (ARGS == 8) { 58 alias Ret delegate(A!(0), A!(1), A!(2), A!(3), A!(4), A!(5), A!(6), A!(7)) type; 59 } else static if (ARGS == 9) { 60 alias Ret delegate(A!(0), A!(1), A!(2), A!(3), A!(4), A!(5), A!(6), A!(7), A!(8)) type; 61 } else static if (ARGS == 10) { 62 alias Ret delegate(A!(0), A!(1), A!(2), A!(3), A!(4), A!(5), A!(6), A!(7), A!(8), A!(9)) type; 63 } 36 alias Ret delegate(T) type; 64 37 } 65 38 … … 71 44 } 72 45 73 struct FakeDG { 74 Object instance; 75 void* fn; 46 /** 47 * This template function converts a pointer to a member function into a 48 * delegate. 49 */ 50 fn_to_dg!(Fn) dg_wrapper(T, Fn) (T t, Fn fn) { 51 fn_to_dg!(Fn) dg; 52 dg.ptr = t; 53 dg.funcptr = fn; 54 55 return dg; 76 56 } 77 57 78 template dg_union(Fn) {79 union dg_union {80 FakeDG fake_dg;81 fn_to_dg!(Fn) real_dg;82 }83 }84 85 /**86 * This dirty hack of a template function converts a pointer to a member87 * function into a delegate.88 */89 fn_to_dg!(Fn) dg_wrapper(T, Fn) (T t, Fn fn) {90 dg_union!(Fn) u;91 u.fake_dg.instance = t;92 u.fake_dg.fn = cast(void*)fn;93 94 return u.real_dg;95 }96 trunk/infrastructure/pyd/dpyobject.d
r29 r45 453 453 int opApply(int delegate(inout DPyObject, inout DPyObject) dg) { 454 454 PyObject* key, value; 455 int pos = 0, result = 0; 455 version(Python_2_5_Or_Later) { 456 Py_ssize_t pos = 0; 457 } else { 458 int pos = 0; 459 } 460 int result = 0; 456 461 DPyObject k, v; 457 462 trunk/infrastructure/pyd/func_wrap.d
r44 r45 30 30 import pyd.make_object; 31 31 32 import meta.Tuple;33 import meta.Bind;34 import meta.FuncMeta;35 import meta.Apply;36 32 import meta.Default; 37 33 import meta.Nameof; 38 34 39 35 import std.string; 36 import std.traits; 40 37 } 41 38 42 39 // Builds a Python callable object from a delegate or function pointer. 43 template DPyFunc_FromDG(T) { 44 PyObject* DPyFunc_FromDG(T dg) { 45 alias wrapped_class_type!(T) type; 46 alias wrapped_class_object!(T) obj; 47 if (!is_wrapped!(T)) { 48 type.ob_type = PyType_Type_p; 49 type.tp_basicsize = obj.sizeof; 50 type.tp_name = "DPyFunc"; 51 type.tp_call = &wrapped_func_call!(T).call; 52 PyType_Ready(&type); 53 is_wrapped!(T) = true; 54 wrapped_classes[typeid(T)] = true; 55 } 56 obj* func = cast(obj*)type.tp_new(&type, null, null); 57 func.d_obj = dg; 58 wrap_class_instances!(T)[dg]++; 59 return cast(PyObject*)func; 60 } 61 } 62 63 // Populates the tuple t with converted arguments from the PyTuple args 64 private void loop(T, uint i = 0) (T* t, PyObject* args) { 65 static if (i < T.length) { 66 t.val!(i) = d_type!(typeof(t.val!(i)))(PyTuple_GetItem(args, i)); 67 loop!(T, i+1)(t, args); 68 } 40 PyObject* DPyFunc_FromDG(T) (T dg) { 41 alias wrapped_class_type!(T) type; 42 alias wrapped_class_object!(T) obj; 43 if (!is_wrapped!(T)) { 44 type.ob_type = PyType_Type_p; 45 type.tp_new = &wrapped_methods!(T).wrapped_new; 46 type.tp_dealloc = &wrapped_methods!(T).wrapped_dealloc; 47 type.tp_basicsize = obj.sizeof; 48 type.tp_name = "DPyFunc"; 49 type.tp_call = &wrapped_func_call!(T).call; 50 PyType_Ready(&type); 51 is_wrapped!(T) = true; 52 wrapped_classes[typeid(T)] = true; 53 } 54 obj* func = cast(obj*)type.tp_new(&type, null, null); 55 func.d_obj = dg; 56 wrap_class_instances!(T)[dg]++; 57 return cast(PyObject*)func; 69 58 } 70 59 … … 103 92 104 93 // Calls the passed function with the passed Python tuple. 105 Ret Type!(fn_t) py_call(fn_t, PY)(fn_t fn, PY* args) {106 alias funcDelegInfoT!(fn_t) Meta;107 const uint MAX_ARGS = Meta.numArgs;108 alias Ret Type!(fn_t) RT;94 ReturnType!(fn_t) py_call(fn_t, PY)(fn_t fn, PY* args) { 95 alias ParameterTypeTuple!(fn_t) T; 96 const uint MAX_ARGS = T.length; 97 alias ReturnType!(fn_t) RT; 109 98 110 99 int ARGS = 0; … … 112 101 if (args !is null) { 113 102 ARGS = PyObject_Length(args); 114 //assert(ARGS == MAX_ARGS, "Function called with wrong number of arguments");115 103 } 116 104 … … 121 109 } 122 110 123 alias getFuncTuple!(fn_t) T; // tuple type124 111 T t; 125 126 loop!(T)(&t, args); 127 128 static if (is(RT : void)) { 129 apply(fn, t); 112 foreach(i, arg; t) { 113 t[i] = d_type!(typeof(arg))(PyTuple_GetItem(args, i)); 114 } 115 116 static if (is(RT == void)) { 117 fn(t); 130 118 return; 131 119 } else { 132 return apply(fn,t);120 return fn(t); 133 121 } 134 122 } 135 123 136 124 template wrapped_func_call(fn_t) { 137 alias funcDelegInfoT!(fn_t) Meta; 138 const uint MAX_ARGS = Meta.numArgs; 139 alias RetType!(fn_t) RT; 125 alias ReturnType!(fn_t) RT; 140 126 // The entry for the tp_call slot of the DPyFunc types. 141 127 // (Or: What gets called when you pass a delegate or function pointer to … … 149 135 150 136 fn_t fn = (cast(wrapped_class_object!(fn_t)*)self).d_obj; 151 //PyObject* ret;152 137 153 138 return exception_catcher({ … … 166 151 // with a PyCFunction. 167 152 template func_wrap(alias real_fn, uint MIN_ARGS, C=void, fn_t=typeof(&real_fn)) { 168 alias funcDelegInfoT!(fn_t) Meta;169 const uint MAX_ARGS = Meta.numArgs;170 alias Ret Type!(fn_t) RT;153 alias ParameterTypeTuple!(fn_t) Info; 154 const uint MAX_ARGS = Info.length; 155 alias ReturnType!(fn_t) RT; 171 156 172 157 // Wraps py_call to return a PyObject* 173 158 PyObject* py_py_call(fn_t, PY)(fn_t fn, PY* args) { 174 static if (is(R etType!(fn_t)== void)) {159 static if (is(RT == void)) { 175 160 py_call(fn, args); 176 161 Py_INCREF(Py_None); … … 181 166 } 182 167 183 // Loops through the tuple of function pointers until the number of184 // elements in the PyTuple equals the number of arguments accepted by the185 // function pointer. Then, it applies the PyTuple to the function pointer.186 PyObject* loop(T, uint i = 0) (T* t, PyObject* args, int argCount) {187 static if (i == T.length) {188 // This is tripped if the number of args in the passed PyTuple is189 // not matched to a function pointer in the defaultsTuple.190 setWrongArgsError(argCount, MIN_ARGS, MAX_ARGS);191 return null;192 } else {193 alias funcDelegInfoT!(typeof(t.val!(i))) current;194 if (current.numArgs == argCount) {195 return py_py_call(t.val!(i), args);196 }197 return loop!(T, i+1) (t, args, argCount);198 }199 }200 201 168 // Calls py_py_call with the proper function contained in a tuple 202 169 // returned from tuples.func_range. 203 PyObject* tuple_py_call( Tu, PY)(Tu t, PY* args) {170 PyObject* tuple_py_call(PY, T ...)(PY* args, T t) { 204 171 int argCount = 0; 205 172 if (args !is null) … … 210 177 return py_py_call(&firstArgs!(real_fn, 0, fn_t), args); 211 178 } 212 return loop!(Tu)(&t, args, argCount); 179 foreach (i, arg; t) { 180 if (ParameterTypeTuple!(typeof(arg)).length == argCount) { 181 return py_py_call(arg, args); 182 } 183 } 213 184 } 214 185 … … 231 202 C instance = (cast(wrapped_class_object!(C)*)self).d_obj; 232 203 fn_to_dg!(fn_t) fn = dg_wrapper!(C, fn_t)(instance, &real_fn); 233 static if (is(Ret Type!(typeof(fn)) == void)) {204 static if (is(ReturnType!(typeof(fn)) == void)) { 234 205 py_call(fn, args); 235 206 Py_INCREF(Py_None); … … 240 211 // If C is not specified, then this is just a normal function call. 241 212 } else { 242 return tuple_py_call(defaultsTuple!(real_fn, MIN_ARGS, fn_t)(), args); 213 alias defaultsTupleT!(real_fn, MIN_ARGS, fn_t).type T; 214 T t; 215 defaultsTuple!(real_fn, MIN_ARGS, fn_t)(delegate void(T tu) { 216 foreach(i, arg; tu) { 217 t[i] = arg; 218 } 219 }); 220 return tuple_py_call(args, t); 243 221 } 244 222 }); … … 268 246 269 247 private template _pycallable_asdgT(Dg) { 270 alias funcDelegInfoT!(Dg) Info; 271 const uint ARGS = Info.numArgs; 272 alias RetType!(Dg) Tr; 273 274 template A(uint i) { 275 alias Info.Meta.ArgType!(i-1) A; 276 } 248 alias ParameterTypeTuple!(Dg) Info; 249 alias ReturnType!(Dg) Tr; 277 250 278 251 Dg func(PyObject* c) { 279 252 auto f = new DPyWrappedFunc(c); 280 253 281 static if (ARGS == 0) 282 return &f.fn!(Tr); 283 else static if (ARGS == 1) 284 return &f.fn!(Tr, A!(1)); 285 else static if (ARGS == 2) 286 return &f.fn!(Tr, A!(1), A!(2)); 287 else static if (ARGS == 3) 288 return &f.fn!(Tr, A!(1), A!(2), A!(3)); 289 else static if (ARGS == 4) 290 return &f.fn!(Tr, A!(1), A!(2), A!(3), A!(4)); 291 else static if (ARGS == 5) 292 return &f.fn!(Tr, A!(1), A!(2), A!(3), A!(4), A!(5)); 293 else static if (ARGS == 6) 294 return &f.fn!(Tr, A!(1), A!(2), A!(3), A!(4), A!(5), A!(6)); 295 else static if (ARGS == 7) 296 return &f.fn!(Tr, A!(1), A!(2), A!(3), A!(4), A!(5), A!(6), A!(7)); 297 else static if (ARGS == 8) 298 return &f.fn!(Tr, A!(1), A!(2), A!(3), A!(4), A!(5), A!(6), A!(7), A!(8)); 299 else static if (ARGS == 9) 300 return &f.fn!(Tr, A!(1), A!(2), A!(3), A!(4), A!(5), A!(6), A!(7), A!(8), A!(9)); 301 else static if (ARGS == 10) 302 return &f.fn!(Tr, A!(1), A!(2), A!(3), A!(4), A!(5), A!(6), A!(7), A!(8), A!(9), A!(10)); 303 else static assert(false, "Unsupported number of args in delegate type."); 254 return &f.fn!(Tr, Info); 304 255 } 305 256 } … … 311 262 this(PyObject* c) { callable = c; Py_INCREF(c); } 312 263 ~this() { Py_DECREF(callable); } 313 314 Tr boilerplate(Tr)(PyObject* ret) { 264 265 Tr fn(Tr, T ...) (T t) { 266 PyObject* ret = call(t); 315 267 if (ret is null) handle_exception(); 316 268 scope(exit) Py_DECREF(ret); 317 269 return d_type!(Tr)(ret); 318 270 } 319 320 Tr fn(Tr)() { 321 return boilerplate!(Tr)(call(makeTuple())); 322 } 323 324 Tr fn(Tr, T1)(T1 t1) { 325 return boilerplate!(Tr)(call(makeTuple(t1))); 326 } 327 328 Tr fn(Tr, T1, T2)(T1 t1, T2 t2) { 329 return boilerplate!(Tr)(call(makeTuple(t1, t2))); 330 } 331 332 Tr fn(Tr, T1, T2, T3)(T1 t1, T2 t2, T3 t3) { 333 return boilerplate!(Tr)(call(makeTuple(t1, t2, t3))); 334 } 335 336 Tr fn(Tr, T1, T2, T3, T4)(T1 t1, T2 t2, T3 t3, T4 t4) { 337 return boilerplate!(Tr)(call(makeTuple(t1, t2, t3, t4))); 338 } 339 340 Tr fn(Tr, T1, T2, T3, T4, T5)(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { 341 return boilerplate!(Tr)(call(makeTuple(t1, t2, t3, t4, t5))); 342 } 343 344 Tr fn(Tr, T1, T2, T3, T4, T5, T6)(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { 345 return boilerplate!(Tr)(call(makeTuple(t1, t2, t3, t4, t5, t6))); 346 } 347 348 Tr fn(Tr, T1, T2, T3, T4, T5, T6, T7)(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) { 349 return boilerplate!(Tr)(call(makeTuple(t1, t2, t3, t4, t5, t6, t7))); 350 } 351 352 Tr fn(Tr, T1, T2, T3, T4, T5, T6, T7, T8)(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) { 353 return boilerplate!(Tr)(call(makeTuple(t1, t2, t3, t4, t5, t6, t7, t8))); 354 } 355 356 Tr fn(Tr, T1, T2, T3, T4, T5, T6, T7, T8, T9)(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) { 357 return boilerplate!(Tr)(call(makeTuple(t1, t2, t3, t4, t5, t6, t7, t8, t9))); 358 } 359 360 Tr fn(Tr, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10) { 361 return boilerplate!(Tr)(call(makeTuple(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10))); 362 } 363 364 void loop(T, uint current)(T* dt, PyObject* pyt) { 365 static if (current < T.length) { 366 PyTuple_SetItem(pyt, current, _py(dt.val!(current))); 367 loop!(T, current+1)(dt, pyt); 368 } 369 } 370 371 PyObject* call(T) (T dt) { 271 272 PyObject* call(T ...) (T t) { 372 273 const uint ARGS = T.length; 373 274 … … 376 277 scope(exit) Py_DECREF(pyt); 377 278 378 loop!(T, 0)(&dt, pyt); 279 foreach(i, arg; t) { 280 PyTuple_SetItem(pyt, i, _py(arg)); 281 } 379 282 return PyObject_CallObject(callable, pyt); 380 283 } trunk/infrastructure/pyd/iteration.d
r40 r45 27 27 module pyd.iteration; 28 28 29 private import python; 30 private import pyd.class_wrap; 31 private import pyd.dg_convert; 32 private import pyd.exception; 33 //private import pyd.ftype; 34 private import pyd.make_object; 29 private { 30 import python; 35 31 36 private import meta.FuncMeta; 32 import pyd.class_wrap; 33 import pyd.dg_convert; 34 import pyd.exception; 35 import pyd.make_object; 37 36 38 private import st.stackcontext; 37 import std.traits; 38 39 import st.stackcontext; 40 } 39 41 40 42 // This exception is for yielding a PyObject* from within a StackContext. … … 48 50 } 49 51 50 // Makes a PyTuple and "steals" all of the passed references51 PyObject* _make_pytuple(PyObject*[] pyobjs ...) {52 PyObject* temp = PyTuple_New(pyobjs.length);53 if (temp is null) {54 foreach (PyObject* o; pyobjs) {55 Py_DECREF(o);56 }57 return null;58 }59 foreach (uint i, PyObject* o; pyobjs) {60 PyTuple_SetItem(temp, i, o);61 }62 return temp;63 }64 65 52 // Creates an iterator object from an object. 66 53 PyObject* DPySC_FromWrapped(T, alias Iter = T.opApply, iter_t = typeof(&Iter)) (T obj) { 67 54 // Get the number of args the opApply's delegate argument takes 68 alias funcDelegInfoT!(iter_t) IInfo;69 alias funcDelegInoutInfoT!(IInfo.Meta.ArgType!(0)) Info;70 const uint ARGS = Info. numArgs;55 alias ParameterTypeTuple!(iter_t) IInfo; 56 alias ParameterTypeTuple!(IInfo[0]) Info; 57 const uint ARGS = Info.length; 71 58 auto sc = new StackContext(delegate void() { 72 59 T o = obj; 73 60 fn_to_dg!(iter_t) t = dg_wrapper!(T, iter_t)(o, &Iter); 74 // So we can get the variable in the enclosing function's stack frame 61 // We yield so we can be sure to get the local variables in the 62 // enclosing function's stack frame. 75 63 StackContext.yield(); 76 64 PyObject* temp; 77 // I seriously doubt I need to support up to ten (10!) arguments to the 78 // opApply delegate, but everything else in Pyd does, so here we go. 79 static if (ARGS == 1) { 80 foreach (i; t) { 81 StackContext.throwYield(new DPyYield(_py(i))); 82 } 83 } else static if (ARGS == 2) { 84 foreach (a0, a1; t) { 85 temp = _make_pytuple(_py(a0), _py(a1)); 86 if (temp is null) StackContext.throwYield(new DPyYield(null)); 87 StackContext.throwYield(new DPyYield(temp)); 88 } 89 } else static if (ARGS == 3) { 90 foreach (a0, a1, a2; t) { 91 temp = _make_pytuple(_py(a0), _py(a1), _py(a2)); 92 if (temp is null) StackContext.throwYield(new DPyYield(null)); 93 StackContext.throwYield(new DPyYield(temp)); 94 } 95 } else static if (ARGS == 4) { 96 foreach (a0, a1, a2, a3; t) { 97 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3)); 98 if (temp is null) StackContext.throwYield(new DPyYield(null)); 99 StackContext.throwYield(new DPyYield(temp)); 100 } 101 } else static if (ARGS == 5) { 102 foreach (a0, a1, a2, a3, a4; t) { 103 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3), _py(a4)); 104 if (temp is null) StackContext.throwYield(new DPyYield(null)); 105 StackContext.throwYield(new DPyYield(temp)); 106 } 107 } else static if (ARGS == 6) { 108 foreach (a0, a1, a2, a3, a4, a5; t) { 109 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3), _py(a4), _py(a5)); 110 if (temp is null) StackContext.throwYield(new DPyYield(null)); 111 StackContext.throwYield(new DPyYield(temp)); 112 } 113 } else static if (ARGS == 7) { 114 foreach (a0, a1, a2, a3, a4, a5, a6; t) { 115 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3), _py(a4), _py(a5), _py(a6)); 116 if (temp is null) StackContext.throwYield(new DPyYield(null)); 117 StackContext.throwYield(new DPyYield(temp)); 118 } 119 } else static if (ARGS == 8) { 120 foreach (a0, a1, a2, a3, a4, a5, a6, a7; t) { 121 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3), _py(a4), _py(a5), _py(a6), _py(a7)); 122 if (temp is null) StackContext.throwYield(new DPyYield(null)); 123 StackContext.throwYield(new DPyYield(temp)); 124 } 125 } else static if (ARGS == 9) { 126 foreach (a0, a1, a2, a3, a4, a5, a6, a7, a8; t) { 127 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3), _py(a4), _py(a5), _py(a6), _py(a7), _py(a8)); 128 if (temp is null) StackContext.throwYield(new DPyYield(null)); 129 StackContext.throwYield(new DPyYield(temp)); 130 } 131 } else static if (ARGS == 10) { 132 foreach (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9; t) { 133 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3), _py(a4), _py(a5), _py(a6), _py(a7), _py(a8), _py(a9)); 134 if (temp is null) StackContext.throwYield(new DPyYield(null)); 135 StackContext.throwYield(new DPyYield(temp)); 136 } 137 } 65 66 t(delegate int(inout Info i) { 67 StackContext.throwYield(new DPyYield(PyTuple_FromItems(i))); 68 return 0; 69 }); 138 70 }); 139 71 // Initialize the StackContext … … 186 118 if (!is_wrapped!(StackContext)) { 187 119 type.ob_type = PyType_Type_p; 120 //type.tp_new = &wrapped_methods!(StackContext).wrapped_new; 121 //type.tp_dealloc = &wrapped_methods!(StackContext).wrapped_dealloc; 188 122 type.tp_basicsize = DPySC_object.sizeof; 123 type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; 189 124 //type.tp_doc = ""; 190 type.tp_name = " DPyOpApplyWrapper";125 type.tp_name = "PydOpApplyWrapper"; 191 126 192 127 type.tp_iter = &PyObject_SelfIter; … … 200 135 } 201 136 } 137 trunk/infrastructure/pyd/make_object.d
r44 r45 29 29 * D type -> PyObject* 30 30 * 31 * The former is handled by d_type, the latter by _ _py. The py function is31 * The former is handled by d_type, the latter by _py. The py function is 32 32 * provided as a convenience to directly convert a D type into an instance of 33 33 * DPyObject. … … 36 36 37 37 private import python; 38 38 39 private import std.string; 39 // Base type 40 40 41 private import pyd.dpyobject; 41 42 private import pyd.class_wrap; 42 43 private import pyd.func_wrap; 43 44 44 private import pyd.exception; 45 45 … … 154 154 155 155 /** 156 * Helper function for creating a PyTuple from a series of D items. 157 */ 158 PyObject* PyTuple_FromItems(T ...)(T t) { 159 PyObject* tuple = PyTuple_New(t.length); 160 PyObject* temp; 161 if (tuple is null) return null; 162 foreach(i, arg; t) { 163 temp = _py(arg); 164 if (temp is null) { 165 Py_DECREF(tuple); 166 return null; 167 } 168 PyTuple_SetItem(tuple, i, temp); 169 } 170 return tuple; 171 } 172 173 /** 156 174 * Constructs an object based on the type of the argument passed in. 157 175 * trunk/infrastructure/pyd/op_wrap.d
r44 r45 30 30 private import pyd.make_object; 31 31 32 private import meta.FuncMeta;33 32 private import meta.Nameof; 33 34 private import std.traits; 35 36 version(Python_2_5_Or_Later) { 37 alias Py_ssize_t index_t; 38 alias lenfunc lenfunc_t; 39 alias ssizeargfunc idxargfunc; 40 alias ssizessizeargfunc idxidxargfunc; 41 alias ssizeobjargproc idxobjargproc; 42 alias ssizessizeobjargproc idxidxobjargproc; 43 } else { 44 alias int index_t; 45 alias inquiry lenfunc_t; 46 alias intargfunc idxargfunc; 47 alias intintargfunc idxidxargfunc; 48 alias intobjargproc idxobjargproc; 49 alias intintobjargproc idxidxobjargproc; 50 } 34 51 35 52 template wrapped_class_as_number(T) { … … 104 121 template opfunc_binary_wrap(T, alias opfn) { 105 122 alias wrapped_class_object!(T) wrap_object; 106 alias funcDelegInfoT!(typeof(&opfn)) Info;123 alias ParameterTypeTuple!(opfn) Info; 107 124 extern(C) 108 125 PyObject* func(PyObject* self, PyObject* o) { … … 113 130 return _py( 114 131 dg( 115 d_type!(Info .Meta.ArgType!(0))(o)132 d_type!(Info[0])(o) 116 133 ) 117 134 ); … … 132 149 133 150 extern(C) 134 PyObject* func(PyObject* self, in t i) {151 PyObject* func(PyObject* self, index_t i) { 135 152 return exception_catcher(delegate PyObject*() { 136 153 return _py((cast(wrap_object*)self).d_obj.opIndex(i)); … … 141 158 template opindexassign_sequence_pyfunc(T) { 142 159 alias wrapped_class_object!(T) wrap_object; 143 alias funcDelegInfoT!(typeof(&T.opIndexAssign)) Info;144 alias Info .Meta.ArgType!(0)AssignT;145 146 extern(C) 147 int func(PyObject* self, in t i, PyObject* o) {160 alias ParameterTypeTuple!(T.opIndexAssign) Info; 161 alias Info[0] AssignT; 162 163 extern(C) 164 int func(PyObject* self, index_t i, PyObject* o) { 148 165 return exception_catcher(delegate int() { 149 166 (cast(wrap_object*)self).d_obj.opIndexAssign(d_type!(AssignT)(o), i); … … 155 172 template opindex_mapping_pyfunc(T) { 156 173 alias wrapped_class_object!(T) wrap_object; 157 alias funcDelegInfoT!(typeof(&T.opIndex)) Info;158 const uint ARGS = Info. numArgs;174 alias ParameterTypeTuple!(T.opIndex) Info; 175 const uint ARGS = Info.length; 159 176 160 177 // Multiple arguments are converted into tuples, and thus become a standard 161 178 // wrapped member function call. A single argument is passed directly. 162 179 static if (ARGS == 1) { 163 alias Info .Meta.ArgType!(0)KeyT;180 alias Info[0] KeyT; 164 181 extern(C) 165 182 PyObject* func(PyObject* self, PyObject* key) { … … 188 205 template opindexassign_mapping_pyfunc(T) { 189 206 alias wrapped_class_object!(T) wrap_object; 190 alias funcDelegInfoT!(typeof(&T.opIndexAssign)) Info;191 const uint ARGS = Info. numArgs;207 alias ParameterTypeTuple!(T.opIndexAssign) Info; 208 const uint ARGS = Info.length; 192 209 193 210 static if (ARGS > 2) { … … 217 234 } 218 235 } else { 219 alias Info .Meta.ArgType!(0)ValT;220 alias Info .Meta.ArgType!(1)KeyT;236 alias Info[0] ValT; 237 alias Info[1] KeyT; 221 238 222 239 extern(C) … … 234 251 235 252 extern(C) 236 PyObject* func(PyObject* self, in t i1, int i2) {253 PyObject* func(PyObject* self, index_t i1, index_t i2) { 237 254 return exception_catcher(delegate PyObject*() { 238 255 return _py((cast(wrap_object*)self).d_obj.opSlice(i1, i2)); … … 243 260 template opsliceassign_pyfunc(T) { 244 261 alias wrapped_class_object!(T) wrap_object; 245 alias funcDelegInfoT!(typeof(&T.opSliceAssign)) Info;246 alias Info .Meta.ArgType!(0)AssignT;247 248 extern(C) 249 int func(PyObject* self, in t i1, int i2, PyObject* o) {262 alias ParameterTypeTuple!(T.opSliceAssign) Info; 263 alias Info[0] AssignT; 264 265 extern(C) 266 int func(PyObject* self, index_t i1, index_t i2, PyObject* o) { 250 267 return exception_catcher(delegate int() { 251 268 (cast(wrap_object*)self).d_obj.opSliceAssign(d_type!(AssignT)(o), i1, i2); … … 257 274 template opin_wrap(T) { 258 275 alias wrapped_class_object!(T) wrap_object; 259 alias funcDelegInfoT!(typeof(&T.opIn_r)) Info;260 alias Info .Meta.ArgType!(0)OtherT;276 alias ParameterTypeTuple!(T.opIn_r) Info; 277 alias Info[0] OtherT; 261 278 262 279 extern(C) … … 273 290 template opcmp_wrap(T) { 274 291 alias wrapped_class_object!(T) wrap_object; 275 alias funcDelegInfoT!(typeof(&T.opCmp)) Info;276 alias Info .Meta.ArgType!(0)OtherT;292 alias ParameterTypeTuple!(T.opCmp) Info; 293 alias Info[0] OtherT; 277 294 extern(C) 278 295 int func(PyObject* self, PyObject* other) { … … 293 310 294 311 extern(C) 295 in t func(PyObject* self) {312 index_t func(PyObject* self) { 296 313 return exception_catcher(delegate int() { 297 314 return (cast(wrap_object*)self).d_obj.length(); … … 306 323 static if ( 307 324 is(typeof(&T.length)) && 308 is(typeof( &T.length()) : int)325 is(typeof(T.length()) : index_t) 309 326 ) { 310 const inquirylength_wrap = &length_pyfunc!(T).func;311 } else { 312 const inquirylength_wrap = null;327 const lenfunc_t length_wrap = &length_pyfunc!(T).func; 328 } else { 329 const lenfunc_t length_wrap = null; 313 330 } 314 331 } … … 317 334 static if ( 318 335 is(typeof(&T.opIndex)) && 319 funcDelegInfoT!(typeof(&T.opIndex)).numArgs== 1 &&320 is( funcDelegInfoT!(typeof(&T.opIndex)).Meta.ArgType!(0) : int)336 ParameterTypeTuple!(T.opIndex).length == 1 && 337 is(ParameterTypeTuple!(T.opIndex)[0] : index_t) 321 338 ) { 322 const i ntargfunc opIndex_sequence_wrap = &opindex_sequence_pyfunc!(T).func;323 } else { 324 const i ntargfunc opIndex_sequence_wrap = null;339 const idxargfunc opIndex_sequence_wrap = &opindex_sequence_pyfunc!(T).func; 340 } else { 341 const idxargfunc opIndex_sequence_wrap = null; 325 342 } 326 343 } … … 329 346 static if ( 330 347 is(typeof(&T.opIndexAssign)) && 331 funcDelegInfoT!(typeof(&T.opIndexAssign)).numArgs== 2 &&332 is( funcDelegInfoT!(typeof(&T.opIndexAssign)).Meta.ArgType!(1) : int)348 ParameterTypeTuple!(T.opIndexAssign).length == 2 && 349 is(ParameterTypeTuple!(T.opIndexAssign)[1] : index_t) 333 350 ) { 334 const i ntobjargproc opIndexAssign_sequence_wrap = &opindexassign_sequence_pyfunc!(T).func;335 } else { 336 const i ntobjargproc opIndexAssign_sequence_wrap = null;351 const idxobjargproc opIndexAssign_sequence_wrap = &opindexassign_sequence_pyfunc!(T).func; 352 } else { 353 const idxobjargproc opIndexAssign_sequence_wrap = null; 337 354 } 338 355 } … … 341 358 static if ( 342 359 is(typeof(&T.opIndex)) && 343 ( funcDelegInfoT!(typeof(&T.opIndex)).numArgs> 1 ||344 !is( funcDelegInfoT!(typeof(&T.opIndex)).Meta.ArgType!(0) : int))360 (ParameterTypeTuple!(T.opIndex).length > 1 || 361 !is(ParameterTypeTuple!(T.opIndex)[0] : index_t)) 345 362 ) { 346 363 const binaryfunc opIndex_mapping_wrap = &opindex_mapping_pyfunc!(T).func; … … 353 370 static if ( 354 371 is(typeof(&T.opIndexAssign)) && 355 ( funcDelegInfoT!(typeof(&T.opIndexAssign)).numArgs> 2 ||356 !is( funcDelegInfoT!(typeof(&T.opIndexAssign)).Meta.ArgType!(1) : int))372 (ParameterTypeTuple!(T.opIndex).length > 2 || 373 !is(ParameterTypeTuple!(T.opIndex)[1] : index_t)) 357 374 ) { 358 375 const objobjargproc opIndexAssign_mapping_wrap = &opindexassign_mapping_pyfunc!(T).func; … … 365 382 static if ( 366 383 is(typeof(&T.opSlice)) && 367 funcDelegInfoT!(typeof(&T.opSlice)).numArgs== 2 &&368 is( funcDelegInfoT!(typeof(&T.opSlice)).Meta.ArgType!(0) : int) &&369 is( funcDelegInfoT!(typeof(&T.opSlice)).Meta.ArgType!(1) : int)384 ParameterTypeTuple!(T.opSlice).length == 2 && 385 is(ParameterTypeTuple!(T.opSlice)[0] : index_t) && 386 is(ParameterTypeTuple!(T.opSlice)[1] : index_t) 370 387 ) { 371 const i ntintargfunc opSlice_wrap = &opslice_pyfunc!(T).func;372 } else { 373 const i ntintargfunc opSlice_wrap = null;388 const idxidxargfunc opSlice_wrap = &opslice_pyfunc!(T).func; 389 } else { 390 const idxidxargfunc opSlice_wrap = null; 374 391 } 375 392 } … … 378 395 static if ( 379 396 is(typeof(&T.opSlice)) && 380 funcDelegInfoT!(typeof(&T.opSlice)).numArgs== 3 &&381 is( funcDelegInfoT!(typeof(&T.opSlice)).Meta.ArgType!(1) : int) &&382 is( funcDelegInfoT!(typeof(&T.opSlice)).Meta.ArgType!(2) : int)397 ParameterTypeTuple!(T.opSlice).length == 3 && 398 is(ParameterTypeTuple!(T.opSlice)[1] : index_t) && 399 is(ParameterTypeTuple!(T.opSlice)[2] : index_t) 383 400 ) { 384 const i ntintobjargproc opSliceAssign_wrap = &opsliceassign_pyfunc!(T).func;385 } else { 386 const i ntintobjargproc opSliceAssign_wrap = null;401 const idxidxobjargproc opSliceAssign_wrap = &opsliceassign_pyfunc!(T).func; 402 } else { 403 const idxidxobjargproc opSliceAssign_wrap = null; 387 404 } 388 405 } trunk/infrastructure/pyd/pyd.d
r41 r45 29 29 public import pyd.def; 30 30 public import pyd.class_wrap; 31 public import pyd.ctor_wrap;31 //public import pyd.ctor_wrap; 32 32 public import pyd.dpyobject; 33 33 public import pyd.exception; trunk/pydmdvars.bat
r30 r45 2 2 3 3 Set D_ROOT=C:\dmd 4 Set PY_ROOT=C:\Python2 44 Set PY_ROOT=C:\Python25 5 5 Set PATH=%D_ROOT%\dmd\bin;%D_ROOT%\dm\bin;%D_ROOT%\gdc\bin;%PY_ROOT%;%PATH% 6 6 Set LIB=%D_ROOT%\dmd\lib;%D_ROOT%\dm\lib;%LIB% trunk/setup.py
r24 r45 21 21 build_manifest.convertPathToDistutilsStandard(path) 22 22 for path in includedPaths 23 ]23 ] 24 24 25 25 # Only Python code files *within the celerid package* should go into … … 32 32 PACKAGE_NAME + '.' + os.path.splitext(f)[0] 33 33 for f in packageCodeFiles 34 ]34 ] 35 35 36 36 distutils.core.setup( … … 40 40 41 41 version=file('version.txt').read().strip(), 42 url=' XXX',43 maintainer=' David Rushby',44 maintainer_email=' davidrushby@yahoo.com',42 url='http://pyd.dsource.org/', 43 maintainer='Kirk McDonald', 44 maintainer_email='kirklin.mcdonald@gmail.com', 45 45 py_modules=packageModules, 46 46 package_data={PACKAGE_NAME: packageDataFiles}, 47 ) 47 ) 48 trunk/version.txt
r24 r45 1 2006_ 07_011 2006_11_19
