aboutsummaryrefslogtreecommitdiffstats
path: root/cppgenerator.cpp
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2010-01-21 13:33:26 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2010-01-21 13:51:02 -0300
commit62bd3820c222cfb6af57c2ff4b23b8b819743bbf (patch)
tree26325d0b6ada5d79334f4ede59fc7432e9cfd482 /cppgenerator.cpp
parentcd12b72f152f970a86cac12f62a0f9d1edd3f6d8 (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.cpp13
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;