Search code examples
python-3.xmacosbundlepyqt5pyinstaller

How to set LANG when creating a bundle with PyInstaller


I'm creating an application with PyQt5 (5.10) and Python 3.6. I'm using PyInstaller to bundle my application. On MacOS, PyInstaller creates a directory named dist which contains an executable myapp and the bundle myapp.app. The executable runs perfectly. The bundle myapp.app runs well, but when I'm inserting accented characters, as é into an input widget, the application crashes with the error:

UnicodeEncodeError: 'ascii' codec can't encode character '\xe9' in position 63: ordinal not in range(128)

The myapp.app just contains the executable myapp which runs as I expect.

I've tested to run myapp with an empty environment:

env -i ./myapp

I get the same error that myapp.app.

With a LANG defined:

env -i LANG=fr_FR.UTF-8 ./myapp

No errors.

So, I now know that the problem is related to LANG environment variable.

Now, my question is:

How to create my bundle to allow myapp.app to access the LANG environment variable?

Any help will be greatly appreciated.

Here is my PyInstaller spec file:

# -*- mode: python -*-

import os
import sys

block_cipher = None

if os.name == 'nt':
    icon = 'images/icon.ico'
elif sys.platform == 'darwin':
    icon = 'images/icon.icns'
else:
    icon = None

a = Analysis(['../main.py'],
             pathex=['.'],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
          cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='My App',
          debug=False,
          strip=False,
          upx=False,
          runtime_tmpdir=None,
          console=False, icon=icon)
app = BUNDLE(exe,
             name='My App.app',
             icon=icon,
             bundle_identifier='com.me.myapp',
             info_plist={
                 'NSHighResolutionCapable': 'True'
             },)

Solution

  • Finally found a solution to my problem.

    I don't know exactly why it crashed but, instead of printing str(my_value), I send it into a log file with the logging module, and there is no longer any crash.

    sys.getdefaultencoding() returns utf-8 so it will remain a mystery... So I guess it must be related to encoding and stdio problem.