PIL/Pillow - ValueError: py.__spec__ is not set

Viewed 1803

I'm trying to make an exe file using py2exe. Previously, this turned out well - I still have the working exe file of this code I edited. However, when I try running the below code now, I get a "ValueError: py.__spec__ is not set" error in Anaconda command prompt. Attempting to create exe file of another program comes out right.

Unfortunately, I saved over the old version of the program that worked earlier, but I reverted my new program to the old version from memory and it still doesn't work. Any ideas why this is happening? I believe it has to do with PIL module because that's the only difference between my other program that continues to get converted correctly to exe. Also, commenting out PIL module also leads to successful conversion. However, this means the program cannot be used for what it was made.

py2exe setup.py code:

from distutils.core import setup

import py2exe

setup(console=['resizeImg.py'])

My program:

from PIL import Image
import os, sys
from pathlib import Path

while True:
    # Warning message for users
    print('')
    print('IMPORTANT!!!'.center(len('IMPORTANT!!!')+12,'*'))
    print('If a file exists in the same name in destination folder, \
it will be IRREVERSIBLY OVERWRITTEN!')
    print('*'*(len('IMPORTANT!!!')+12))
    
    print('\nEnter full paths for source and destination. \
          \nEnter q to quit.')
          
    spath = input('Source path: ')
    if spath == 'q':
        sys.exit()
    dpath = input('Destination path: ')
    if dpath == 'q':
        sys.exit()
    elif dpath == spath:
        Path(spath,'scaledImages').mkdir(exist_ok=True)
        dpath = str(Path(spath,'scaledImages'))
    htsize = int(input('Height dimension: '))
    if htsize == 'q':
        sys.exit()
    
    os.chdir(Path(spath))
    optSize = htsize
    
    for filename in os.listdir('.'):
        print (filename)
        if not (filename.endswith('.jpeg') or filename.endswith('.jpg') or filename.endswith('.png') or filename.endswith('.bmp')):
            continue
        else:
            im = Image.open(filename)
            width, height = im.size
            
        if height > optSize:
            # commented out to remove width height check
            # if width > height:
            #     height = int((optSize / width) * height)
            #     width = optSize
                
            # else:
            #     width = int((optSize / height) * width)
            #     height = optSize
            width = int((optSize / height) * width)
            height = optSize
            
                
            print('')
            print(f'Resizing {filename} ...')
            
            im = im.resize((width,height))
            
            im.save(Path(dpath) / filename)
            
        else:
            im.save(Path(dpath) / filename)
            
        print('New dimension: ' + str(width) + ' x ' + str(height))
            
    print('\nRescaling complete. Rescaled images saved in: ' + \
          dpath + '\n')
    quitPrompt = input('q to quit; any other input for new search: ')
    if quitPrompt.lower() == 'q':
        sys.exit()

When I try to execute py2exe in Anaconda command prompt by running 'python setup.py py2exe'

running py2exe
Traceback (most recent call last):
  File "setup.py", line 11, in <module>
    setup(console=['resizeImg.py'])
  File "C:\Users\hamis\anaconda3\lib\distutils\core.py", line 148, in setup
    dist.run_commands()
  File "C:\Users\hamis\anaconda3\lib\distutils\dist.py", line 966, in run_commands
    self.run_command(cmd)
  File "C:\Users\hamis\anaconda3\lib\distutils\dist.py", line 985, in run_command
    cmd_obj.run()
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\distutils_buildexe.py", line 192, in run
    self._run()
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\distutils_buildexe.py", line 272, in _run
    builder.analyze()
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\runtime.py", line 177, in analyze
    target.analyze(mf)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\runtime.py", line 78, in analyze
    modulefinder.run_script(self.script)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 62, in run_script
    self._scan_code(mod.__code__, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 109, in import_hook
    self._handle_fromlist(module, fromlist, caller)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 180, in _handle_fromlist
    self._gcd_import('{}.{}'.format(mod.__name__, x))
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 393, in _scan_code
    self._scan_code(c, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 393, in _scan_code
    self._scan_code(c, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 109, in import_hook
    self._handle_fromlist(module, fromlist, caller)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 180, in _handle_fromlist
    self._gcd_import('{}.{}'.format(mod.__name__, x))
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 393, in _scan_code
    self._scan_code(c, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 393, in _scan_code
    self._scan_code(c, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 104, in import_hook
    module = self._gcd_import(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 109, in import_hook
    self._handle_fromlist(module, fromlist, caller)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 180, in _handle_fromlist
    self._gcd_import('{}.{}'.format(mod.__name__, x))
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 104, in import_hook
    module = self._gcd_import(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 393, in _scan_code
    self._scan_code(c, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 393, in _scan_code
    self._scan_code(c, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 104, in import_hook
    module = self._gcd_import(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 104, in import_hook
    module = self._gcd_import(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 109, in import_hook
    self._handle_fromlist(module, fromlist, caller)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 180, in _handle_fromlist
    self._gcd_import('{}.{}'.format(mod.__name__, x))
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 104, in import_hook
    module = self._gcd_import(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 303, in _find_and_load
    spec = importlib.util.find_spec(name, path)
  File "C:\Users\hamis\anaconda3\lib\importlib\util.py", line 111, in find_spec
    raise ValueError('{}.__spec__ is not set'.format(name)) from None
ValueError: py.__spec__ is not set
2 Answers

I use python 3.8 et spyder 4.1.4.

When you are creating your exe with the library py2exe, sometimes there are problems with the import of modules. if you find the wrong module, you can exclude it in your setup.py.

  • How find the wrong module during the import when you create your exe ? :

The library py2exe use the script util.py, in the library importlib, to constructing importer. In this script, you add a print(module) in the function find_spec() in the else :

else:
    module = sys.modules[fullname]
    print(module)
    if module is None:
        return None

After add the print, when you will try to create an exe, in the console, you will see the imported modules. And when there is an error like :

ValueError: py.__spec__ is not set

Search the last module whose imported and exclude it in your setup.py. Module by module, you won't see any more mistakes.

  • How to exclude a module ? :

To exclude a wrong module in your setup.py, write the name of the wrong module in the options. If you want, you can also exclude dll_excludes.

Below, i excluded wrong modules of your script :

from distutils.core import setup

import py2exe

setup(options = {"py2exe":{   "excludes": ["_pytest","qtpy"] } },
      console = ['resizeImg.py'])

I don't know if it's a good way to solves your problem, but it's functionnal with my scripts when i want to convert a py to an exe.

p2exe works until python version 3.6

If you manage to downgrade python runtime, it should compile well. Else, you would need to use alternative libraries like pyinstaller

Related