From df1774dd19af3dd9b713969b7ab9b99ea70ce923 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 31 May 2007 14:10:51 +0100 Subject: [PATCH] Add support for generating PyMethodDef function tables. --- pybindgen/functionwrapper.py | 16 ++++++++++++++++ pybindgen/typehandlers/base.py | 12 ++++++++++++ tests/test-generation.py | 14 +++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/pybindgen/functionwrapper.py b/pybindgen/functionwrapper.py index 0ad10e9..4ec07df 100644 --- a/pybindgen/functionwrapper.py +++ b/pybindgen/functionwrapper.py @@ -21,6 +21,7 @@ class FunctionWrapper(ForwardWrapperBase): parse_error_return="return NULL;", error_return="return NULL;") self.function_name = function_name + self.was_generated = False def generate_call(self): "virtual method implementation; do not call" @@ -46,3 +47,18 @@ class FunctionWrapper(ForwardWrapperBase): tmp_sink.flush_to(code_sink) code_sink.unindent() code_sink.writeln('}') + self.was_generated = True + + def get_py_method_def(self, name, docstring=None): + """Returns an array element to use in a PyMethodDef table. + Should only be called after code generation. + + name -- python function/method name + docstring -- documentation string, or None + """ + assert self.was_generated + flags = self.get_py_method_def_flags() + return "{\"%s\", (PyCFunction) _wrap_%s, %s, %s }," % \ + (name, self.function_name, '|'.join(flags), + (docstring is None and "NULL" or ('"'+docstring+'"'))) + diff --git a/pybindgen/typehandlers/base.py b/pybindgen/typehandlers/base.py index 0534682..9d5bc9f 100644 --- a/pybindgen/typehandlers/base.py +++ b/pybindgen/typehandlers/base.py @@ -658,6 +658,18 @@ class ForwardWrapperBase(object): self.before_call.sink.flush_to(code_sink) self.after_call.sink.flush_to(code_sink) + def get_py_method_def_flags(self): + """ + Get a list of PyMethodDef flags that should be used for this wrapper. + """ + if self.parameters: + if self.parse_params.get_keywords() is None: + return ["METH_VARARGS"] + else: + return ["METH_VARARGS", "METH_KEYWORDS"] + else: + return ["METH_NOARGS"] + class ReturnValue(object): '''Abstract base class for all classes dedicated to handle diff --git a/tests/test-generation.py b/tests/test-generation.py index 63a5a95..13225e9 100755 --- a/tests/test-generation.py +++ b/tests/test-generation.py @@ -50,6 +50,7 @@ def test(): print ## test generic forward wrappers + function_defs = [] for return_type, return_handler in typehandlers.base.return_type_matcher.items(): for param_type, param_handler in typehandlers.base.param_type_matcher.items(): for direction in param_handler.DIRECTIONS: @@ -73,8 +74,19 @@ def test(): except typehandlers.base.CodeGenerationError, ex: print >> sys.stderr, "SKIPPING %s %s(%s): %s" % \ (return_type, function_name, param_type, str(ex)) + continue print - + function_defs.append(wrapper.get_py_method_def(function_name)) + + code_out.writeln("static PyMethodDef foo_functions[] = {") + code_out.indent() + for funcdef in function_defs: + code_out.writeln(funcdef) + code_out.writeln("{NULL, NULL, 0, NULL}") + code_out.unindent() + code_out.writeln("};") + + if __name__ == '__main__': test()