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 931 - isinstance() fails with Signal instances
: isinstance() fails with Signal instances
Status: CLOSED FIXED
Product: PySide
Classification: Unclassified
Component: QtCore
: HEAD
: PC Linux
: P3 normal
Assigned To: renato filho
:
:
:
  Show dependency treegraph
 
Reported: 2011-07-15 16:22 EEST by Hereldar
Modified: 2011-08-23 00:35 EEST (History)
8 users (show)

See Also:


Attachments
Test for signals (340 bytes, text/x-python)
2011-07-15 16:22 EEST, Hereldar
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Hereldar 2011-07-15 16:22:32 EEST
Created attachment 375 [details]
Test for signals

When you try to check if the signal of an object instance is a instance of
PySide.QtCore.Signal, the `isinstance()` function returns False.

Steps to Reproduce:
-------------------

    from PySide.QtCore import QObject, Signal
    o = QObject()

    QObject.destroyed
    type(QObject.destroyed)
    isinstance(QObject.destroyed, Signal)
    type(QObject.destroyed) == Signal

    o.destroyed
    type(o.destroyed)
    isinstance(o.destroyed, Signal)
    type(o.destroyed) == Signal

Actual Results:
---------------

    destroyed()
    <type 'PySide.QtCore.Signal'>
    True
    True

    <PySide.QtCore.Signal object at 0xe88138>
    <type 'PySide.QtCore.Signal'>
    False
    False

Expected Results:
-----------------

    destroyed()
    <type 'PySide.QtCore.Signal'>
    True
    True

    <PySide.QtCore.Signal object at 0xe88138>
    <type 'PySide.QtCore.Signal'>
    True
    True

Platform:
---------

    Distribution: Kubuntu 11.04
    KDE S.C.:     4.6.2
    Qt:           4.7.2
    PySide:       1.0.3
    PySide Tools: 0.2.9
Comment 1 renato filho 2011-07-19 16:31:42 EEST
Thanks for the report.

The problem here is the instance type was printed wrong, the correct type for
instance signals is "SignalInstance", this is necessary due some "magical"
stuff which is need to have Qt signal working on python.

I have fixed that, and created a new unit test base on this one, you can check
that on : https://github.com/PySide/PySide/blob/master/tests/QtCore/bug_931.py

the fix can be found on the pyside commit:

commit 58e3040802eedae58e9dd6443c2a59ebaa97f888
Author: Renato Filho <renato.filho@openbossa.org>
Date:   Mon Jul 18 15:18:06 2011 -0300
Comment 2 Hereldar 2011-07-20 17:55:02 EEST
Is not more elegant to override the `__instancecheck__()` method?

For example:

    def __instancecheck__(self, instance):
        return (type(instance) == Signal)

Or maybe more complete:

    def __instancecheck__(cls, instance):
        mro = getattr(instance, '__mro__', None)
        if mro:
            return (Signal in mro)
        else:
            return (type(instance) == Signal)

Overriding this method, is easy to check whether a instance attribute is a
signal, just type the following:

    isinstance(o.destroyed, Signal)

Instead:

    type(o.destroyed).__name__ == "SignalInstance"

I think this way is more elegant and pythonic, you can implement it?
Comment 3 Hereldar 2011-07-20 18:03:03 EEST
Sorry, my `__instancecheck__()` implementations are wrong. The following is
better:

class SignalType(type):

    def __instancecheck__(cls, instance):
        mro = getattr(instance, '__mro__', None)
        if mro:
            return ((Signal in mro) or (SignalInstance in mro))
        else:
            return (type(instance) in (Signal, SignalInstance))

class Signal:
    __metaclass__ = SignalType
Comment 4 renato filho 2011-07-20 21:04:02 EEST
sure this is a best idea i will check how to implement this on c python,
thanks.
Comment 5 renato filho 2011-07-26 16:08:27 EEST
update in pyside commit:

commit 017fbee08f78a0dcab8c26b9da23f889752dce70
Author: Renato Filho <renato.filho@openbossa.org>
Date:   Mon Jul 25 18:37:22 2011 -0300
Comment 6 renato filho 2011-08-23 00:35:35 EEST
Released on PySide 1.0.6