moses-palmer / pystray

GNU General Public License v3.0
482 stars 59 forks source link

Get TypeError exception for value of __package__ is None after py2exe #105

Closed jason990420 closed 2 years ago

jason990420 commented 3 years ago

The execution of EXE file compiled by py2exe and stopped when import pystray. Following show all the related information, not sure what's wrong here.

  1. Platform

    • WIN10
    • Python 3.9.5
    • pystray 0.18.0
    • py2exe 0.11.0.1
  2. Test filea

    
    # test3.py
    import pystray

print('Hello World')

```python
# setup.py
from distutils.core import setup
import py2exe

setup(
    options={'py2exe': {'includes': ['pystray._win32']}},
    console=[{'script': 'test3.py',}],
)
  1. The process

    
    d:\>python setup.py py2exe
    running py2exe
    
    14 missing Modules
    ------------------
    ? StringIO                            imported from six
    ? __main__                            imported from bdb, pdb
    ? _frozen_importlib                   imported from importlib, importlib.abc, zipimport
    ? _frozen_importlib_external          imported from importlib, importlib._bootstrap, importlib.abc, zipimport
    ? _posixshmem                         imported from multiprocessing.resource_tracker, multiprocessing.shared_memory
    ? _util.serialized_image              imported from pystray._win32
    ? _winreg                             imported from platform
    ? asyncio.DefaultEventLoopPolicy      imported from -
    ? dummy.Process                       imported from multiprocessing.pool
    ? java.lang                           imported from platform
    ? org.python.core                     imported from copy, pickle
    ? os.path                             imported from os, pkgutil, py_compile, sysconfig, tracemalloc, unittest, unittest.util
    ? pep517                              imported from importlib.metadata
    ? readline                            imported from cmd, code, pdb
    Building 'dist\test3.exe'.
    Building shared code archive 'dist\library.zip'.
    Copy c:\software\python\python39.dll to dist
    Copy C:\Software\Python\DLLs\unicodedata.pyd to dist\unicodedata.pyd
    Copy C:\Software\Python\DLLs\select.pyd to dist\select.pyd
    Copy C:\Software\Python\DLLs\_bz2.pyd to dist\_bz2.pyd
    Copy C:\Software\Python\DLLs\_lzma.pyd to dist\_lzma.pyd
    Copy C:\Software\Python\DLLs\_hashlib.pyd to dist\_hashlib.pyd
    Copy C:\Software\Python\DLLs\pyexpat.pyd to dist\pyexpat.pyd
    Copy C:\Software\Python\DLLs\_socket.pyd to dist\_socket.pyd
    Copy C:\Software\Python\DLLs\_ssl.pyd to dist\_ssl.pyd
    Copy C:\Software\Python\DLLs\_queue.pyd to dist\_queue.pyd
    Copy C:\Software\Python\DLLs\_tkinter.pyd to dist\_tkinter.pyd
    Copy C:\Software\Python\DLLs\_uuid.pyd to dist\_uuid.pyd
    Copy C:\Software\Python\DLLs\_ctypes.pyd to dist\_ctypes.pyd
    Copy C:\Software\Python\DLLs\_multiprocessing.pyd to dist\_multiprocessing.pyd
    Copy C:\Software\Python\DLLs\_decimal.pyd to dist\_decimal.pyd
    Copy C:\Software\Python\DLLs\_asyncio.pyd to dist\_asyncio.pyd
    Copy C:\Software\Python\DLLs\_overlapped.pyd to dist\_overlapped.pyd
    Copy DLL C:\Software\Python\DLLs\libssl-1_1.dll to dist\
    Copy DLL C:\Software\Python\DLLs\tcl86t.dll to dist\
    Copy DLL C:\Software\Python\DLLs\libcrypto-1_1.dll to dist\
    Copy DLL C:\Software\Python\DLLs\tk86t.dll to dist\
    Copy DLL C:\Software\Python\DLLs\libffi-7.dll to dist\

d:>cd dist

d:\dist>test3

![image](https://user-images.githubusercontent.com/55352169/142375476-1c197aaa-c928-48fe-b6d0-4614e07697ea.png)

```python
d:\dist>type test3.log
Traceback (most recent call last):
  File "test3.py", line 2, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 627, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "psgtray\__init__.pyc", line 2, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 627, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "psgtray\psgtray.pyc", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 627, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "pystray\__init__.pyc", line 48, in <module>
  File "pystray\__init__.pyc", line 40, in backend
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
Traceback (most recent call last):
  File "test3.py", line 2, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 627, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "psgtray\__init__.pyc", line 2, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 627, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "psgtray\psgtray.pyc", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 627, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "pystray\__init__.pyc", line 49, in <module>
  File "pystray\__init__.pyc", line 41, in backend
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
Traceback (most recent call last):
  File "test3.py", line 2, in <module>
  File "<frozen zipimport>", line 259, in load_module
  File "psgtray\__init__.pyc", line 2, in <module>
  File "<frozen zipimport>", line 259, in load_module
  File "psgtray\psgtray.pyc", line 1, in <module>
  File "<frozen zipimport>", line 259, in load_module
  File "pystray\__init__.pyc", line 49, in <module>
  File "pystray\__init__.pyc", line 45, in backend
ImportError: this platform is not supported: No module named 'pystray._win32'
Traceback (most recent call last):
  File "test3.py", line 2, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 627, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "psgtray\__init__.pyc", line 2, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 627, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "psgtray\psgtray.pyc", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 627, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "pystray\__init__.pyc", line 49, in <module>
  File "pystray\__init__.pyc", line 41, in backend
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
Traceback (most recent call last):
  File "test3.py", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 627, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "pystray\__init__.pyc", line 48, in <module>
  File "pystray\__init__.pyc", line 40, in backend
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
Traceback (most recent call last):
  File "test3.py", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 664, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 627, in _load_backward_compatible
  File "<frozen zipimport>", line 259, in load_module
  File "pystray\__init__.pyc", line 48, in <module>
  File "pystray\__init__.pyc", line 40, in backend
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

Line # 40 in pystray/init.py get exception when execute test3.py

            return importlib.import_module(__package__ + '._' + module)

After checked, __package__ will be None. Not sure why it happened. One more statement added to set it to 'pystray', then everything OK.

def backend():
    """Returns the backend module.
    """
    import importlib

    backend_name = os.environ.get('PYSTRAY_BACKEND', None)
    if backend_name:
        modules = [backend_name]
    elif sys.platform == 'darwin':
        modules = ['darwin']
    elif sys.platform == 'win32':
        modules = ['win32']
    else:
        modules = ['appindicator', 'gtk', 'xorg']

    errors = []
    __package__ = 'pystray'        # New statement added here
    for module in modules:
        try:
            return importlib.import_module(__package__ + '._' + module)
        except ImportError as e:
            errors.append(e)

    raise ImportError('this platform is not supported: {}'.format(
        '; '.join(str(e) for e in errors)))
moses-palmer commented 2 years ago

Thank you for your report.

Can you test the branch feature-explicit-backends? I contains changes to the dynamic backend loading to simplify using packagers, and does not reference __package__.

jason990420 commented 2 years ago

Don't know how to install it from github, so I replaced all files.

After replaced all files and subdirectory under Lib\site-packages\pystray from https://github.com/moses-palmer/pystray/tree/feature-explicit-backends/lib/pystray, then test it again, it looks fine now.

Very grateful for your help !

d:\>python setup.py py2exe
running py2exe

  505 missing Modules
  ------------------
? AppKit                              imported from pystray._darwin
? Foundation                          imported from pystray._darwin
? IPython                             imported from matplotlib.backend_bases, matplotlib.pyplot
? IPython.core                        imported from matplotlib.backend_bases
? IPython.core.pylabtools             imported from matplotlib.pyplot
? IPython.display                     imported from PIL.ImageShow

...

Copy DLL C:\Software\Python\DLLs\libcrypto-1_1.dll to dist\
Copy lib file C:\Software\Python\lib\site-packages\certifi\cacert.pem to dist\
Copy ExtensionDLL C:\Software\Python\Lib\site-packages\pywin32_system32\pythoncom39.dll to dist\
Copy ExtensionDLL C:\Software\Python\python3.dll to dist\
Copy ExtensionDLL C:\Software\Python\Lib\site-packages\pywin32_system32\pywintypes39.dll to dist\

d:\>cd dist

d:\dist>test3
Hello World
moses-palmer commented 2 years ago

Thank you for your feedback!

I have made a new release pystray 0.19.1 with this fix.