Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Test under xvfb fail after upgrade to qt 5.15.0 for python



  • I have my Python application which use qt for GUI. I use qtpy as wrapper so my application can use PyQt5 or PySide2 as frontend. And for both backends for version 5.15.0 when tests are executed on CI server it fails with qt widgets test with sigabort (Test for Windows and MacOS pass) .

    Test pass on local machine.

    What can change in qt that it causes such error? It happens on Github Actions and Azure Pipelines on ubuntu image.

    Link to project:

    https://github.com/4DNucleome/PartSeg/tree/develop

    Sample fail: https://github.com/4DNucleome/PartSeg/runs/726680128?check_suite_focus=true


  • Banned

    Okay that is a lot of code to have to look at but what I am not understanding is your statement that you use PyQt5 or PySide2 as your backend as these are frontend pieces and the backend and middletier ought to be pretty much straight python?

    So can you explain this a bit more clearly as to how PyQt5 and/or PySide2 are being used as the backend but not the frontend?



  • My mistake. I use it as frontend, not backend. This fail on test custom widgets

    I try to create smaller example.




  • Banned

    Here is a MUC showing you how to implement the importing of a custom file that contains a custom object note if you have sub-folders that contain files each of these sub-folders should contain one of these __init__.py files as outlined below.

    # Create Folder Called Test
    # Create a text file in Test rename it:  __init__.py
    # Create a text file in Test rename it:  MyPushButton.py
    # Create a text file in Text rename it:  Main.py
    
    
    # Noting goes in __init__.py this is simply used by python to facilitate importing
    
    
    # Place this in your MyPushButton.py file
    
    from PyQt5.QtWidgets import QPushButton
    
    class BigButton(QPushButton):
        def __init__(self, Text):
            QPushButton.__init__(self)
    
            self.setFixedHeight(100)
            self.setFixedWidth(100)
            
            self.setText(Text)
    
    
    # Place this in your Main.py file
    
    from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout
    
    from MyPushButton import BigButton
    
    class MainDisply(QWidget):
        def __init__(self):
            QWidget.__init__(self)
            Top=300; Left=700; Width=300; Hight=100
            self.setGeometry(Left, Top, Width, Hight)
            self.setWindowTitle('Custom Tester')
            
            self.btnPush = BigButton('Push')
            self.btnPush.clicked.connect(self.Pushed)
            
            HBox = QHBoxLayout()
            HBox.addWidget(self.btnPush)
            HBox.addStretch(1)
            
            self.setLayout(HBox)
            
        def Pushed(self):
            print('Hey You Pushed Me!')
    
    if __name__ == "__main__":
        MainEventHandler = QApplication([])
    
        MainApplication = MainDisply()
        MainApplication.show()
        
        MainEventHandler.exec()
    


  • How this respond on my question about changes in Qt 5.15?. My code works with Qt 5.14. It fail on QApplication constructor call.

    here is log for both bind (PyQt5 and PySide2) for Qt in version 5.14 and 5.15.

    https://github.com/Czaki/sample_qt_error/runs/727854634?check_suite_focus=true

    For Qt 5.14 all test pass. For Qt 5.15 it fail on QApplication creation.

    On My PC it pass for both version. On server without X (but with Xvfb) it fails.


  • Banned

    Okay @Czaki it was not clear in your first post that you were having a versioning issue but I would guess if you implemented things as I have shown the issue would go away that it fails in a later version versus an earlier version means perhaps they fixed the bug that allowed that to work that way

    So did you try the example I supplied to see whether it works for you or not in whatever version of Qt you are using?

    Also if you can denote exactly where within your source code you are making the Import and there the file you are Importing resides I can look at that too and let you know if there are any basic structural issues within your code -- I import numerous custom objects in my project without any issues at all



  • @Czaki I am only just now arriving on this thread, and when I look at the GitHub actions now (for PartSeg) I see a lot of "green" (successful) jobs. Did you fix the problem?

    Was this your fix? https://github.com/4DNucleome/PartSeg/commit/d7771b213007e9e44ef4f1e159c5258cbb2dbadf

    (I don't use python, but I, too, have run into weird issues with the Azure/Microsoft configuration of the GitHub Ubuntu runner environment.)



  • @KH-219Design I look like it point to wrong build, but I'm not sure how it can change. Current build are green because I block 5.15.0 release
    Maybe this link will work: https://github.com/4DNucleome/PartSeg/runs/726685612?check_suite_focus=true

    In this repository I reproduce this error https://github.com/Czaki/sample_qt_error
    It shows that this is problem with QApplication in this line

            _qapp_instance = qt_api.QApplication(qapp_args)
    

    where qapp_args is empty list

    @Denni-0 This code is test runner (pytest). Main application is run in proper way https://github.com/4DNucleome/PartSeg/blob/develop/package/PartSeg/launcher_main.py

    And I can run code on linux with running x11 server. Problem happens on server with x emulation with xvfb. But CI provider does not provide server with running x11, so xvfb and Xdummy are only options to test gui components. But I do not know how to setup Xdummy.

    But also test runner create QApplication object before test start.


  • Banned

    Wow I looked at that custom Main program you have and that is rather ugly (note I do not say that without also extending an offer to help you with that clean up if you want). It would take me quite a while to dissect it and clean it up in order to sort out what you are doing and where any potential issues might reside. So first I would suggest that you consider cleaning it up and making it a bit more clear and concise but that aside let me supply you with this bit of code to maybe help you with your issue...

    Note being dependent on another tool means you have just one more layer that can cause issues so maybe instead of using qtpy you might want to just use the following more explicit means to handle your "dual" boot

    try:
        from PyQt5.QtCore    import pyqtSignal, pyqtSlot
        from PyQt5.QtGui     import QFontDatabase
        from PyQt5.QtWidgets import QApplication
    
    except ImportError:
        from PySide2.QtCore    import Signal as pyqtSignal, Slot as pyqtSlot
        from PySide2.QtGui     import QFontDatabase
        from PySide2.QtWidgets import QApplication
    # -------------------------
    import argparse
    .... everything else
    

    The above simply makes sure you are using the same modules that are currently being used in Qt5 as the only current differences between PyQt5 and PySide2 are the Signal and Slot references and that PySide2 still uses the Qt4 version to launch your MainEventThread = QApplication([]) as follows: sys.exit(MainEventHandler.exec_()) where PyQt5 while it currently still supports the Qt4 call (for now) has upgraded to the Qt5 version to launch your MainEventThread as follows: MainEventHandler.exec() Oh and that PySide2 does not currently support all of Qt5 but this will help you know that right up front when you try to run the program as it will fail on import for PySide2.

    Further by simply adding something in the PyQt import that automatically fails you can force it to do a PySide2 implementation

    Also when importing other things in conjunction with Qt you should always declare the Qt stuff first as there is a known issue where if you do not then you sometimes get incorrect associations and this can cause all kinds of strange runtime errors and simply by declaring the Qt stuff first forces all subsequent imports to be associate with that specific Qt version



  • In other place I found that my problems comes from this change:
    https://codereview.qt-project.org/c/qt/qtbase/+/253905

    so I need to install xcb libraries with:

    sudo apt-get install -y libdbus-1-3 libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0
    

    (not sure if all needed)

    I use simple file:

    from qtpy.QtWidgets import QApplication, QMainWindow
    
    app = QApplication([])
    window = QMainWindow()
    window.show()
    app.exec_()
    

    with defined QT_DEBUG_PLUGINS=1 in environment to get information which libraries are missing

    @Denni-0 This code starts one of 3 applications base on command line arguments. and contains function _test_imports which test if all libraries are properly bundled when freezing with pyinstaller.

    I'm not sure If you can simplify it. qtpy is simple wrapper which detect qt libraries and allow to control it if have multiple installed.

    Base on PEP-8 all imports of python standard library should be before import of third parts library.


  • Banned

    Well keep in mind two things first PEP-8 is not an actually good set of standards as they contain of lot of nonsensical items that have nothing to do with creating quality code and have more to do with restricting someones style to fit someone else's view of what should and should not be -- these kind of standards are rarely ever good standards as basic standards should leave room for style flexibility while covering all those things that are actually good coding practices which those standards also do not fully cover

    Next Python-Qt is not pure Python code which is what PEP-8 only applies to and this is just an example of why they are not good standards to follow and/or should be taken with a major grain of salt and only use those things that are actually good generic programming practices as opposed to some self-opinionated preferences. Now if you feel a need to follow PEP-8 as if it were created by some gods then go ahead just know that within Python-Qt there is a statement that if you do not import your Python-Qt files first that (especially in multi-version settings) you may end up with incorrect file associations and all the issues that go right along with that.

    Oh as a secondary note I had someone once tell me that those standards are a must to use by anyone and everyone using python and I simply said not if they are not required to do so by whomever is signing the paycheck and again frankly if some company asked me about those standards I would give them my honest opinion which is not to use them as is -- not saying all of it is bad -- but it truly is not something I would adhere to by any stretch of the imagination unless the guy signing my paycheck said I had to which they often do not.

    Further if you step into a house that did not use PEP-8 for there coding standards (as they did not consult the gods that forbade this) then you would do a much better job if you figure out their standards (if any) and adhere to these so all the code remains having the same look and feel. BTW you might be surprised to find that this happens (not using PEP-8) more often than not because other experienced software engineers feel the same way I do in that those are not good standards due to their heavy incomplete bias

    On a slightly different note -- I think there actually would be a much cleaner and more concise manner to setup a primary file whose job is to determine what set of code to call based on various criterion and then encapsulate the various functionalities as completely autonomous units. Also if the purpose of all the code is to determine if you have missing code libraries and to determine which program to actually launch then -- I am definitely sure I can help you design a much cleaner process than you currently have and do not think it would require a lot of re-coding just some adjustments and clean ups an encapsulating



  • @Denni-0 Could you point any part of standard python library which may breaks Qt?

    I know that there are some third part library (like matplotlib, vispy) which may break when using Qt with wrong import order. But I do not see any option when part of python standard library may break Qt.



  • @Czaki said in Test under xvfb fail after upgrade to qt 5.15.0 for python:

    @Denni-0 Could you point any part of standard python library which may breaks Qt?

    Excellent question.


  • Banned

    So what you are actually asking is have I dug so deeply into Python-Qt that I have discovered the actual bug that creates the phenomena that Qt denotes is a known issue within their documentation. The answer to that not-so-excellent question is no -- nor do I plan to at this time and perhaps never. Basically dealing with that low-level of coding is not my favorite part of programming I much prefer to solve business related puzzles.

    Now of course if you would care to dig that deeply into Qt to understand why that occurs and specifically with what it occurs with, as THEY (Qt) have describe it does. Then by all means do so, and share your findings. I am personally fine with adhering to their (Qt's) advice of declaring the Qt stuff first (I guess they do not adhere to PEP-8 either imagine that) followed by the python stuff followed by anything else.

    However let me juxtapose a question -- can you point out why PEP-8 denotes that ALL non-direct-python libraries MUST come after the python libraries. Is this sound advice or simply a white-wash with no actual solid basis. I am not saying that it applies to just some libraries because that is not their claim (or at least as you have stated it). There claim is ALL other libraries so the reason for it MUST apply to ALL such libraries and not to just some. Or are you like me, simply taking their advice on the surface and running with it. Personally considering all the other junk in PEP-8 I will always take whatever they say with major grain of salt as to me their so-called standards speak of incompetency and if you have that on some level within something that important you generally get it throughout. Again I am not saying all of what they outline is bad, as they may have pulled some of their guidelines from actual quality standards but I am saying there is enough garbage in their to make them only a mild suggestion and that everything and I mean EVERYTHING they claim ought to be investigated with a fine tooth comb prior to adopting it for ones own standards for coding. Is it truly the issue they claim it to be or is it just some of their incompetent (note denoting something as standard guidelines that is simply a style preference and has no basis for quality coding is what I refer to as part of their incompetency) garbage that they chose to toss on the heap.

    As for the Qt quandary investigate it yourself as I always tell my students, do not take what anyone else says as gospel, learn about it yourself and that goes double for anything I teach. I am not omnipotent and I can make mistakes but unless someone proves me wrong I stand on what I have learned to be true. So far no one has stepped forward to actually prove me wrong with actual facts, they would rather just say hey I do not agree with you so you must be wrong - so prove to me you are right. To which I reply prove that I am wrong or simply continue to choose to do it the wrong way that is YOUR choice. As for me, my stance was based on actual personal extensive research into the why's and how's and I am now just sharing the results. The Truth is Out There -- YOU just sometimes have to wade through a lot of garbage to find it.

    So @Czaki and @JonB you make your own decision based on what you have found to be True assuming you bother to do so. I would challenge you both not to be mere lemmings and blind followers of PEP-8 become instead informed and educated programmers in the know. Find the arguments for both sides, dig deep into the why's and how's before you choose to adopt something as your own standard for doing something correctly.

    Oh and these kind of issues tend to be compiler issues rather than actually bugs in language implementation so perhaps if you want to better understand this you need to better understand the compilers that are being used.

    As I final note I will always speak out harshly against anything that is being toted as the Truth that is choke full of Lies and that is how I see PEP-8. It might contain truths but it also contains lies as such it is not to be trusted by any stretch of the imagination and definitely ought not to be followed so blindly as seems to be the case by some



  • @Czaki I'm laughing (at myself!) as I write this, because I'm about to say almost the same thing I said yesterday.

    I'm not crazy! And I have read the latest messages.

    Seeing that this was this still unsolved this morning, and given that I still have a lot of personal curiosity about things that go wrong in GitHub CI specifically, I came here thinking "well the post did link to a minimum repro of the issue."

    So I decided I would dig in and fork the "Czaki/sample_qt_error" repository and see if I could diagnose it.

    But when I go to https://github.com/Czaki/sample_qt_error/actions/runs/121851186 it looks like there is a "green" (successful) job. So was this the fix? https://github.com/Czaki/sample_qt_error/commit/758bc7b3420330529cc1e713f511d61ae665d62b

    If so, congrats on narrowing it down, and thank you for sharing this with the forum. (And sorry we did not provide the answer!)

    If I am once again misinterpreting a "green" job, then today I will actually collaborate if this is still an ongoing problem.



  • In this case, there seems to be ample evidence that simply upgrading to Py Qt 5.15.0 is the change that broke the CI jobs.

    However, I thought I should share one "trick" I have been using on GitHub CI, which has helped me identify cases where changes made by GitHub have been the sudden cause of broken CI jobs.

    In my CI job script: https://github.com/219-design/qt-qml-project-template-with-ci/blob/1b981d218c7/run_all_tests.sh

    I print into the CI log the following information before I start my compilation and test commands:

      # Try various ways to print OS version info.
      # This lets us keep a record of this in our CI logs,
      # in case the CI docker images change.
      uname -a       || true
      lsb_release -a || true
      gcc --version  || true  # oddly, gcc often prints great OS information
      cat /etc/issue || true
    
      # What environment variables did the C.I. system set? Print them:
      env
    

    If a job suddenly fails one day, then I download the GitHub logs from the most recent SUCCESS and from the failure jobs, and I do a diff of the log. This can reveal changes in the GitHub runner environment.

    GitHub also prints similar info at the top of each job's log. Their built-in descriptive logging looks like:

    2020-06-02T01:29:00.2554826Z ##[section]Finishing: Request a runner to run this job
    2020-06-02T01:29:04.9619878Z Current runner version: '2.263.0'
    2020-06-02T01:29:04.9642595Z ##[group]Operating System
    2020-06-02T01:29:04.9643252Z Ubuntu
    2020-06-02T01:29:04.9643359Z 18.04.4
    2020-06-02T01:29:04.9643510Z LTS
    2020-06-02T01:29:04.9643685Z ##[endgroup]
    2020-06-02T01:29:04.9643850Z ##[group]Virtual Environment
    2020-06-02T01:29:04.9643978Z Environment: ubuntu-18.04
    2020-06-02T01:29:04.9644127Z Version: 20200525.2
    2020-06-02T01:29:04.9644336Z Included Software: https://github.com/actions/virtual-environments/blob/ubuntu18/20200525.2/images/linux/Ubuntu1804-README.md
    

    So when jobs fail mysteriously, I have tended to "diff the logs" specifically to check that no GitHub changes happened.

    Normally I adhere to "the first rule of bug hunting is assume the bug is your own." But GitHub Actions as a feature is in its infancy still, and they have made many rapid changes and I have seen it break several times. (see: https://github.com/219-design/qt-qml-project-template-with-ci/commit/7eda342bb693738d6c9d912619a34cacb498b7c1 and https://github.com/219-design/qt-qml-project-template-with-ci/pull/12)

    I offer this all as "future advice". Again, I see that the change to Qt 5.15.0 is sufficient to explain the broken jobs for @Czaki .


  • Banned

    Well okay so the issue has to do with the from Qt 5.14.0 to Qt 5.15.0 but this is only a minor adjustment which typical does not break major things and as such my suspicions lie with the qtpy layer as being where the issue actually resides -- aka the change in 5.14 to 5.15 has not been handled within qtpy and it is qtpy that is breaking due to this change that does not actually break Qt in any way.

    However to prove this the code would have to be compiled without using qtpy and using perhaps that suggestion I made. If it were I and I was developing this project -- I would have 2 branches one that uses qtpy and one that does not -- and when compiling and running I would always do both in order to determine if qtpy (that extra layer that got added that I have no control of) is the issue or not.

    Again as always adding extra layers that one has no control over that can effect your code so dramatically is rather dangerous which is why I would stray away from it and perhaps see if there were a better methodology that would do the same thing and reduce the complexity level K.I.S.S. (Keep It Simple and Smart) is always the best rule of thumb in programming

    Nice insights btw @KH-219Design those I am sure can prove helpful to anyone using Github



  • @KH-219Design I fix it and describe here: https://forum.qt.io/post/598392 (few post above).

    And I was sure that problem is in changes in Qt, because exactly same code works for QT 5.14.2 and fail for Qt 5.15.0 at same time, at same machine. (one Github Actions job)

    @Denni-0 said in Test under xvfb fail after upgrade to qt 5.15.0 for python:

    Now of course if you would care to dig that deeply into Qt to understand why that occurs and specifically with what it occurs with, as THEY (Qt) have describe it does. Then by all means do so, and share your findings. I am personally fine with adhering to their (Qt's) advice of declaring the Qt stuff first (I guess they do not adhere to PEP-8 either imagine that) followed by the python stuff followed by anything else.

    Could you provide link to article about this? Because I open Pyside2/__init__.py and it starts from

    from __future__ import print_function
    import os
    import sys
    

    Which is import of Python standard library

    If you import sys and check len(sys.modules.keys()) you will got information that above 60 modules are already loaded (Python 3.6.8 on Linux gives 63 modules loade). So import of any of this module cannot break Qt.

    Next Python-Qt is not pure Python code

    I see no difference for Qt and other libraries. Many of common used libraries has extensions in C ore are simply wrapper for C/C++ library.

    This putting all python standard library elements before third party libraries id good idea to see dependences of code. all packages from second section need to be installed using package manager.

    I understand how compilers works. I even write simple one. You produce wall of text which is not connected with my issue without any arguments. Breaking PEP-8 block usage of many tools which do code analysis, which speed-up and increase of quality of code developing.

    Finally it shown that whole problem is connected with drop single library from Qt build.

    However to prove this the code would have to be compiled without using qtpy and using perhaps that suggestion I made. If it were I and I was developing this project -- I would have 2 branches one that uses qtpy and one that does not -- and when compiling and running I would always do both in order to determine if qtpy (that extra layer that got added that I have no control of) is the issue or not.

    I do qtpy code review and it is enough.

    And I test my code against two version of Qt at same time and one pass and other fail. With exactly same version of other packages (qtpy also) so this need to be connected with Qt change.

    I also create short code example which in one version import from PySide2 not qtpy and it also fail.



  • @Czaki Ah. I actually clicked through to https://codereview.qt-project.org/c/qt/qtbase/+/253905 this time. Fascinating.

    Excellent detective work.


  • Banned

    @Czaki said in Test under xvfb fail after upgrade to qt 5.15.0 for python:

    Could you provide link to article about this? Because I open Pyside2/__init__.py and it starts from

    Okay the next time I stumble across it I will remember to record it this time. Most times I am in an intensive research mode and I never consider recording where all the bits and pieces are since the purpose is not to educate everyone else but just to educate myself.

    Okay it seems you are satisfied with your version of what you have found great I hope it helps you moving forward. I was only throwing out information I have encountered to give you more food for thought as well as things you ought to caution against doing based on my past experiences.

    BTW you do know that of the two PySide2 is not the one I would choose to test solidity against because it still uses code elements from Qt4 and of the two PyQt5 is far more up to date on having all the bits and pieces that correspond to the latest versions of Qt5 and as such is less likely to break because something internally is out of sync



  • My main backend is PyQt5 but it is from another company (Riverbank Computing). But, because of licensing, some people prefer PySide2 over PyQt5. So I try to write universal code. But it happens that some release of PySide2 breaks, when PyQt5 works. But fortunately next releases of PySide2 fixes it.

    I start this thread because It fail on both Qt packages, which means that it is connected with Qt code, not python part.

    And I show examples based on PySide2 because this package is produced by Qt company.


Log in to reply