def __str__(self): """Generate (i.e. yield) the source code of the module line-by-line. """ themethods = [] theextraobjects = [] theoverloads = [] for vname in self.global_vars: theextraobjects.append( 'PyModule_AddObject(theModule, "{0}", {0});'.format(vname)) for fname, overloads in self.functions.items(): tryall = [] signatures = [] for overload, ctypes, signature in overloads: try_ = dedent(""" if(PyObject* obj = {name}(self, args, kw)) return obj; PyErr_Clear(); """.format(name=overload)) tryall.append(try_) signatures.append(signature) candidates = signatures_to_string(fname, signatures) wrapper_name = pythran_ward + 'wrapall_' + fname candidate = dedent(''' static PyObject * {wname}(PyObject *self, PyObject *args, PyObject *kw) {{ return pythonic::handle_python_exception([self, args, kw]() -> PyObject* {{ {tryall} return pythonic::python::raise_invalid_argument( "{name}", {candidates}, args, kw); }}); }} '''.format(name=fname, tryall="\n".join(tryall), candidates=self.splitstring( candidates.replace('\n', '\\n')), wname=wrapper_name)) fdoc = self.docstring(self.docstrings.get(fname, '')) themethod = dedent('''{{ "{name}", (PyCFunction){wname}, METH_VARARGS | METH_KEYWORDS, {doc}}}'''.format(name=fname, wname=wrapper_name, doc=fdoc)) themethods.append(themethod) theoverloads.append(candidate) for ptrname, sig in self.capsules: capsule = ''' PyModule_AddObject(theModule, "{ptrname}", PyCapsule_New((void*)&{ptrname}, "{sig}", NULL) );'''.format(ptrname=ptrname, sig=sig) theextraobjects.append(capsule) methods = dedent(''' static PyMethodDef Methods[] = {{ {methods} {{NULL, NULL, 0, NULL}} }}; '''.format(methods="".join(m + "," for m in themethods))) module = dedent(''' #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = {{ PyModuleDef_HEAD_INIT, "{name}", /* m_name */ {moduledoc}, /* m_doc */ -1, /* m_size */ Methods, /* m_methods */ NULL, /* m_reload */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ }}; #define PYTHRAN_RETURN return theModule #define PYTHRAN_MODULE_INIT(s) PyInit_##s #else #define PYTHRAN_RETURN return #define PYTHRAN_MODULE_INIT(s) init##s #endif PyMODINIT_FUNC PYTHRAN_MODULE_INIT({name})(void) #ifndef _WIN32 __attribute__ ((visibility("default"))) __attribute__ ((externally_visible)) #endif ; PyMODINIT_FUNC PYTHRAN_MODULE_INIT({name})(void) {{ import_array() #if PY_MAJOR_VERSION >= 3 PyObject* theModule = PyModule_Create(&moduledef); #else PyObject* theModule = Py_InitModule3("{name}", Methods, {moduledoc} ); #endif if(! theModule) PYTHRAN_RETURN; PyObject * theDoc = Py_BuildValue("(sss)", "{version}", "{date}", "{hash}"); if(! theDoc) PYTHRAN_RETURN; PyModule_AddObject(theModule, "__pythran__", theDoc); {extraobjects} PYTHRAN_RETURN; }} '''.format(name=self.name, extraobjects='\n'.join(theextraobjects), **self.metadata)) body = (self.preamble + self.includes + self.implems + [Line('#ifdef ENABLE_PYTHON_MODULE')] + self.python_implems + [Line(code) for code in self.wrappers + theoverloads] + [Line(methods), Line(module), Line('#endif')]) return "\n".join(Module(body).generate())
def __str__(self): """Generate (i.e. yield) the source code of the module line-by-line. """ themethods = [] theextraobjects = [] theoverloads = [] for vname in self.global_vars: theextraobjects.append( 'PyModule_AddObject(theModule, "{0}", {0});'.format(vname)) for fname, overloads in self.functions.items(): tryall = [] signatures = [] for overload, ctypes, signature in overloads: try_ = dedent(""" if(PyObject* obj = {name}(self, args, kw)) return obj; PyErr_Clear(); """.format(name=overload)) tryall.append(try_) signatures.append(signature) candidates = signatures_to_string(fname, signatures) wrapper_name = pythran_ward + 'wrapall_' + fname candidate = dedent(''' static PyObject * {wname}(PyObject *self, PyObject *args, PyObject *kw) {{ return pythonic::handle_python_exception([self, args, kw]() -> PyObject* {{ {tryall} return pythonic::python::raise_invalid_argument( "{name}", "{candidates}", args, kw); }}); }} '''.format(name=fname, tryall="\n".join(tryall), candidates=candidates.replace('\n', '\\n'), wname=wrapper_name)) fdoc = self.docstring(self.docstrings.get(fname, '')) themethod = dedent('''{{ "{name}", (PyCFunction){wname}, METH_VARARGS | METH_KEYWORDS, {doc}}}'''.format(name=fname, wname=wrapper_name, doc=fdoc)) themethods.append(themethod) theoverloads.append(candidate) for ptrname, sig in self.capsules: capsule = ''' PyModule_AddObject(theModule, "{ptrname}", PyCapsule_New((void*)&{ptrname}, "{sig}", NULL) );'''.format(ptrname=ptrname, sig=sig) theextraobjects.append(capsule) methods = dedent(''' static PyMethodDef Methods[] = {{ {methods} {{NULL, NULL, 0, NULL}} }}; '''.format(methods="".join(m + "," for m in themethods))) module = dedent(''' #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = {{ PyModuleDef_HEAD_INIT, "{name}", /* m_name */ {moduledoc}, /* m_doc */ -1, /* m_size */ Methods, /* m_methods */ NULL, /* m_reload */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL, /* m_free */ }}; #define PYTHRAN_RETURN return theModule #define PYTHRAN_MODULE_INIT(s) PyInit_##s #else #define PYTHRAN_RETURN return #define PYTHRAN_MODULE_INIT(s) init##s #endif PyMODINIT_FUNC PYTHRAN_MODULE_INIT({name})(void) #ifndef _WIN32 __attribute__ ((visibility("default"))) __attribute__ ((externally_visible)) #endif ; PyMODINIT_FUNC PYTHRAN_MODULE_INIT({name})(void) {{ import_array() #if PY_MAJOR_VERSION >= 3 PyObject* theModule = PyModule_Create(&moduledef); #else PyObject* theModule = Py_InitModule3("{name}", Methods, {moduledoc} ); #endif if(! theModule) PYTHRAN_RETURN; PyObject * theDoc = Py_BuildValue("(sss)", "{version}", "{date}", "{hash}"); if(! theDoc) PYTHRAN_RETURN; PyModule_AddObject(theModule, "__pythran__", theDoc); {extraobjects} PYTHRAN_RETURN; }} '''.format(name=self.name, extraobjects='\n'.join(theextraobjects), **self.metadata)) body = (self.preamble + self.includes + self.implems + [Line('#ifdef ENABLE_PYTHON_MODULE')] + self.python_implems + [Line(code) for code in self.wrappers + theoverloads] + [Line(methods), Line(module), Line('#endif')]) return "\n".join(Module(body).generate())