Register PyMethodDefs for glued methods. Create PyMethodDef entries for each wrapped Clownfish method.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/d8ced59c Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/d8ced59c Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/d8ced59c Branch: refs/heads/py_exp13 Commit: d8ced59cb135f628c0266e6aff0141152280f603 Parents: 71c836a Author: Marvin Humphrey <[email protected]> Authored: Tue Feb 2 17:13:28 2016 -0800 Committer: Marvin Humphrey <[email protected]> Committed: Wed Feb 24 15:36:07 2016 -0800 ---------------------------------------------------------------------- compiler/src/CFCPyClass.c | 5 +++++ compiler/src/CFCPyMethod.c | 21 +++++++++++++++++++++ compiler/src/CFCPyMethod.h | 5 +++++ runtime/python/test/test_clownfish.py | 2 ++ 4 files changed, 33 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d8ced59c/compiler/src/CFCPyClass.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPyClass.c b/compiler/src/CFCPyClass.c index 11a4905..529c6cf 100644 --- a/compiler/src/CFCPyClass.c +++ b/compiler/src/CFCPyClass.c @@ -160,6 +160,11 @@ CFCPyClass_gen_binding_code(CFCPyClass *self) { char *wrapper = CFCPyMethod_wrapper(meth, klass); bindings = CFCUtil_cat(bindings, wrapper, "\n", NULL); FREEMEM(wrapper); + + // Add PyMethodDef entry. + char *meth_def = CFCPyMethod_pymethoddef(meth, klass); + meth_defs = CFCUtil_cat(meth_defs, " ", meth_def, "\n", NULL); + FREEMEM(meth_def); } // Complete the PyMethodDef array. http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d8ced59c/compiler/src/CFCPyMethod.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c index 4220aea..1291568 100644 --- a/compiler/src/CFCPyMethod.c +++ b/compiler/src/CFCPyMethod.c @@ -519,3 +519,24 @@ CFCPyMethod_wrapper(CFCMethod *method, CFCClass *invoker) { return wrapper; } +char* +CFCPyMethod_pymethoddef(CFCMethod *method, CFCClass *invoker) { + CFCParamList *param_list = CFCMethod_get_param_list(method); + const char *flags = CFCParamList_num_vars(param_list) == 1 + ? "METH_NOARGS" + : "METH_KEYWORDS|METH_VARARGS"; + char *meth_sym = CFCMethod_full_method_sym(method, invoker); + char *micro_sym = CFCUtil_strdup(CFCSymbol_get_name((CFCSymbol*)method)); + for (int i = 0; micro_sym[i] != 0; i++) { + micro_sym[i] = tolower(micro_sym[i]); + } + + char pattern[] = + "{\"%s\", (PyCFunction)S_%s, %s, NULL},"; + char *py_meth_def = CFCUtil_sprintf(pattern, micro_sym, meth_sym, flags); + + FREEMEM(meth_sym); + FREEMEM(micro_sym); + return py_meth_def; +} + http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d8ced59c/compiler/src/CFCPyMethod.h ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPyMethod.h b/compiler/src/CFCPyMethod.h index 53768e2..b3d6808 100644 --- a/compiler/src/CFCPyMethod.h +++ b/compiler/src/CFCPyMethod.h @@ -31,6 +31,11 @@ struct CFCClass; char* CFCPyMethod_callback_def(struct CFCMethod *method, struct CFCClass *invoker); +/** Generate a PyMethodDef entry for an instance method. + */ +char* +CFCPyMethod_pymethoddef(struct CFCMethod *method, struct CFCClass *invoker); + char* CFCPyMethod_wrapper(struct CFCMethod *method, struct CFCClass *invoker); http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d8ced59c/runtime/python/test/test_clownfish.py ---------------------------------------------------------------------- diff --git a/runtime/python/test/test_clownfish.py b/runtime/python/test/test_clownfish.py index d8f2594..f7908ca 100644 --- a/runtime/python/test/test_clownfish.py +++ b/runtime/python/test/test_clownfish.py @@ -14,6 +14,7 @@ # limitations under the License. import unittest +import inspect import clownfish class MyTest(unittest.TestCase): @@ -23,6 +24,7 @@ class MyTest(unittest.TestCase): def testClassesPresent(self): self.assertIsInstance(clownfish.Hash, type) + self.assertTrue(inspect.ismethoddescriptor(clownfish.Hash.store)) if __name__ == '__main__': unittest.main()
