Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable access weirdness in a QObject derivative

The code below is supposed to print the same thing three times. Why does it not?

from PySide.QtCore import QObject


class A(QObject):
    instance = 1

    @classmethod
    def test(cls):
        cls.instance  # Remove this line and it prints the right thing
        cls.instance = cls()
        print(cls.__dict__['instance'])
        print(cls.instance)
        print(type.__getattribute__(cls, 'instance'))

A.test()

Expected result:

<__main__.A object at 0x1310c20>
<__main__.A object at 0x1310c20>
<__main__.A object at 0x1310c20>

Actual result:

<__main__.A object at 0x2242878>
1
1

The metaclass behind QObject doesn't even override getattribute so how is it possible that I'm not getting the A instance back with "cls.instance"?

Even stranger is that not accessing the attribute (see the commented code line) before assigning it makes it work fine.

I can reproduce this as follows (with PySide 1.1.0):

  • Windows 7 64-bit, Python 2.7.1 32-bit: works
  • Windows 7 64-bit, Python 2.7.3 32-bit: works
  • Windows 7 64-bit, Python 3.2.3 32-bit: fails
  • Ubuntu 11.10 64-bit, Python 2.7.2+: works
  • Ubuntu 11.10 64-bit, Python 3.2.2: fails

Update: I managed to compile PySide 1.1.1 on Python 3.2.2 on Ubuntu, and it does not fix the problem.

like image 643
Alex Grönholm Avatar asked Apr 20 '12 13:04

Alex Grönholm


1 Answers

I can confirm this on Python 3.2.3 / PySide 1.1.0, Ubuntu 12.04. Works with PyQt4 on the same installation.

This is defenitely a bug in PySide. You should file a bug report, if you haven't already done so.

If I only change the example a little, the example even segfaults:

from PySide.QtCore import *

class A(QObject):
    instance = []

    @classmethod
    def test(cls):
        print(cls.instance)
        cls.instance = cls()
        print(cls.__dict__['instance'])
        print("still ok")
        print(cls.instance)
        print("you won't see me")
        print(type.__getattribute__(cls, 'instance'))

A.test()
like image 170
mata Avatar answered Oct 05 '22 02:10

mata