Search code examples
pythonpython-sphinxpyside2read-the-docsxcb

Can you use QT in a ReadTheDocs build without mocking?


Our project uses QT (PySide2, qtpy) and is documented on ReadTheDocs using sphinx autodoc. Up til now we have mocked out most dependencies, but in this specific case mocking qtpy is very complicated. I am hoping to simplify by installing the dependencies in the conda or python sections of .readthedocs.yml.

Installing seems to work fine but I am getting an error in the sphinx-build step of the RTD build:

qt.qpa.xcb: could not connect to display 
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl, xcb.

Fatal Python error: Aborted

The traceback points to the line in our code: QT_APP = QApplication(sys.argv).

I have tried setting QT_DEBUG_PLUGINS=1 which gives some output that I can't make anything of:

...
Got keys from plugin meta data ("xcb")
QFactoryLoader::QFactoryLoader() checking directory path "/home/docs/checkouts/readthedocs.org/user_builds/invest/conda/395/bin/platforms" ...
loaded library "/home/docs/checkouts/readthedocs.org/user_builds/invest/conda/395/lib/python3.8/site-packages/PySide2/Qt/plugins/platforms/libqeglfs.so"
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-docs'
QFactoryLoader::QFactoryLoader() checking directory path "/home/docs/checkouts/readthedocs.org/user_builds/invest/conda/395/lib/python3.8/site-packages/PySide2/Qt/plugins/egldeviceintegrations" ...
QFactoryLoader::QFactoryLoader() looking at "/home/docs/checkouts/readthedocs.org/user_builds/invest/conda/395/lib/python3.8/site-packages/PySide2/Qt/plugins/egldeviceintegrations/libqeglfs-emu-integration.so"
Found metadata in lib /home/docs/checkouts/readthedocs.org/user_builds/invest/conda/395/lib/python3.8/site-packages/PySide2/Qt/plugins/egldeviceintegrations/libqeglfs-emu-integration.so, metadata=
{
    "IID": "org.qt-project.qt.qpa.egl.QEglFSDeviceIntegrationFactoryInterface.5.5",
    "MetaData": {
        "Keys": [
            "eglfs_emu"
        ]
    },
    "archreq": 0,
    "className": "QEglFSEmulatorIntegrationPlugin",
    "debug": false,
    "version": 331520
}
...

And I have tried changing the platform plugin by setting QT_QPA_PLATFORM=eglfs, which gives a similar error: Could not initialize egl display. Googling for the errors mostly turned up issues related to Raspberry Pi.

Is this happening because the virtual machine running the build doesn't actually have a display? Is there any way around this?


Solution

  • Is this happening because the virtual machine running the build doesn't actually have a display?

    I would guess "yes". The error should be that Qt failed to connect to the X11 display.

    Is there any way around this?

    You can try running your build script under xvfb-run. So, instead of running foo, you would run xvfb-run. This sets up a headless X11 server.