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:
parent
e6529b608e
commit
ad45adbadd
@ -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).
|
||||
|
@ -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<typename T>
|
||||
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 :
|
||||
|
@ -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;
|
||||
|
@ -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)])
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user