From: Alf P. Steinbach /Usenet on 12 Jul 2010 04:06 Hi. With the current cppy code the Python 3.1.1 doc's spam example extension module looks like this (actual working code): <code> #include <progrock/cppx/devsupport/better_experience.h> #include <progrock/cppy/Module.h> using namespace progrock; namespace { class Spam: public cppy::Module { public: Spam(): cppy::Module( L"spam", L"bl�b�rsyltet�y er bl�tt" ) {} PyObject* system( PyObject* args ) { const char *command; if( !PyArg_ParseTuple( args, "s", &command ) ) { return NULL; } int const sts = ::system( command ); return Py_BuildValue( "i", sts ); } }; } // namespace <anon> CPPY_MODULE_CROUTINE( Spam, system, L"Execute a shell command" ) PyMODINIT_FUNC PyInit_spam() { return cppy::safeInit< Spam >(); } </code> Issues: 1. Wide string literals OK? The basic Python API often requires UTF-8 encoded byte strings. With C++ source code encoded using e.g. Windows ANSI Western, string literals with national characters such as Norwegian ��� then become gobbledegook or cause outright failure. I balanced the hypothetical need for string literals with national characters, versus perceived unnaturalness of wide string literals for *nix developers, in favor of the former, i.e. L"wide string literals". Related issue here: in Windows MinGW g++ can not compile utf-8 encoded source with BOM, while MSVC requires a BOM in order to detect the encoding. Is L"this" an acceptable decision if you were to use something like cppy? 2. Exception translation OK? The code within the 'system' member routine could conceivably be reduced to a single short line by adding some C++ support, but that would require use of exceptions to report errors. Translating C++ exceptions to Python exceptions does however add some overhead to every Python -> C++ call. Currently I do this only for the module initialization code, but should it be done for every exported method? Or perhaps as user choice? Benefit of translation e.g. reducing 'system' above to sweet single line. Cost is setup of try-block (negligible) and exception translation (inefficient). 3. Some unsafety OK? In 'PyInit_spam' there may be a window of opportunity for client code to Mess Things Up. Within the cppy::safeInit the C++ module object is created and creates a Python module object, and if anything fails then the C++ side frees the Python object. And after PyInit_spam has returned to Python the cleanup responsibility resides with the Python interpreter: freeing the Python module object causes the C++ object to be destroyed. But if say the client code's equivalent of 'PyInit_spam' calls cppy::safeInit and just discards the result and returns 0 (say) to Python, then it seems to not be documented whether Python will free the Python module, i.e. possible leak. 4. Threading? Is it necessary to make singletons/statics thread safe? Or does Python ensure that no other threads execute while PyInit_spam is called? Can it be called simultaneously by two or more threads? 5. Reload of interpreter? My impression from the documentation is that finalization and reinit of the interpreter is something that an application shouldn't really do, and that an extension developer need not worry about that happening. Is it so? Cheers, - Alf -- blog at <url: http://alfps.wordpress.com>
|
Pages: 1 Prev: Numpy now supports Python3, Scipy to follow soon Next: round issue |