diff --git a/pytriqs/wrap_generator/wrap_generator.py b/pytriqs/wrap_generator/wrap_generator.py index 0ecf7a63..6923e6c5 100644 --- a/pytriqs/wrap_generator/wrap_generator.py +++ b/pytriqs/wrap_generator/wrap_generator.py @@ -38,7 +38,7 @@ class cfunction : INCOMPATIBLE with c_name. If c_name is given, the default calling_pattern is made. """ - def __init__(self, doc = '', is_method = False, no_self_c = False, **kw) : + def __init__(self, doc = '', is_method = False, no_self_c = False, is_static = False, **kw) : """ Use keywords to build, from the data. Cf doc of class""" self.c_name = kw.pop("c_name", None) self._calling_pattern = kw.pop("calling_pattern", None) @@ -48,6 +48,7 @@ class cfunction : assert not(self.c_name and self._calling_pattern), "You can not specify c_name and calling_pattern" self.doc = doc self.is_method = is_method + self.is_static = is_static self.args = [] if 'signature' in kw : assert 'rtype' not in kw and 'args' not in kw, "signature and rtype/args are not compatible" @@ -81,7 +82,9 @@ class cfunction : def calling_pattern(self) : if self._calling_pattern : return self._calling_pattern s= "%s result = "%self.rtype if self.rtype != "void" else "" - self_c = "self_c." if self.is_method else "" + self_c = "" + if self.is_method: + self_c = "self_c." if not self.is_static else "self_class::" # the wrapped types are called by pointer ! # do we want to keep it this way ? return "%s %s%s(%s)"%(s,self_c, self.c_name , ",".join([ ('*' if t in module_.wrapped_types else '') + n for t,n,d in self.args])) @@ -128,12 +131,13 @@ class pyfunction : The function must take a python object, and return one... - module : module path to the function [pure python only] """ - def __init__(self, py_name, is_method = False, doc = '', python_precall = None, python_postcall = None, arity = None, **unused) : + def __init__(self, py_name, is_method = False, is_static = False, doc = '', python_precall = None, python_postcall = None, arity = None, **unused) : """ Use keywords to build, from the data. Cf doc of class""" self.py_name =py_name # name given in python self.doc = doc self.arity = arity self.is_method = is_method # can be a method, a function... + self.is_static = is_static # self.python_precall, self.python_postcall = python_precall, python_postcall self.overloads = [] # List of all C++ overloads self.do_implement = True # in some cases, we do not want to implement it automatically, (special methods). diff --git a/pytriqs/wrap_generator/wrapper.mako.cpp b/pytriqs/wrap_generator/wrapper.mako.cpp index 177596b2..600f23a2 100644 --- a/pytriqs/wrap_generator/wrapper.mako.cpp +++ b/pytriqs/wrap_generator/wrapper.mako.cpp @@ -302,7 +302,7 @@ static PyGetSetDef ${c.py_type}_getseters[] = { static PyMethodDef ${c.py_type}_methods[] = { %for meth_name, meth in c.methods.items(): %if not meth_name.startswith('__') : - {"${meth_name}", (PyCFunction)${c.py_type}_${meth_name}, METH_VARARGS| METH_KEYWORDS, "${c.methods[meth_name].generate_doc()}" }, + {"${meth_name}", (PyCFunction)${c.py_type}_${meth_name}, METH_VARARGS| METH_KEYWORDS ${"|METH_STATIC" if meth.is_static else ""}, "${c.methods[meth_name].generate_doc()}" }, %endif %endfor %if c.serializable : @@ -532,9 +532,12 @@ template static char *kwlist[] = {${",".join([ '"%s"'%n for t,n,d in overload.args] + ["NULL"])}}; static const char * format = "${overload.format()}"; if (PyArg_ParseTupleAndKeywords(args, keywds, format, kwlist ${"".join([ module.get_proper_converter(t) + ' ,&%s'%n for t,n,d in overload.args])})) { - %if overload.is_method and not overload.is_constructor and not overload.no_self_c : + %if overload.is_method and not overload.is_constructor and not overload.no_self_c and not overload.is_static : auto & self_c = convert_from_python<${self_c_type}>(self); %endif + %if overload.is_static : + using self_class = ${self_c_type}; + %endif try { ${overload.calling_pattern()}; // the call is here. It sets up "result" : sets up in the python layer. %if not overload.is_constructor : diff --git a/pytriqs/wrap_test/a.hpp b/pytriqs/wrap_test/a.hpp index 3a88c2ef..e353765b 100644 --- a/pytriqs/wrap_test/a.hpp +++ b/pytriqs/wrap_test/a.hpp @@ -38,6 +38,28 @@ struct A { return x + 2 * u + 3 * y; } + static int sm(int i) { return i*2;} + + int count =0; + + void long_fnt() { + + PyOS_sighandler_t sig = PyOS_getsig(SIGINT); + Py_BEGIN_ALLOW_THREADS; + for (int u = 0; u < 101; u +=10) { + sleep(1); + if (!triqs::signal_handler().empty()) goto _end; + count = u; + std::cout << " inner count " << count << std::endl; + } + std::cout << " completed" << std::endl; + _end: + + Py_END_ALLOW_THREADS; + PyOS_setsig(SIGINT, sig); + + // PyErr_SetString(PyExc_KeyboardInterrupt, " ended long_fnt"); + } double m1(int u) const { std::cout << " calling m1 one arg " << u << std::endl; diff --git a/pytriqs/wrap_test/my_module_desc.py b/pytriqs/wrap_test/my_module_desc.py index 8727f492..0f67d4e7 100644 --- a/pytriqs/wrap_test/my_module_desc.py +++ b/pytriqs/wrap_test/my_module_desc.py @@ -30,6 +30,9 @@ g.add_method(py_name = "m1p", c_name = "m1", signature = "double (int u, double # demo of adding a simple piece of C++ code, there is no C++ method corresponding g.add_method(py_name = "m1_x", calling_pattern = "bool result = (self_c.x >0) && (self_c.x < 10)" , signature = "bool()", doc = "A method which did not exist in C++") +# +g.add_method(py_name = "sm", c_name = "sm", signature = "int (int u)", is_static = True, doc = "a static method") + # alternative syntax #g.add_method(py_name = "m1", python_precall = "aux.ffg", python_postcall = "aux.post1").add_overload(c_name = "m1", rtype = "double", doc = "DOC of mm", args = [("int","u"), ("double","y",3)])