[PyQt] Wrong unicode text encoding in the embedded :qt/etc/qt.conf.

Phil Thompson phil at riverbankcomputing.com
Mon Nov 5 17:52:30 GMT 2018


On 5 Nov 2018, at 2:21 pm, Ales Erjavec <ales.erjavec324 at gmail.com> wrote:
> 
> Hi,
> 
> When PyQt5 (wheel) is installed on a path containing non-latin1
> characters it fails with
> ```
> qt.qpa.plugin: Could not find the Qt platform plugin "cocoa" in ""
> This application failed to start because no Qt platform plugin could
> be initialized. Reinstalling the application may fix this problem.
> 
> Abort trap: 6
> ```
> 
> To reproduce this, run (in bash):
> ```
> python -m venv --clear ~/virt/šš
> ~/virt/šš/bin/python -m pip install PyQt5
> ~/virt/šš/bin/python -c "import PyQt5.QtWidgets as w; w.QApplication([])"
> ```
> 
> Explicitly setting the QT_PLUGIN_PATH to the correct location does work however
> ```
> export QT_PLUGIN_PATH=$HOME/virt/šš/lib/python3.6/site-packages/PyQt5/Qt/plugins/
> ~/virt/šš/bin/python -c"import PyQt5.QtWidgets as w; w.QApplication([])"
> ```
> 
> The problem is that reading the "Paths/Prefix" in qt.conf with
> QSettings (the way Qt does), produces a garbled path:
> ```
> from PyQt5.QtCore import QSettings
> s = QSettings(":qt/etc/qt.conf", QSettings.IniFormat)
> print(s.value("Paths/Prefix"))
> # -> .../virt/sÌ\x8csÌ\x8c/lib/python3.6/site-packages/PyQt5/Qt'
> ```
> 
> Reading the file with QFile
> ```
> f = QFile(":/qt/etc/qt.conf")
> f.open(QFile.ReadOnly)
> print(bytes(f.readAll()).decode("utf-8"))
> ```
> reveals that the contents are utf-8 encoded,

The contents are a QByteArray created by calling QString::toLocal8Bit() on the pathname of the PyQt5 directory. See qpycore_qt_conf.cpp in the source tarball.

> however from
> http://doc.qt.io/qt-5/qsettings.html#Format-enum
> 
>> QSettings will accept Latin-1 encoded INI files, but generate pure ASCII files, where non-ASCII values are encoded using standard INI escape sequences.
> 
> The `QSettings` does have a `setIniCodec` method, but it is not used
> by Qt for parsing the qt.conf file.
> 
> Writing the path using QSettings
> ```
> s = QSettings("a.conf", QSettings.IniFormat)
> s.setValue("Paths/Prefix", ".../virt/šš/...")
> ```
> produces:
> ```
> [Paths]
> Prefix=".../virt/\x161\x161/..."
> ```
> which can then be correctly read back.
> 
> Unfortunately Qt does not provide a public interface for INI escape
> sequence encoding. It is implemented in
> http://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/io/qsettings.cpp?h=v5.11.2#n618
> 
> Tested on:
> * macOS 10.11.6, Python 3.6, PyQt5 5.11.3
> * KDE Neon 16.04 Python 3.5, PyQt5 5.11.3

Sorry, I'm not clear what your suggestion/fix is.

Phil


More information about the PyQt mailing list