From: Ken S. <ksi...@tt...> - 2001-08-31 21:15:17
|
Jeff Youel posted some interesting questions in his recent Ethernet MAC address script (the first publicly announced script to use PyInline! -- see it at http://www.jeffyouel.com), which I have paraphrased in this email. Perhaps other PyInliners out there could help me find answers to Jeff's questions. 1. How do I raise Python exceptions from PyInline'd C code? To generate exceptions from your inlined Python functions, you must do some of the inlining legwork yourself. Rather than returning one of the standard C data types from your function, you must return a PyObject* and set up the return value using Py_BuildValue() or one of the other value-building functions in the Python C API. When you want to throw an exception, just call PyErr_SetString() or one of the other exception "throwing" functions and return NULL. For example, the following bit of Python defines a C function that adds two numbers together and returns the result, but which fires an exception if the result is zero. import PyInline m = PyInline.build(code=r""" PyObject* add(int a, int b) { PyObject* retval; int sum = a + b; if(sum == 0) { PyErr_SetString(PyExc_ValueError, "Sum must not be zero!"); return NULL; } else { retval = Py_BuildValue("i", sum); return retval; } } """, language="C") print m.add(10, 5) # Okay print m.add(10, -10) # Throws an exception. 2. How do I return dynamically allocated strings without leaking memory? Probably the easiest way to return a dynamically allocated string is to just return a PyObject* from your PyInlined function. For example, import PyInline m = PyInline.build(code=r""" PyObject* genstring(void) { PyObject* retval = Py_BuildValue("s", "This is my special string."); return retval; } """, language="C") str = m.genstring() print str PyInline knows that if you return a PyObject* from your inlined C function, the PyObject* should just be passed verbatim back to Python. 3. How can I ship my inline Python script along with its compiled binary extensions? Currently, the only way to ship the binary part of your inline script is to first run the script on your system to generate and compile any inlined C source code and then ship the _PyInline_abc34234... directory along with your script. I am currently discussing this problem with Brian Ingerson (of Inline for Perl fame) and hope to have a better solution soon. Probably the new solution will involve configuration files... 4. How do I keep from collecting dozens of _PyInline_* directories while I'm developing? Currently, "rm -r _PyInline*" is the most effective strategy to reduce clutter. In future, PyInline will provide a configuration file inside a much better-named directory (perhaps _PyInline_MyModuleName) which contains the MD5 checksum of all inlined sources so that PyInline knows when to do a rebuild. TTUL Ken On Fri, 31 Aug 2001, Ken Simpson wrote: > Hi Jeff, > I was wondering whether you would mind if I added your PyInline MAC > address script to the examples directory of PyInline? > > To my knowledge, your script is the first real-world use of PyInline! > > TTUL > Ken > > |