Hi Sylvain

* First up, I should point out that I think pylint is a great tool ... I use it in combination with flymake in emacs to give me realtime error checking which is very helpful. * I have already posted the suggested fix to the PyQt mailing list, along with the note of a bus error
* On the bus error I have more information but will post that separately
* As request, attached is an example simple PyQt app. Here is what the unpatched pylint output appears as

$ pylint-2.6 -f parseable -r n --disable-msg-cat=C,R testcase.py
testcase.py:9: [E0611] No name 'QtGui' in module 'PyQt4'
testcase.py:9: [E0611] No name 'QtCore' in module 'PyQt4'
testcase.py:11: [W0232, TextWidget] Class has no __init__ method
testcase.py:11: [E1101, TextWidget] Module 'PyQt4.QtGui' has no 'QLineEdit' member testcase.py:14: [E1101, MainWindow] Module 'PyQt4.QtGui' has no 'QDialog' member testcase.py:16: [E1101, MainWindow.__init__] Module 'PyQt4.QtGui' has no 'QDialog' member testcase.py:21: [E1101, MainWindow.init] Module 'PyQt4.QtGui' has no 'QGroupBox' member testcase.py:22: [E1101, MainWindow.init] Module 'PyQt4.QtGui' has no 'QRadioButton' member testcase.py:23: [E1101, MainWindow.init] Module 'PyQt4.QtGui' has no 'QRadioButton' member testcase.py:24: [E1101, MainWindow.init] Module 'PyQt4.QtGui' has no 'QRadioButton' member testcase.py:27: [E1101, MainWindow.init] Module 'PyQt4.QtGui' has no 'QVBoxLayout' member testcase.py:35: [E1101, MainWindow.init] Module 'PyQt4.QtGui' has no 'QVBoxLayout' member testcase.py:38: [E1101, MainWindow.init] Instance of 'TextWidget' has no 'setEnabled' member testcase.py:42: [E1101, MainWindow.init] Module 'PyQt4.QtGui' has no 'QPushButton' member testcase.py:45: [E1101, MainWindow.init] Instance of 'MainWindow' has no 'setLayout' member testcase.py:48: [E1101, MainWindow.quit] Instance of 'MainWindow' has no 'done' member
testcase.py:47: [W0613, MainWindow.quit] Unused argument 'args'
testcase.py:47: [W0613, MainWindow.quit] Unused argument 'kw'
testcase.py:51: [E1101] Module 'PyQt4.QtGui' has no 'QApplication' member
testcase.py:53: [E1101] Instance of 'MainWindow' has no 'exec_' member
testcase.py:9: [W0611] Unused import QtCore

Its mostly full of false positives. A largish module using Qt gets swamped with output, and in my case it means emacs highlights every other line as containing a problem :-)

With the patch it appears as

$ pylint-2.6 -f parseable -r n --disable-msg-cat=C,R testcase.py
testcase.py:47: [W0613, MainWindow.quit] Unused argument 'args'
testcase.py:47: [W0613, MainWindow.quit] Unused argument 'kw'
testcase.py:9: [W0611] Unused import QtCore

Pleased to (hopefully) help.
derek.

import sys
from PyQt4 import QtCore, QtGui

class TextWidget(QtGui.QLineEdit):
    pass

class MainWindow(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.init()

    def init(self):
        # create a group of radio buttons
        self.groupBox = QtGui.QGroupBox("Exclusive Radio Buttons")
        self.radio1 = QtGui.QRadioButton("&Radio button 1")
        self.radio2 = QtGui.QRadioButton("R&adio button 2")
        self.radio3 = QtGui.QRadioButton("Ra&dio button 3")
        self.radio1.setChecked(True)
        
        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(self.radio1)
        vbox.addWidget(self.radio2)
        vbox.addWidget(self.radio3)
        vbox.addStretch(1)
        self.groupBox.setLayout(vbox)

        # add to the dialog along with a disabled text edit
        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(self.groupBox)
        txtEditor = TextWidget()
        txtEditor.setEnabled(False)
        vbox.addWidget(txtEditor)

        # add a button
        self.btnQuit = QtGui.QPushButton("Quit")
        self.btnQuit.clicked.connect(self.quit)
        vbox.addWidget(self.btnQuit)
        self.setLayout(vbox)

    def quit(self, *args, **kw):
        self.done(1)
                        
if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    mainwindow = MainWindow()
    mainwindow.exec_()
    



On 29/07/2009, at 12:37 AM, Sylvain Thénault wrote:

On 27 juillet 18:53, Derek Harland wrote:
Hello,

Hi,

The more recent releases of PyQt4 seem to break pylint ... pylint
will emit the following errors
(i) unable to find submodules of PyQt4
   main.py:3: [E0611] No name 'QtCore' in module 'PyQt4'
   main.py:4: [E0611] No name 'QtGui' in module 'PyQt4'
(ii) as a result, all use of classes from eg QtGui, or inheritors
from them, spark lots of errors
   main.py:11: [E1101, MyValidator] Module 'PyQt4.QtGui2' has no
'QValidator' member
   main.py:33: [E1101, DaycountWidget.__init__] Instance of
'DaycountWidget' has no 'setEditable' member

I've tracked down the problem I believe ...
* PyQt4.QtCore's namespace has instances of a c-module defined type
called pyqtSignal
* pylint believes these are methoddescriptors
[inspect.ismethoddescriptor(.) -> returns true ]
* However, they do not have __name__ or __doc__ defined, which
logilab/astng/raw_building.py:object_build_methoddescriptor expects

even if having a fix for this on the pylint/astng side, this is probably
worth mentionning to the pyqt team.

As a result pylint basically refuses to load the Qt modules and this
causes all subsequent errors.

How to fix?  The following patch will avoid the error

which error ? False positives as mentioned above ?

--- logilab/astng/builder.py.orig       2009-07-27 18:43:54.000000000 +1200
+++ logilab/astng/builder.py    2009-07-27 18:44:57.000000000 +1200
@@ -194,8 +194,12 @@
                    # recursion
                    self.object_build(class_node, member)
            elif ismethoddescriptor(member):
-                assert isinstance(member, object)
-                object_build_methoddescriptor(node, member)
+                # avoid objects without __name__, they're not what
they seem ...
+                # (eg PyQt4.QtCore.pyqtSignal instances)
+                if hasattr(member, "__name__") and hasattr(member,
"__doc__"):
+                    assert isinstance(member, object)
+                    object_build_methoddescriptor(node, member)
+                else: attach_dummy_node(node, name, member)
            elif isdatadescriptor(member):
                assert isinstance(member, object)
                object_build_datadescriptor(node, member, name)

could you provide which version of pyqt are you using and a minimal
sample script to reproduce the pb ?

imo (but I've not at all tracked down this as you have), a better fix
consits in giving to object_build_* methods the name of the member
(eg the loop variable) if member.__name__ is not set.

After this patch pylint seems to work as expected.  However users
must ensure their code imports PyQt4.QtGui before PyQt4.QtCore or a
bus error will occur when running pylint. (I have no idea why ...
within a python program itself it doesn't mind the order in which
they are imported).

Weird

Hope this is useful, I know that there are a few posts to newsgroups
wondering how to fix this problem

Bug reports, moreover those including results of digging the code, are
really valuable! Thank you for this one.

--
Sylvain Thénault                               LOGILAB, Paris (France)
Formations Python, Debian, Méth. Agiles: http://www.logilab.fr/formations
Développement logiciel sur mesure: http://www.logilab.fr/ services
CubicWeb, the semantic web framework:    http://www.cubicweb.org


_______________________________________________
Python-Projects mailing list
Python-Projects@lists.logilab.org
http://lists.logilab.org/mailman/listinfo/python-projects

Reply via email to