3
0
mirror of https://github.com/triqs/dft_tools synced 2024-12-25 13:53:40 +01:00

wrapper: add static methods

- is_static= True to wrap a static method.
This commit is contained in:
Olivier Parcollet 2014-05-30 11:11:28 +02:00
parent e6529b608e
commit ad45adbadd
4 changed files with 37 additions and 5 deletions

View File

@ -38,7 +38,7 @@ class cfunction :
INCOMPATIBLE with c_name. INCOMPATIBLE with c_name.
If c_name is given, the default calling_pattern is made. 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""" """ Use keywords to build, from the data. Cf doc of class"""
self.c_name = kw.pop("c_name", None) self.c_name = kw.pop("c_name", None)
self._calling_pattern = kw.pop("calling_pattern", 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" assert not(self.c_name and self._calling_pattern), "You can not specify c_name and calling_pattern"
self.doc = doc self.doc = doc
self.is_method = is_method self.is_method = is_method
self.is_static = is_static
self.args = [] self.args = []
if 'signature' in kw : if 'signature' in kw :
assert 'rtype' not in kw and 'args' not in kw, "signature and rtype/args are not compatible" 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) : def calling_pattern(self) :
if self._calling_pattern : return self._calling_pattern if self._calling_pattern : return self._calling_pattern
s= "%s result = "%self.rtype if self.rtype != "void" else "" 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 ! # the wrapped types are called by pointer !
# do we want to keep it this way ? # 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])) 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... The function must take a python object, and return one...
- module : module path to the function [pure python only] - 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""" """ Use keywords to build, from the data. Cf doc of class"""
self.py_name =py_name # name given in python self.py_name =py_name # name given in python
self.doc = doc self.doc = doc
self.arity = arity self.arity = arity
self.is_method = is_method # can be a method, a function... 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.python_precall, self.python_postcall = python_precall, python_postcall
self.overloads = [] # List of all C++ overloads self.overloads = [] # List of all C++ overloads
self.do_implement = True # in some cases, we do not want to implement it automatically, (special methods). self.do_implement = True # in some cases, we do not want to implement it automatically, (special methods).

View File

@ -302,7 +302,7 @@ static PyGetSetDef ${c.py_type}_getseters[] = {
static PyMethodDef ${c.py_type}_methods[] = { static PyMethodDef ${c.py_type}_methods[] = {
%for meth_name, meth in c.methods.items(): %for meth_name, meth in c.methods.items():
%if not meth_name.startswith('__') : %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 %endif
%endfor %endfor
%if c.serializable : %if c.serializable :
@ -532,9 +532,12 @@ template<typename T>
static char *kwlist[] = {${",".join([ '"%s"'%n for t,n,d in overload.args] + ["NULL"])}}; static char *kwlist[] = {${",".join([ '"%s"'%n for t,n,d in overload.args] + ["NULL"])}};
static const char * format = "${overload.format()}"; 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 (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); auto & self_c = convert_from_python<${self_c_type}>(self);
%endif %endif
%if overload.is_static :
using self_class = ${self_c_type};
%endif
try { try {
${overload.calling_pattern()}; // the call is here. It sets up "result" : sets up in the python layer. ${overload.calling_pattern()}; // the call is here. It sets up "result" : sets up in the python layer.
%if not overload.is_constructor : %if not overload.is_constructor :

View File

@ -38,6 +38,28 @@ struct A {
return x + 2 * u + 3 * y; 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 { double m1(int u) const {
std::cout << " calling m1 one arg " << u << std::endl; std::cout << " calling m1 one arg " << u << std::endl;

View File

@ -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 # 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 = "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 # 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)]) #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)])