diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2010-01-21 13:33:26 -0300 |
---|---|---|
committer | Marcelo Lira <marcelo.lira@openbossa.org> | 2010-01-21 13:51:02 -0300 |
commit | 62bd3820c222cfb6af57c2ff4b23b8b819743bbf (patch) | |
tree | 26325d0b6ada5d79334f4ede59fc7432e9cfd482 /cppgenerator.cpp | |
parent | cd12b72f152f970a86cac12f62a0f9d1edd3f6d8 (diff) |
Adds support for Duck Punching (aka Monkey Patching).
The simplest definition of duck punching for our purposes is
the ability to change the definition of a method in an instance of
a class.
To allow this behaviour the SbkBaseWrapper structure had to be
extended with a 'ob_dict' which is a PyObject pointer to the instance
dictionary. It is originally set to NULL until the user tries to access
it. This dictionary could be accessed through the '__dict__' instance
property. For now it is read-only.
The generator was updated to handle the instance dictionary, and an
extensive duck punching test was also added.
Reviewed by Hugo Parente Lima <hugo.lima@openbossa.org>
Diffstat (limited to 'cppgenerator.cpp')
-rw-r--r-- | cppgenerator.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp index 45f35352a..5acaf0313 100644 --- a/cppgenerator.cpp +++ b/cppgenerator.cpp @@ -2347,6 +2347,19 @@ void CppGenerator::writeGetattroFunction(QTextStream& s, const AbstractMetaClass s << INDENT << "if (self) {" << endl; { Indentation indent(INDENT); + s << INDENT << "if (SbkBaseWrapper_instanceDict(self)) {" << endl; + { + Indentation indent(INDENT); + s << INDENT << "PyObject* meth = PyDict_GetItem(SbkBaseWrapper_instanceDict(self), name);" << endl; + s << INDENT << "if (meth) {" << endl; + { + Indentation indent(INDENT); + s << INDENT << "Py_INCREF(meth);" << endl; + s << INDENT << "return meth;" << endl; + } + s << INDENT << '}' << endl; + } + s << INDENT << '}' << endl; s << INDENT << "const char* cname = PyString_AS_STRING(name);" << endl; foreach (const AbstractMetaFunction* func, getMethodsWithBothStaticAndNonStaticMethods(metaClass)) { s << INDENT << "if (strcmp(cname, \"" << func->name() << "\") == 0)" << endl; |