Changeset 46

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

CeleriD enhancements, more examples, small exception wrapping enhancement.

Files:

Legend:

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

    r45 r46  
    154154        sources.append(pythonHeaderPath) 
    155155 
     156        # flags = (no_pyd, no_st, no_meta) 
     157        flags = [f for f, category in macros if category == 'aux'][0] 
    156158        # And Pyd! 
    157         # XXX: Add support for compiling without Pyd 
    158         for file in _pydFiles: 
    159             filePath = os.path.join(_infraDir, 'pyd', file) 
    160             if not os.path.isfile(filePath): 
    161                 raise DistutilsPlatformError("Required Pyd source file '%s' is" 
    162                     " missing." % filePath 
    163                
    164             sources.append(filePath) 
     159        if not flags[0]: 
     160            for file in _pydFiles: 
     161                filePath = os.path.join(_infraDir, 'pyd', file) 
     162                if not os.path.isfile(filePath): 
     163                    raise DistutilsPlatformError("Required Pyd source file '%s' is" 
     164                        " missing." % filePath 
     165                   
     166                sources.append(filePath) 
    165167        # And StackThreads 
    166         for file in _stFiles: 
    167             filePath = os.path.join(_infraDir, 'st', file) 
    168             if not os.path.isfile(filePath): 
    169                 raise DistutilsPlatformError("Required StackThreads source" 
    170                     " file '%s' is missing." % filePath 
    171                 ) 
    172             sources.append(filePath) 
     168        if not flags[1]: 
     169            for file in _stFiles: 
     170                filePath = os.path.join(_infraDir, 'st', file) 
     171                if not os.path.isfile(filePath): 
     172                    raise DistutilsPlatformError("Required StackThreads source" 
     173                        " file '%s' is missing." % filePath 
     174                    ) 
     175                sources.append(filePath) 
    173176        # And meta 
    174         for file in _metaFiles: 
    175             filePath = os.path.join(_infraDir, 'meta', file) 
    176             if not os.path.isfile(filePath): 
    177                 raise DistutilsPlatformError("Required meta source file" 
    178                     " '%s' is missing." % filePath 
    179                 ) 
    180             sources.append(filePath) 
     177        if not flags[2]: 
     178            for file in _metaFiles: 
     179                filePath = os.path.join(_infraDir, 'meta', file) 
     180                if not os.path.isfile(filePath): 
     181                    raise DistutilsPlatformError("Required meta source file" 
     182                        " '%s' is missing." % filePath 
     183                    ) 
     184                sources.append(filePath) 
    181185        # Add the infraDir to the include path for pyd, st, and meta. 
    182         includePathOpts += self._includeOpts 
    183         includePathOpts[-1] = includePathOpts[-1] % os.path.join(_infraDir) 
     186        if False in flags: 
     187            includePathOpts += self._includeOpts 
     188            includePathOpts[-1] = includePathOpts[-1] % os.path.join(_infraDir) 
    184189         
    185190        # Add DLL/SO boilerplate code file. 
  • trunk/examples/testdll/readme.txt

    r24 r46  
    1 After setting the D_ROOT environment variable, execute the conventional distutils command 
     1This example runs through many of the advanced features of Pyd. 
    22 
     3Execute the conventional distutils command 
    34    python setup.py build 
    4  
    55to build. 
    66 
    77Then execute 
    8  
    98    python test.py 
    10  
    119to exercise this example extension. 
  • trunk/html_doc/celerid.html

    r45 r46  
    4343 
    4444<pre class="code">&gt;python setup.py build</pre> 
     45 
     46<p>The Python module <code>celerid.support</code>, when imported, hot-patches distutils to know about the D compiler. It also provides the following:</p> 
     47 
     48<dl> 
     49<dt><code>setup</code></dt> <dd>This is simply an alias of <code>distutils.core.setup</code>, included here so you only have to import <code>celerid.support</code> in your setup.py module.</dd> 
     50 
     51<dt><code>Extension</code></dt> <dd>This is a subclass of <code>distutils.core.Extension</code>. It supports all of the arguments of the base class, with the exception of <code>define_macros</code> and <code>undef_macros</code>. D does not have a preprocessor, so an exception will be raised if you attempt to use either of these options. This class also supports these additional arguments beyond the base class: 
     52    <dl> 
     53    <dt><code>version_flags</code></dt> <dd>This should be a list of strings, which will be passed to the D compiler as version flags.</dd> 
     54    <dt><code>debug_flags</code></dt> <dd>Similar to <code>version_flags</code>, the strings in this list will be passed to D as debug flags.</dd> 
     55    <dt><code>raw_only</code></dt> <dd>This flag defaults to <code>False</code>. When <code>True</code>, it supresses the compilation and linkage of Pyd, StackThreads, and meta. This is useful if you only want to write a raw Python/C extension without the overhead of Pyd and its auxiliary packages. This is equivalent to specifying <code>True</code> to the next three flags.</dd> 
     56    <dt><code>no_pyd</code></dt> <dd>This flag defaults to <code>False</code>. When <code>True</code>, it supresses the compilation and linkage of Pyd. This is useful if you want to write a raw Python/C extension and don't want the overhead of compiling Pyd.</dd> 
     57    <dt><code>no_st</code></dt> <dd>This flag defaults to <code>False</code>. When <code>True</code>, it supresses the compilation and linkage of StackThreads. Because Pyd depends on StackThreads, an exception will be raised if this is specified and <code>no_pyd</code> is not.</dd> 
     58    <dt><code>no_meta</code></dt> <dd>This flag defaults to <code>False</code>. When <code>True</code>, it supresses the compilation and linkage of <code>meta</code> (Pyd's metaprogramming package). Because Pyd depends on meta, an exception will be raised if this is specified and <code>no_pyd</code> is not.</dd> 
     59    </dl> 
     60</dd> 
     61</dl> 
    4562</div> 
    4663 
  • trunk/html_doc/except_wrapping.html

    r45 r46  
    3838<dd>This checks if a Python exception has been set and, if it has, throws a <code>PythonException</code> containing the set exception. It will also clear the Python error condition.</dd> 
    3939 
    40 <dt><code>PyObject* exception_catcher(PyObject* delegate() <span class="arg">dg</span>);</code</dt> 
    41 <dt><code>int exception_catcher(int delegate() <span class="arg">dg</span>);</code</dt> 
    42 <dd>These two functions call the passed delegate within a <code>try ... catch</code> block, and if any exception occurs, will set an appropriate Python error condidition and return an "invalid" value. (These are <code>null</code> for the <code>PyObject*</code> version, -1 for the <code>int</code> version.) Otherwise, it will simply return whatever the delegate does. It is recommended that any function that interfaces directly with Python place its contents within a function literal in a call to one of these functions. (D can usually infer the return type of a function literal. If it can't, you might want to review D's syntax for <a href="http://www.digitalmars.com/d/expression.html#FunctionLiteral">function literals</a>.) For example: 
     40<dt><code>T exception_catcher(<span class="t_arg">T</span>) (T delegate() <span class="arg">dg</span>);</code</dt> 
     41<dd>This template function calls the passed delegate within a <code>try ... catch</code> block, and if any exception occurs, sets an appropriate Python error condidition and returns an "invalid" value. (These are <code>null</code> for <code>PyObject*</code> and -1 for <code>int</code>. These and <code>void</code> are the only acceptable types which may be passed to <code>T</code>.) Otherwise, it will simply return whatever the delegate does. It is recommended that any function that interfaces directly with Python place its contents within a function literal in a call to this function. (D can usually infer the return type of a function literal. If it can't, you might want to review D's syntax for <a href="http://www.digitalmars.com/d/expression.html#FunctionLiteral">function literals</a>.) For example: 
    4342 
    4443<pre class="code"><span class="keyword">extern</span> (C) 
  • trunk/infrastructure/pyd/exception.d

    r37 r46  
    2323 
    2424private import python; 
     25private import meta.Nameof; 
    2526private import std.string; 
    2627 
     
    4041} 
    4142 
     43// Used internally. 
     44T error_code(T) () { 
     45    static if (is(T == PyObject*)) { 
     46        return null; 
     47    } else static if (is(T == int)) { 
     48        return -1; 
     49    } else static if (is(T == void)) { 
     50        return; 
     51    } else static assert(false, "exception_catcher cannot handle return type " ~ prettytypeof!(T)); 
     52} 
     53 
    4254/** 
    4355 * It is intended that any functions that interface directly with Python which 
     
    5264 *}) 
    5365 */ 
    54 PyObject* exception_catcher(PyObject* delegate() dg) { 
     66T exception_catcher(T) (T delegate() dg) { 
    5567    try { 
    5668        return dg(); 
     
    6072    catch (PythonException e) { 
    6173        PyErr_Restore(e.type(), e.value(), e.traceback()); 
    62         return null
     74        return error_code!(T)()
    6375    } 
    6476    // A D exception was raised and should be translated into a meaningful 
     
    6678    catch (Exception e) { 
    6779        PyErr_SetString(PyExc_RuntimeError, "D Exception: " ~ e.classinfo.name ~ ": " ~ e.msg ~ \0); 
    68         return null
     80        return error_code!(T)()
    6981    } 
    7082    // Some other D object was thrown. Deal with it. 
    7183    catch (Object o) { 
    7284        PyErr_SetString(PyExc_RuntimeError, "thrown D Object: " ~ o.classinfo.name ~ ": " ~ o.toString() ~ \0); 
    73         return null; 
    74     } 
    75 
    76  
    77 // XXX: Some way to combine this with the above? 
    78 int exception_catcher(int delegate() dg) { 
    79     try { 
    80         return dg(); 
    81     } 
    82     // A Python exception was raised and duly re-thrown as a D exception. 
    83     // It should now be re-raised as a Python exception. 
    84     catch (PythonException e) { 
    85         PyErr_Restore(e.type(), e.value(), e.traceback()); 
    86         return -1; 
    87     } 
    88     // A D exception was raised and should be translated into a meaningful 
    89     // Python exception. 
    90     catch (Exception e) { 
    91         PyErr_SetString(PyExc_RuntimeError, "D Exception: " ~ e.classinfo.name ~ ": " ~ e.msg ~ \0); 
    92         return -1; 
    93     } 
    94     // Some other D object was thrown. Deal with it. 
    95     catch (Object o) { 
    96         PyErr_SetString(PyExc_RuntimeError, "thrown D Object: " ~ o.classinfo.name ~ ": " ~ o.toString() ~ \0); 
    97         return -1; 
     85        return error_code!(T)(); 
    9886    } 
    9987} 
  • trunk/support.py

    r24 r46  
    55from distutils.core import setup, Extension as std_Extension 
    66from distutils.errors import DistutilsOptionError 
    7  
    87 
    98class Extension(std_Extension): 
     
    4039                del kwargs['debug_flags'] 
    4140 
     41        # Similarly, pass in no_pyd, &c, via define_macros. 
     42        if 'raw_only' in kwargs: 
     43            kwargs['no_pyd'] = True 
     44            kwargs['no_st'] = True 
     45            kwargs['no_meta'] = True 
     46            del kwargs['raw_only'] 
     47        no_pyd  = kwargs.pop('no_pyd', False) 
     48        no_st   = kwargs.pop('no_st', False) 
     49        no_meta = kwargs.pop('no_meta', False) 
     50        if not no_pyd and (no_st or no_meta): 
     51            raise DistutilsOptionError( 
     52                'Cannot specify no_st or no_meta while using Pyd. Specify' 
     53                ' raw_only or no_pyd if you want to compile a raw Python/C' 
     54                ' extension.' 
     55            ) 
     56        define_macros.append(((no_pyd, no_st, no_meta), 'aux')) 
    4257        kwargs['define_macros'] = define_macros 
    4358 
    4459        std_Extension.__init__(self, *args, **kwargs) 
     60