Changeset 46
- Timestamp:
- 11/20/06 19:32:54 (1 year ago)
- Files:
-
- trunk/dcompiler.py (modified) (1 diff)
- trunk/examples/hello (added)
- trunk/examples/hello/hello.d (added)
- trunk/examples/hello/readme.txt (added)
- trunk/examples/hello/setup.py (added)
- trunk/examples/hello/test.py (added)
- trunk/examples/rawexample (added)
- trunk/examples/rawexample/rawexample.d (added)
- trunk/examples/rawexample/readme.txt (added)
- trunk/examples/rawexample/setup.py (added)
- trunk/examples/rawexample/test.py (added)
- trunk/examples/testdll/readme.txt (modified) (1 diff)
- trunk/html_doc/celerid.html (modified) (1 diff)
- trunk/html_doc/except_wrapping.html (modified) (1 diff)
- trunk/infrastructure/pyd/exception.d (modified) (5 diffs)
- trunk/support.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/dcompiler.py
r45 r46 154 154 sources.append(pythonHeaderPath) 155 155 156 # flags = (no_pyd, no_st, no_meta) 157 flags = [f for f, category in macros if category == 'aux'][0] 156 158 # And Pyd! 157 # XXX: Add support for compiling without Pyd158 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." % filePath163 )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) 165 167 # 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) 173 176 # 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) 181 185 # 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) 184 189 185 190 # 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 1 This example runs through many of the advanced features of Pyd. 2 2 3 Execute the conventional distutils command 3 4 python setup.py build 4 5 5 to build. 6 6 7 7 Then execute 8 9 8 python test.py 10 11 9 to exercise this example extension. trunk/html_doc/celerid.html
r45 r46 43 43 44 44 <pre class="code">>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> 45 62 </div> 46 63 trunk/html_doc/except_wrapping.html
r45 r46 38 38 <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> 39 39 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: 43 42 44 43 <pre class="code"><span class="keyword">extern</span> (C) trunk/infrastructure/pyd/exception.d
r37 r46 23 23 24 24 private import python; 25 private import meta.Nameof; 25 26 private import std.string; 26 27 … … 40 41 } 41 42 43 // Used internally. 44 T 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 42 54 /** 43 55 * It is intended that any functions that interface directly with Python which … … 52 64 *}) 53 65 */ 54 PyObject* exception_catcher(PyObject*delegate() dg) {66 T exception_catcher(T) (T delegate() dg) { 55 67 try { 56 68 return dg(); … … 60 72 catch (PythonException e) { 61 73 PyErr_Restore(e.type(), e.value(), e.traceback()); 62 return null;74 return error_code!(T)(); 63 75 } 64 76 // A D exception was raised and should be translated into a meaningful … … 66 78 catch (Exception e) { 67 79 PyErr_SetString(PyExc_RuntimeError, "D Exception: " ~ e.classinfo.name ~ ": " ~ e.msg ~ \0); 68 return null;80 return error_code!(T)(); 69 81 } 70 82 // Some other D object was thrown. Deal with it. 71 83 catch (Object o) { 72 84 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)(); 98 86 } 99 87 } trunk/support.py
r24 r46 5 5 from distutils.core import setup, Extension as std_Extension 6 6 from distutils.errors import DistutilsOptionError 7 8 7 9 8 class Extension(std_Extension): … … 40 39 del kwargs['debug_flags'] 41 40 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')) 42 57 kwargs['define_macros'] = define_macros 43 58 44 59 std_Extension.__init__(self, *args, **kwargs) 60
