ronaldoussoren / py2app

py2app is a Python setuptools command which will allow you to make standalone Mac OS X application bundles and plugins from Python scripts.
Other
340 stars 36 forks source link

macOS: py2app produced binary errors out: No module named 'encodings' #481

Open mario-grgic opened 1 year ago

mario-grgic commented 1 year ago

I am using macOS 10.15.7 (Catalina) with Python 3.11.1 and py2app version 0.28.5. I have a simple tkinter python script that works when run from command line that I am trying to package as standalone Mac application.

My setup.py looks like this:

"""
This is a setup.py script generated by py2applet

Usage:
    python setup.py py2app
"""

from setuptools import setup

APP = ['test.py']
DATA_FILES = []
OPTIONS = {}

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)

then I run python3 setup.py py2app which generates a working application:

...
checking for any import problems
Modules not found (unconditional imports):
 * _io._WindowsConsoleIO (importlib._bootstrap_external)
 * _overlapped (asyncio.windows_events)

Modules not found (conditional imports):
 * _manylinux (pkg_resources._vendor.packaging._manylinux)
 * jnius (pkg_resources._vendor.platformdirs.android, platformdirs.android)

Done!

When I run the generate application I get the error:

Python path configuration:
  PYTHONHOME = '/Volumes/ramdisk/Test.app/Contents/Resources'
  PYTHONPATH = '/Volumes/ramdisk/Test.app/Contents/Resources'
  program name = '/Applications/Xcode.app/Contents/Developer/usr/bin/python3'
  isolated = 0
  environment = 1
  user site = 1
  import site = 1
  sys._base_executable = '/Applications/Xcode.app/Contents/Developer/usr/bin/python3'
  sys.base_prefix = '/Volumes/ramdisk/Test.app/Contents/Resources'
  sys.base_exec_prefix = '/Volumes/ramdisk/Test.app/Contents/Resources'
  sys.executable = '/Applications/Xcode.app/Contents/Developer/usr/bin/python3'
  sys.prefix = '/Volumes/ramdisk/Test.app/Contents/Resources'
  sys.exec_prefix = '/Volumes/ramdisk/Test.app/Contents/Resources'
  sys.path = [
    '/Volumes/ramdisk/Test.app/Contents/Resources',
    '/Volumes/ramdisk/Test.app/Contents/Resources/lib/python38.zip',
    '/Volumes/ramdisk/Test.app/Contents/Resources/lib/python3.8',
    '/Volumes/ramdisk/Test.app/Contents/Resources/lib/python3.8/lib-dynload',
  ]
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'

Current thread 0x000000010e590dc0 (most recent call first):
<no Python frame>
mario-grgic commented 1 year ago

That /Applications/Xcode.app/Contents/Developer/usr/bin/python3 path above is very suspect. Not sure why that is picked up at all.

AymericFerreira commented 1 year ago

Did you find a solution ? I have the same issue.

mario-grgic commented 1 year ago

@AymericFerreira No, I have not pursued this further, so I don't have a workaround.

rauta0127 commented 4 months ago

+1

AymericFerreira commented 2 months ago

We finally managed to solve the issue, although the workaround might not be the same for everyone. However, I'll share our solution in case it helps.

Here was our full error log:

Python path configuration:
 PYTHONHOME = ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/Resources’
 PYTHONPATH = ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/Resources’
 program name = ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/MacOS/python’
 isolated = 0
 environment = 1
 user site = 1
 safe_path = 0
 import site = 1
 is in build tree = 0
 stdlib dir = ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/Resources/lib/python3.12’
 sys._base_executable = ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/MacOS/python’
 sys.base_prefix = ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/Resources’
 sys.base_exec_prefix = ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/Resources’
 sys.platlibdir = ‘lib’
 sys.executable = ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/MacOS/python’
 sys.prefix = ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/Resources’
 sys.exec_prefix = ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/Resources’
 sys.path = [
  ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/Resources’,
  ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/Resources/lib/python312.zip’,
  ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/Resources/lib/python3.12’,
  ‘/Users/aymericferreira/Downloads/StitcherApp.app/Contents/Resources/lib/python3.12/lib-dynload’,
 ]
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
Traceback (most recent call last):
 File “<frozen zipimport>“, line 518, in _get_decompress_func
ImportError: dlopen(/Users/aymericferreira/Downloads/StitcherApp.app/Contents/Resources/zlib.cpython-312-darwin.so, 0x0002): Symbol not found: _adler32
 Referenced from: <8C70B32E-A411-312F-AF6B-7C317ACCFF47> /Users/aymericferreira/Downloads/StitcherApp.app/Contents/Resources/zlib.cpython-312-darwin.so
 Expected in:   <9465408F-73C9-346B-986D-F8A0C8590651> /Users/aymericferreira/Downloads/StitcherApp.app/Contents/Frameworks/libz.1.3.1.dylib
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
 File “<frozen zipimport>“, line 566, in _get_data
 File “<frozen zipimport>“, line 521, in _get_decompress_func
zipimport.ZipImportError: can’t decompress data; zlib not available
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
 File “<frozen zipimport>“, line 137, in get_code
 File “<frozen zipimport>“, line 700, in _get_module_code
 File “<frozen zipimport>“, line 568, in _get_data
zipimport.ZipImportError: can’t decompress data; zlib not available

In our case, the issue was related to the zlib library. The solution was to explicitly include zlib in the setup.py file as follows:

OPTIONS = {
    "packages": ["zlib", ...],
    "includes": ["zlib", ...]
}

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)