PySide Bugzilla Closed for New Bugs

PySide is now a Qt Add-on and uses the Qt Project's JIRA Bug Tracker instead of this Bugzilla instance. This Bugzilla is left for reference purposes.

Bug 634 - It is not possible mock any Qt functions with PySide. Always raises TypeError...
: It is not possible mock any Qt functions with PySide. Always raises TypeError...
Status: CLOSED FIXED
Product: PySide
Classification: Unclassified
Component: PySide
: 1.0.0 beta3
: All All
: P3 normal
Assigned To: Marcelo Lira
:
:
:
  Show dependency treegraph
 
Reported: 2011-01-22 18:46 EET by Marcus Lindblom
Modified: 2011-05-26 17:03 EEST (History)
8 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marcus Lindblom 2011-01-22 18:46:14 EET
I'm using the following pattern to test my code with PyQt4 and Mock (see
http://pypi.python.org/pypi/mock/):

    def testDontShowInitialMessage(self):
        @apply
        @patch.object(QSystemTrayIcon, 'showMessage')
        def test(mock):
            self.build.set_status('success')
            self.assertFalse(mock.called, "shouldn't show message on startup")

This works well in PyQt, but with PySide I get this:

Traceback (most recent call last):
  File "D:\3rd\BuildBotIcon\my-buildboticon\python\src\bbicon\tests.py", line
95, in testSetIcon
    @patch.object(QSystemTrayIcon, 'showMessage')
  File
"D:\3rd\BuildBotIcon\my-buildboticon\python\mock-0.7.0b4-py2.6.egg\mock.py",
line 557, in patched
    arg = patching.__enter__()
  File
"D:\3rd\BuildBotIcon\my-buildboticon\python\mock-0.7.0b4-py2.6.egg\mock.py",
line 620, in __enter__
    setattr(self.target, self.attribute, new_attr)
TypeError: can't set attributes of built-in/extension type
'PySide.QtGui.QSystemTrayIcon'

The current state of PySide rather limiting the powers of Python for testing
things that interact with the external world in Qt. 

F.ex, I'm testing if QSound.play() is called, or if QNetworkAccessManager.get
is called with the right URLs, etc etc. I'm not sure how to add tests for these
if I can't mock certain functions. I could perhaps mock the entire class, but
that's not necessary at the moment...

Is there a global switch that can be used to allow this somehow, or some other
simple workaround?
Comment 1 Matti Airas 2011-01-28 08:56:08 EET
Thanks for the bug (and sorry for the slight delay before addressing it). The
issue sounds like it might be not exactly trivial to solve (although, what do I
know...). Maybe Hugo/Renato can chime in?

I'm prioritizing this P3 for now. If it doesn't seem to be feasible to fix this
before 1.0, then let's re-prioritize it to P4.
Comment 2 Hugo Parente Lima 2011-01-28 20:55:52 EET
It needs further investigation, anyway I agree with P3.
Comment 3 Matti Airas 2011-01-31 05:21:43 EET
OK, thanks. :-)
Comment 4 renato filho 2011-02-09 16:34:02 EET
could you provida a full test?
Comment 5 renato filho 2011-02-09 16:37:17 EET
could you provide a full test?
Comment 6 Hugo Parente Lima 2011-02-16 16:18:45 EET
ping!

Could you provide some executable code showing the problem?
Comment 7 Marcus Lindblom 2011-02-16 18:56:29 EET
Sorry for being silent. I've been slightly busy lately. 
(Thanks for persisting in bugging me about it too...)

Here's a small piece of code which emulates Mock:

from PySide import QtCore

class Mock(object):
    def __init__(self):
        self.called = False
        self.return_value = None

    def __call__(self, *args, **kwargs):
        self.called = True
        return self.return_value

mock = Mock()
setattr(QtCore.QCoreApplication, 'instance', mock)
QtCore.QCoreApplication.instance()
assert mock.called

This fails with:

TypeError: can't set attributes of built-in/extension type
'PySide.QtCore.QCoreApplication'

The same thing, with QtCore imported from PyQt4, works fine.

Maybe the sip-wrappers are more pythonic/dynamic than shiboken's wrapper
classes?
Comment 8 Hugo Parente Lima 2011-02-16 19:21:23 EET
Thanks for the fish! I can reproduce it here.
Comment 9 Marcelo Lira 2011-02-18 09:45:35 EET
It amounts to a Shiboken generated wrapper type not being able to have its
attributes set:

from sample import Point
setattr(Point, 'foo', 123)

We'll have to make the wrapper types heap type objects, which practically
speaking means to change a bit the way the binding deals with memory
allocation, deallocation and garbage collection.

Can do. :)
Comment 10 Hugo Parente Lima 2011-03-22 20:16:33 EET
Assigning the bug to nobody, as nobody is working on it right now.
Comment 11 Hugo Parente Lima 2011-03-25 20:45:21 EET
Lowering the priority to P4 as the huge effort needed to fix it would be better
applied to fix many other worth bugs.
Comment 12 Marcelo Lira 2011-05-17 23:53:48 EEST
Fixed in Shiboken/b56f78f3.
Comment 13 renato filho 2011-05-26 17:03:58 EEST
PySide release 1.0.3