McMillan Enterprises, Inc. |
|
SCXX classesPWOBaseThe base class for all PWOxxx classes. You can think of this as a PyObject * which may be NULL. Use it to wrap arbitrary Python objects. Takes care of reference counts. Most of the PyObject_xxx calls are available as methods (hasAttr, getAttr, setAttr, delAttr, print, cmp, repr, str, isCallable, hash, isTrue, type and cmp). In addition, the comparison operators are mapped to cmp (this version does not go through the new comparison protocol). Finally, PWOBase::disOwn() allows the wrapper to be destroyed without decrementing the PyObject's refcount (use this to return an object to Python). All of the other wrapping objects are subclasses of PWOBase. PWONumberWraps numbers at the PyNumber_XXX level. Can be constructed from a PyObject * (PyNumber_Check will be called), or a C int, long, unsigned long or double. Has operator overloads for the arithmetic and bitwise operators as well as abs, divmod, and casts back to C types (conversions performed if necessary). PWOSequenceWraps any Python sequence type. Can only be created from a sequence object (use one of the concrete classes to create a new list, tuple or string). Operators are overloaded in the same way Python does it (eq, Also supports PWOTupleWraps or creates PyTuple objects. When creating a new tuple, you must set the size PWOListWraps or creates a list. In addition to the methods and operators you would expect from above, you can use operator PWOListMmbrThese are temporary objects which "remember" a PWOList and index. They are there to support using operator PWOStringWraps or creates a PyString object. Creating a PWOString can take a normal null-terminated string, or a binary string and size. Casting to Like a Python string, PWOStrings are immutable. PWOMappingWraps or creates a Python dictionary. Supports operator PWOMappingMmbrThese are temporary objects which "remember" a PWOMapping and key. They are there to support using operator PWOCallableWraps a callable object (anything that for which PyCallable_Check() returns true). Has one new method, PWOModuleWraps a module object. Has three new methods: getDict(), getName() and getFilename(). PWExceptionThese are lightweight C++ exceptions that set the Python exception for you. Casting one to PyObject * will return NULL to Python.
To throw:
Catching:
PWCallbackExceptionA subclass of PWException that leaves the Python exception (as set by the callback) alone. Used by PWOCallable to transmit the inner Python exception to the outer Python interpreter. You shouldn't need to throw one. Catch them exactly as above. PWEngineThis class attempts to make sense of the highly confusing area of Python threads. It is a singleton class (in the Borg pattern - all state is shared; creation and destruction are nearly no-ops). It has one user-callable method: Create a static PWEngine in your initmodule method, and immediately call recordThread(). In methods which might get called on a previously unknown Python thread, call PWEngine().recordThread(). When you want to release the Python lock, use the FreeThreadedBlock class (on the stack). Where you need to aquire the Python lock (and the right threadstate), use a (stack based) PythonThreadedBlock. FreeThreadedBlock
PythonThreadedBlockThe inverse of a FreeThreadedBlock. As long as the OS thread ID has been seen before and the corresponding Python threadstate is still valid, a PythonThreadedBlock will reaquire the lock. Actually, it will create a new threadstate if it can't find one. As long as it knows about the right Python interpreterstate, it will work (with only one interpreter, that means as long as recordThread() has been called at least once). But if you're using mulitple Python interpreters and it can't find an existing threadstate, you might end up in the wrong interpreter!
I don't like it, that's why. It started out as a handy convenience, but at this point it has developed into a pure line-noise sub-language. SCXX takes care of much of the drudgery for you.
In this very bare example, the user passing wrong args will get a slightly poorer message in his exception than if you used PyArg_ParseTuple. On the other hand, by the time you dressed up your code to be specific about what was wrong with what arg, you might well have less code doing it this way (and, in my opinion, much clearer code). |
|
copyright 2002 McMillan Enterprises, Inc. |