summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Parente Lima <hugo.pl@gmail.com>2010-09-16 19:12:33 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2010-09-17 10:29:00 -0300
commit42a3b42f8a00e94dd10e786210739fee7878cf51 (patch)
tree99979228e8fcdb3dfae6b4c70d36d5a35e300650
parent4914a426267dd6f6cf852445f071650b5c0f7971 (diff)
downloadshiboken-42a3b42f8a00e94dd10e786210739fee7878cf51.tar.gz
shiboken-42a3b42f8a00e94dd10e786210739fee7878cf51.tar.xz
shiboken-42a3b42f8a00e94dd10e786210739fee7878cf51.zip
Fix bug#339 - "RuntimeError when accessing mousepress event object"
Reviewer: Luciano Wolf <luciano.wolf@openbossa.org> Lauro Moura <lauro.filho@openbossa.org>
-rw-r--r--cppgenerator.cpp35
-rw-r--r--tests/libsample/objecttype.cpp6
-rw-r--r--tests/libsample/objecttype.h4
-rw-r--r--tests/samplebinding/ownership_invalidate_after_use_test.py21
-rw-r--r--tests/samplebinding/typesystem_sample.xml3
5 files changed, 59 insertions, 10 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp
index 89efd3b3..3e95f0ab 100644
--- a/cppgenerator.cpp
+++ b/cppgenerator.cpp
@@ -546,6 +546,16 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, const AbstractMetaFu
s << argConversions.join(",\n") << endl;
s << INDENT << "));" << endl;
}
+
+ bool invalidateReturn = false;
+ foreach (FunctionModification funcMod, func->modifications()) {
+ foreach (ArgumentModification argMod, funcMod.argument_mods) {
+ if (argMod.resetAfterUse)
+ s << INDENT << "bool invalidadeArg" << argMod.index << " = PyTuple_GET_ITEM(pyargs, " << argMod.index - 1 << ")->ob_refcnt == 1;" << endl;
+ else if (argMod.index == 0 && argMod.ownerships[TypeSystem::TargetLangCode] == TypeSystem::CppOwnership)
+ invalidateReturn = true;
+ }
+ }
s << endl;
CodeSnipList snips;
@@ -564,6 +574,9 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, const AbstractMetaFu
s << INDENT;
s << "Shiboken::AutoDecRef " PYTHON_RETURN_VAR "(PyObject_Call(py_override, pyargs, NULL));" << endl;
if (type) {
+ if (invalidateReturn)
+ s << INDENT << "bool invalidadeArg0 = " PYTHON_RETURN_VAR "->ob_refcnt == 1;" << endl;
+
s << INDENT << "// An error happened in python code!" << endl;
s << INDENT << "if (" PYTHON_RETURN_VAR ".isNull()) {" << endl;
{
@@ -651,15 +664,19 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, const AbstractMetaFu
}
}
- bool transferReturnToCpp = false;
- foreach (FunctionModification func_mod, func->modifications()) {
- foreach (ArgumentModification arg_mod, func_mod.argument_mods) {
- if (arg_mod.resetAfterUse) {
+ if (invalidateReturn) {
+ s << INDENT << "if (invalidadeArg0)" << endl;
+ Indentation indentation(INDENT);
+ s << INDENT << "BindingManager::instance().invalidateWrapper(" << PYTHON_RETURN_VAR ".object());" << endl;
+ }
+
+ foreach (FunctionModification funcMod, func->modifications()) {
+ foreach (ArgumentModification argMod, funcMod.argument_mods) {
+ if (argMod.resetAfterUse) {
+ s << INDENT << "if (invalidadeArg" << argMod.index << ")" << endl;
+ Indentation indentation(INDENT);
s << INDENT << "BindingManager::instance().invalidateWrapper(PyTuple_GET_ITEM(pyargs, ";
- s << (arg_mod.index - 1) << "));" << endl;
- } else if ((arg_mod.index == 0) && (arg_mod.ownerships[TypeSystem::TargetLangCode] == TypeSystem::CppOwnership)) {
- s << INDENT << "BindingManager::instance().invalidateWrapper(" << PYTHON_RETURN_VAR ".object());" << endl;
- transferReturnToCpp = true;
+ s << (argMod.index - 1) << "));" << endl;
}
}
}
@@ -671,7 +688,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, const AbstractMetaFu
}
if (type) {
- if (!transferReturnToCpp && (func->type()->isObject() || func->type()->isValuePointer()) ) {
+ if (!invalidateReturn && (func->type()->isObject() || func->type()->isValuePointer()) ) {
s << INDENT << "if (" << PYTHON_RETURN_VAR << "->ob_refcnt < 2) {" << endl;
{
Indentation indent(INDENT);
diff --git a/tests/libsample/objecttype.cpp b/tests/libsample/objecttype.cpp
index ea3c78e7..c1407d23 100644
--- a/tests/libsample/objecttype.cpp
+++ b/tests/libsample/objecttype.cpp
@@ -167,6 +167,12 @@ ObjectType::processEvent(ObjectTypeList objects, Event *event)
}
void
+ObjectType::callInvalidateEvent(Event* event)
+{
+ invalidateEvent(event);
+}
+
+void
ObjectType::setLayout(ObjectTypeLayout* l)
{
if (!l) {
diff --git a/tests/libsample/objecttype.h b/tests/libsample/objecttype.h
index c3bd8c62..b09b402e 100644
--- a/tests/libsample/objecttype.h
+++ b/tests/libsample/objecttype.h
@@ -78,6 +78,9 @@ public:
virtual bool event(Event* event);
static int processEvent(ObjectTypeList objects, Event *event);
+ void callInvalidateEvent(Event* event);
+ virtual void invalidateEvent(Event* event) {}
+
// This nonsense method emulate QWidget.setLayout method
// All layout objects will became children of this object.
void setLayout(ObjectTypeLayout* layout);
@@ -99,7 +102,6 @@ public:
void setObject(const Null&);
int callId() const;
-
private:
ObjectType(const ObjectType&);
ObjectType& operator=(const ObjectType&);
diff --git a/tests/samplebinding/ownership_invalidate_after_use_test.py b/tests/samplebinding/ownership_invalidate_after_use_test.py
index 80f252d5..5a03fc47 100644
--- a/tests/samplebinding/ownership_invalidate_after_use_test.py
+++ b/tests/samplebinding/ownership_invalidate_after_use_test.py
@@ -42,6 +42,22 @@ class ExtObjectType(ObjectType):
self.type_of_last_event = event.eventType()
return True
+class MyObjectType (ObjectType):
+ def __init__(self):
+ super(MyObjectType, self).__init__()
+ self.fail = False
+
+ def event(self, ev):
+ self.callInvalidateEvent(ev)
+ try:
+ ev.eventType()
+ except:
+ self.fail = True
+ raise
+ return True
+
+ def invalidateEvent(self, ev):
+ pass
class OwnershipInvalidateAfterUseTest(unittest.TestCase):
'''Ownership tests for cases of invalidation of Python wrapper after use.'''
@@ -61,6 +77,11 @@ class OwnershipInvalidateAfterUseTest(unittest.TestCase):
self.assertEqual(eot.type_of_last_event, Event.ANY_EVENT)
self.assertRaises(RuntimeError, ot.event, eot.last_event)
+ def testit(self):
+ obj = MyObjectType()
+ obj.causeEvent(Event.BASIC_EVENT)
+ self.assertFalse(obj.fail)
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml
index de262c9e..40b70ab4 100644
--- a/tests/samplebinding/typesystem_sample.xml
+++ b/tests/samplebinding/typesystem_sample.xml
@@ -141,6 +141,9 @@
<modify-function signature="event(Event*)">
<modify-argument index="1" invalidate-after-use="yes"/>
</modify-function>
+ <modify-function signature="invalidateEvent(Event*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
<modify-function signature="create()">
<modify-argument index="return">
<define-ownership owner="target"/>