The following relates to Python3.4, PyQt5.4, and OS X 10.10. While trying to bundle an app for distribution I found that the behavior of QSettings differs between the app when run by CPython from the command line, and when it runs in a “bundle” as prepared by cx_freeze[1] OR by PyInstaller[2].
The apps made by either bundling method fail in the identical way. That is why I am bringing this to the PyQt list first. I have reduced it to a bare minimum of code in hopes someone can suggest what to investigate next. [14:04:48 scratch] cat writer.py from PyQt5.QtCore import QCoreApplication, QSettings app = QCoreApplication([]) app.setOrganizationName("BOGUS_NAME") app.setOrganizationDomain("bogosity.com") app.setApplicationName("BOGUS_APP") settings = QSettings() settings.clear() settings.setValue('b',b'\xde\xad\xbe\xef') [14:04:53 scratch] cat reader.py from PyQt5.QtCore import QCoreApplication, QSettings app = QCoreApplication([]) app.setOrganizationName("BOGUS_NAME") app.setOrganizationDomain("bogosity.com") app.setApplicationName("BOGUS_APP") settings = QSettings() # open settings file assert b'\xde\xad\xbe\xef' == settings.value('b',b'\x00') All is nominal when run from the command line: [14:04:56 scratch] python3 writer.py [14:05:01 scratch] python3 reader.py The cx_freeze reader fails. [14:05:23 scratch] cxwork/dist/reader Traceback (most recent call last): File "reader.py", line 7, in <module> assert b'\xde\xad\xbe\xef' == settings.value('b',b'\x00') TypeError: unable to convert a QVariant back to a Python object The pyinstaller reader also fails the same way. [14:05:41 scratch] piwork/dist/reader/reader Traceback (most recent call last): File "<string>", line 7, in <module> TypeError: unable to convert a QVariant back to a Python object Remake the Settings file using a bundled writer: [14:05:48 scratch] rm ~/Library/Preferences/com.bogosity.BOGUS_APP.plist [14:06:12 scratch] piwork/dist/writer/writer Now the normal reader fails also. [14:06:23 scratch] python3 reader.py Traceback (most recent call last): File "reader.py", line 7, in <module> assert b'\xde\xad\xbe\xef' == settings.value('b',b'\x00') TypeError: unable to convert a QVariant back to a Python object But so do the bundled readers [14:06:30 scratch] piwork/dist/reader/reader Traceback (most recent call last): File "<string>", line 7, in <module> TypeError: unable to convert a QVariant back to a Python object The cxfreeze reader and writer tests are the same, omitted. To recap: the Settings plist written by the “normal” writer can be read only by the “normal” reader. The plist written by either bundled writer cannot be read by ANY reader. So is there a difference in output of a normal versus a bundled writer? [14:07:04 scratch] rm ~/Library/Preferences/com.bogosity.BOGUS_APP.plist [14:07:11 scratch] python3 writer.py [14:07:16 scratch] hexdump -C ~/Library/Preferences/com.bogosity.BOGUS_APP.plist 00000000 62 70 6c 69 73 74 30 30 d1 01 02 51 62 6f 10 2f |bplist00...Qbo./| 00000010 00 40 00 56 00 61 00 72 00 69 00 61 00 6e 00 74 |.@.V.a.r.i.a.n.t| 00000020 00 28 00 00 00 00 00 00 00 7f 00 00 00 00 00 00 |.(..............| 00000030 00 0e 00 50 00 79 00 51 00 74 00 5f 00 50 00 79 |...P.y.Q.t._.P.y| 00000040 00 4f 00 62 00 6a 00 65 00 63 00 74 00 00 00 00 |.O.b.j.e.c.t....| 00000050 00 00 00 00 00 0b 00 80 00 03 00 43 00 04 00 de |...........C....| 00000060 00 ad 00 be 00 ef 00 71 00 00 00 2e 00 29 08 0b |.......q.....)..| 00000070 0d 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 |................| 00000080 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000090 6e |n| [14:07:23 scratch] rm ~/Library/Preferences/com.bogosity.BOGUS_APP.plist [14:07:28 scratch] piwork/dist/writer/writer [14:07:37 scratch] hexdump -C ~/Library/Preferences/com.bogosity.BOGUS_APP.plist 00000000 62 70 6c 69 73 74 30 30 d1 01 02 51 62 5f 10 24 |bplist00...Qb_.$| 00000010 40 56 61 72 69 61 6e 74 28 00 00 00 7f 00 00 00 |@Variant(.......| 00000020 0e 50 79 51 74 5f 50 79 4f 62 6a 65 63 74 00 00 |.PyQt_PyObject..| 00000030 00 00 00 29 08 0b 0d 00 00 00 00 00 00 01 01 00 |...)............| 00000040 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 |................| 00000050 00 00 00 00 00 00 34 |......4| One immediate difference appears: the strings in the “normal” plist are in UTF-16(?), those in the “bundled” plist are ASCII. Another is that the byte string values "deadbeef" which are visible in the normal plist (offset 05f forward) are not visible in the other. This would explain why the “normal” reader cannot read the “bundled” plist - if it expected 16-bit chars. It might explain why the "bundled" reader can't read the "normal" plist (if it expects ASCII) and why it can't read a "bundled" plist (if the item value is munged/omitted). I need to make a "bundled" app work with QSettings, and would love any suggestions as to what to look at next. Thanks for your attention. [1] http://cx-freeze.sourceforge.net/ [2] https://github.com/pyinstaller/pyinstaller/wiki -- You received this message because you are subscribed to the Google Groups "PyInstaller" group. To unsubscribe from this group and stop receiving emails from it, send an email to pyinstaller+unsubscr...@googlegroups.com. To post to this group, send email to pyinstaller@googlegroups.com. Visit this group at http://groups.google.com/group/pyinstaller. For more options, visit https://groups.google.com/d/optout.