Changeset 45

Show
Ignore:
Timestamp:
11/19/06 20:08:43 (1 year ago)
Author:
KirkMcDonald
Message:

Update for DMD 0.174 and Python 2.5. Now uses D's native tuples.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/dcompiler.py

    r40 r45  
    3232    'dpyobject.d', 
    3333    'exception.d', 
    34 #    'ftype.d', 
    3534    'func_wrap.d', 
    3635    'iteration.d', 
     
    3837    'op_wrap.d', 
    3938    'pyd.d', 
    40 #    'tuples.d', 
    4139] 
    4240 
     
    4947 
    5048_metaFiles = [ 
    51     'Apply.d', 
    52     'Bind.d', 
    5349    'Default.d', 
    5450    'Demangle.d', 
    55     'FuncMeta.d', 
    56     'Instantiate.d', 
    5751    'Nameof.d', 
    58     'Tuple.d', 
    59     'Use.d', 
    6052    'Util.d', 
    61     'VarArg.d', 
    6253] 
    6354 
     
    153144        # To sources, add the appropriate D header file python.d, as well as 
    154145        # any platform-specific boilerplate. 
    155         pythonHeaderPath = os.path.join(_infraDir, 'python', 'headers', 'python.d') 
     146        pythonHeaderPath = os.path.join(_infraDir, 'python', _pyVerXDotY, 'python.d') 
    156147        # Add the python header's directory to the include path 
    157148        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
    159150        if not os.path.isfile(pythonHeaderPath): 
    160151            raise DistutilsPlatformError('Required D translation of Python' 
     
    188179                ) 
    189180            sources.append(filePath) 
    190         # Add the infraDir to the include path for Pyd and ST 
     181        # Add the infraDir to the include path for pyd, st, and meta. 
    191182        includePathOpts += self._includeOpts 
    192183        includePathOpts[-1] = includePathOpts[-1] % os.path.join(_infraDir) 
     
    451442            # more convenient to distribute a pre-extracted .lib file to the 
    452443            # 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' % _pyVerXY 
     444            pythonDMDLibPath = _qp(os.path.join(_infraDir, 'python', _pyVerXDotY
     445                'python%s_digitalmars.lib' % _pyVerXY 
    455446            )) 
    456447            if not os.path.isfile(pythonDMDLibPath): 
  • trunk/examples/testdll/testdll.d

    r44 r45  
    44import pyd.pyd; 
    55//import pyd.ftype; 
    6 import std.stdio
     6import std.stdio, std.string
    77 
    8 import meta.Tuple; 
    9 import meta.Apply; 
     8//import meta.Tuple; 
     9//import meta.Apply; 
    1010 
    1111void apply_test(int i, char[] s) { 
     
    1414 
    1515void foo() { 
     16    /+ 
    1617    alias Tuple!(int, char[]) T; 
    1718    T t; 
     
    1920    t.val!(1) = "Monkey"; 
    2021    apply(&apply_test, t); 
     22    +/ 
     23    writefln("20 Monkey"); 
    2124} 
    2225 
  • trunk/html_doc/basics.html

    r40 r45  
    1111<p><big>Contents</big></p> 
    1212<a class="nav" href="index.html">Main</a><br /> 
     13<a class="nav" href="install.html">Installation</a><br /> 
    1314<a class="navcur" href="basics.html">The basics</a><br /> 
    1415<a class="nav" href="celerid.html">CeleriD</a><br /> 
     
    1718<a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 
    1819<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> 
    2022</div> 
    2123 
     
    2325 
    2426<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> 
    3527 
    3628<h3>Module basics</h3> 
     
    6052 
    6153<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> 
    6256</div> 
    6357 
  • trunk/html_doc/celerid.html

    r35 r45  
    1111<p><big>Contents</big></p> 
    1212<a class="nav" href="index.html">Main</a><br /> 
     13<a class="nav" href="install.html">Installation</a><br /> 
    1314<a class="nav" href="basics.html">The basics</a><br /> 
    1415<a class="navcur" href="celerid.html">CeleriD</a><br /> 
     
    1718<a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 
    1819<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> 
    2022</div> 
    2123 
  • trunk/html_doc/class_wrapping.html

    r44 r45  
    1111<p><big>Contents</big></p> 
    1212<a class="nav" href="index.html">Main</a><br /> 
     13<a class="nav" href="install.html">Installation</a><br /> 
    1314<a class="nav" href="basics.html">The basics</a><br /> 
    1415<a class="nav" href="celerid.html">CeleriD</a><br /> 
     
    1718<a class="navcur" href="class_wrapping.html">Class wrapping</a><br /> 
    1819<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> 
    2022</div> 
    2123 
     
    4749</dd> 
    4850 
    49 <dt><code>static void init(<span class="t_arg">C1</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> 
    5153 
    5254<dt><code>static void iter(<span class="t_arg">iter_t</span>) ();</code></dt> 
  • trunk/html_doc/conversion.html

    r35 r45  
    1111<p><big>Contents</big></p> 
    1212<a class="nav" href="index.html">Main</a><br /> 
     13<a class="nav" href="install.html">Installation</a><br /> 
    1314<a class="nav" href="basics.html">The basics</a><br /> 
    1415<a class="nav" href="celerid.html">CeleriD</a><br /> 
     
    1718<a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 
    1819<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> 
    2022</div> 
    2123 
  • trunk/html_doc/dpyobject.html

    r35 r45  
    1111<p><big>Contents</big></p> 
    1212<a class="nav" href="index.html">Main</a><br /> 
     13<a class="nav" href="install.html">Installation</a><br /> 
    1314<a class="nav" href="basics.html">The basics</a><br /> 
    1415<a class="nav" href="celerid.html">CeleriD</a><br /> 
     
    1718<a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 
    1819<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> 
    2022</div> 
    2123 
  • trunk/html_doc/except_wrapping.html

    r35 r45  
    1111<p><big>Contents</big></p> 
    1212<a class="nav" href="index.html">Main</a><br /> 
     13<a class="nav" href="install.html">Installation</a><br /> 
    1314<a class="nav" href="basics.html">The basics</a><br /> 
    1415<a class="nav" href="celerid.html">CeleriD</a><br /> 
     
    1718<a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 
    1819<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> 
    2022</div> 
    2123 
  • trunk/html_doc/func_wrapping.html

    r41 r45  
    1111<p><big>Contents</big></p> 
    1212<a class="nav" href="index.html">Main</a><br /> 
     13<a class="nav" href="install.html">Installation</a><br /> 
    1314<a class="nav" href="basics.html">The basics</a><br /> 
    1415<a class="nav" href="celerid.html">CeleriD</a><br /> 
     
    1718<a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 
    1819<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> 
    2022</div> 
    2123 
  • trunk/html_doc/index.html

    r44 r45  
    1111<p><big>Contents</big></p> 
    1212<a class="navcur" href="index.html">Main</a><br /> 
     13<a class="nav" href="install.html">Installation</a><br /> 
    1314<a class="nav" href="basics.html">The basics</a><br /> 
    1415<a class="nav" href="celerid.html">CeleriD</a><br /> 
     
    1718<a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 
    1819<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> 
    2022</div> 
    2123 
     
    2325 
    2426<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> 
    2628 
    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 &copy; 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--> 
    2836 
    2937<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  
    44module meta.Default; 
    55 
    6 private import meta.FuncMeta; 
    7 private import meta.Tuple; 
    8 private import meta.Nameof; 
    9 private import meta.Util; 
     6private import std.traits; 
     7private import std.typetuple; 
    108 
    119/** 
     
    1715 
    1816template firstArgsT(alias fn, uint args, fn_t = typeof(&fn)) { 
    19     alias RetType!(fn_t) R; 
    20     alias funcDelegInfoT!(fn_t) Info
     17    alias ReturnType!(fn_t) R; 
     18    alias ParameterTypeTuple!(fn_t) T
    2119 
    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); 
    7226        } 
    7327    } 
    7428} 
    7529 
    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
     30template 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
    7933    static if (current > MAX_ARGS) { 
    8034        alias T type; 
    8135    } 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; 
    9137    } 
    9238} 
     
    9642    calls to that function, as per its default arguments. 
    9743*/ 
    98 defaultsTupleT!(fn, MIN_ARGS, fn_t).type defaultsTuple(alias fn, uint MIN_ARGS, fn_t = typeof(&fn)) () { 
     44void defaultsTuple(alias fn, uint MIN_ARGS, fn_t = typeof(&fn)) ( 
     45    void delegate(defaultsTupleT!(fn, MIN_ARGS, fn_t).type) dg 
     46) { 
    9947    alias defaultsTupleT!(fn, MIN_ARGS, fn_t).type T; 
    10048    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); 
    10353} 
    10454 
     
    12575 
    12676template minArgsT(alias fn, fn_t = typeof(&fn)) { 
    127     alias funcDelegInfoT!(fn_t) Info
     77    alias ParameterTypeTuple!(fn_t) T
    12878 
    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; 
    13581    } 
    13682 
  • trunk/infrastructure/pyd/class_wrap.d

    r41 r45  
    3434 
    3535    import meta.Default; 
    36     import meta.FuncMeta; 
    37     import meta.Tuple; 
    3836    import meta.Nameof; 
    3937 
    4038    import std.string; 
     39    import std.traits; 
    4140} 
    4241 
     
    6160/// The type object, an instance of PyType_Type 
    6261    static PyTypeObject wrapped_class_type = { 
    63         1, 
    64         null, 
     62        1,                            /*ob_refcnt*/ 
     63        null,                         /*ob_type*/ 
    6564        0,                            /*ob_size*/ 
    6665        null,                         /*tp_name*/ 
     
    8281        null,                         /*tp_setattro*/ 
    8382        null,                         /*tp_as_buffer*/ 
    84         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 
     83        0, /*tp_flags*/ 
    8584        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*/ 
    111110    }; 
    112111} 
     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. 
     116template 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 */ 
     124template is_wrapped(T) { 
     125    bool is_wrapped = false; 
     126} 
     127 
     128// The list of wrapped methods for this class. 
     129template 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. 
     136template wrapped_prop_list(T) { 
     137    static PyGetSetDef[] wrapped_prop_list = [ 
     138        { null, null, null, null, null } 
     139    ]; 
     140} 
     141 
     142////////////////////// 
     143// STANDARD METHODS // 
     144////////////////////// 
    113145 
    114146/// Various wrapped methods 
     
    133165    extern(C) 
    134166    void wrapped_dealloc(PyObject* self) { 
    135         exception_catcher(delegate PyObject*() { 
     167        //exception_catcher(delegate PyObject*() { 
     168        try { 
    136169            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        //}); 
    140174    } 
    141175} 
     
    154188} 
    155189 
    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  
    169190// This template gets an alias to a property and derives the types of the 
    170191// getter form and the setter form. It requires that the getter form return the 
     
    173194    // This may be either the getter or the setter 
    174195    alias typeof(&p) p_t; 
    175     alias funcDelegInfoT!(p_t) Info; 
     196    alias ParameterTypeTuple!(p_t) Info; 
    176197    // This means it's the getter 
    177     static if (Info.numArgs == 0) { 
     198    static if (Info.length == 0) { 
    178199        alias p_t getter_type; 
    179200        // The setter may return void, or it may return the newly set attribute. 
    180         alias typeof(p(RetType!(p_t).init)) function(RetType!(p_t)) setter_type; 
     201        alias typeof(p(ReturnType!(p_t).init)) function(ReturnType!(p_t)) setter_type; 
    181202    // This means it's the setter 
    182203    } else { 
    183204        alias p_t setter_type; 
    184         alias Info.Meta.ArgType!(0) function() getter_type; 
     205        alias Info[0] function() getter_type; 
    185206    } 
    186207} 
     
    216237} 
    217238 
    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////////////////////////////// 
    246242 
    247243/** 
     
    321317         * the same number of arguments. 
    322318         */ 
    323         static void init(C1=int, C2=int, C3=int, C4=int, C5=int, C6=int, C7=int, C8=int, C9=int, C10=int) () { 
     319        static void init(C ...) () { 
    324320            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; 
    326322        } 
    327323 
     
    367363     
    368364    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)); 
    371366    // 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); 
    373370    type.tp_basicsize = (wrapped_class_object!(T)).sizeof; 
    374371    type.tp_doc       = name ~ " objects" ~ \0; 
     372    type.tp_flags     = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; 
    375373    //type.tp_new       = &PyType_GenericNew; 
    376     type.tp_repr      = &wrapped_repr!(T).repr; 
     374    //type.tp_repr      = &wrapped_repr!(T).repr; 
    377375    type.tp_methods   = wrapped_method_list!(T); 
    378376    type.tp_name      = module_name ~ "." ~ name ~ \0; 
     
    409407 
    410408    // 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    //
    414412    if (PyType_Ready(&type) < 0) { 
    415413        // XXX: This will probably crash the interpreter, as it isn't normally 
     
    422420    wrapped_classes[typeid(T)] = true; 
    423421} 
     422 
     423/////////////////////// 
     424// PYD API FUNCTIONS // 
     425/////////////////////// 
    424426 
    425427/** 
     
    442444} 
    443445 
     446/** 
     447 * Returns the object contained in a Python wrapped type. 
     448 */ 
    444449T WrapPyObject_AsObject(T) (PyObject* _self) { 
    445450    alias wrapped_class_object!(T) wrapped_object; 
     
    469474    if (t !is null) wrap_class_instances!(T)[t]++; 
    470475} 
     476 
  • trunk/infrastructure/pyd/ctor_wrap.d

    r40 r45  
    2828private import pyd.make_object; 
    2929 
    30 private import meta.Tuple; 
    31 private import meta.Bind; 
    32 private import meta.Instantiate; 
     30private import std.traits; 
    3331 
    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); 
     32T 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. 
     37template 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        }); 
    7745    } 
    7846} 
     
    8149// Tuples, which each describe a ctor of T, and  uses them to wrap a Python 
    8250// tp_init function. 
    83 template wrapped_ctors(T, Tu) { 
     51template wrapped_ctors(T, C ...) { 
    8452    alias wrapped_class_object!(T) wrap_object; 
    85  
    86     // The user can provide ctor footprints as either function pointer types 
    87     // 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 ctor 
    96     // 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 arguments 
    107     // passed in from Python. Then, it calls the ctor with the passed-in 
    108     // arguments. 
    109     int findAndCallCtor(uint current) (PyObject* self, PyObject* args, int argCount) { 
    110         static if (current == Ctors.length) { 
    111             // No match, handle error 
    112             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     } 
    12553 
    12654    extern(C) 
     
    13664                } 
    13765            } 
    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; 
    13979        }); 
    14080    } 
  • trunk/infrastructure/pyd/def.d

    r40 r45  
    2424private import python; 
    2525 
    26 private import pyd.class_wrap; 
    27 private import pyd.dg_convert; 
    28 private import pyd.exception; 
    2926private import pyd.func_wrap; 
    30 private import pyd.make_object; 
    3127 
    3228private import meta.Default; 
    3329private import meta.Nameof; 
    34  
    35 private import std.string; 
    3630 
    3731private 
  • trunk/infrastructure/pyd/dg_convert.d