Exemple #1
0
    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())
Exemple #2
0
    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())