Execute py script in pyinstaller spec file

2.2k Views Asked by At

I use PyInstaller to bundle my app in exe (for windows as of now). I have successfully added version info to the exe file by creating the version.rc file. I also want to use current version at run time to take some decisions. Thus I want to create the version.rc file dynamically at the time of creating package using pyinstaller. Also want to have only on reference to current version. So, I have created a _version.py file at root. This file contains a property and a function

__version__ = '0.0.0.1'
def write_version_file():
    content = f'''
    VSVersionInfo(
        ffi=FixedFileInfo(
        mask=0x3f,
        flags=0x0,
        OS=0x40004,
        fileType=0x1,
        subtype=0x0,
        date=(0, 0)),
        kids=[StringFileInfo([StringTable(
        u'040904B0',
        [StringStruct(u'FileDescription', u'spagent'),
        StringStruct(u'FileVersion', u'{__verison__}'),
        StringStruct(u'InternalName', u'spagent'),
        StringStruct(u'LegalCopyright', u'Copyright'),
        StringStruct(u'OriginalFilename', u'spagent'),
        StringStruct(u'ProductName', u'spagent'),
        StringStruct(u'ProductVersion', u'{__verison__}'),
        StringStruct(u'Language', u'Language Neutral'),
        StringStruct(u'LegalTrademarks', u'')])]), 
        VarFileInfo([VarStruct(u'Translation', [1033, 1200])])]
    )
    '''
    filePath = os.path.join('version.rc')
    with open(filePath, 'w') as w:
        w.write(content)

I am trying to execute the write_version_file script in spec file, so that it writes the version.rc file just before creating build. and use that file for versioning. Below is the extract of my main.spec file.

# -*- mode: python -*-
block_cipher = None
import shutil
import glob
from distutils.dir_util import copy_tree

#create version file
from _version import write_version_file
write_version_file()

my directory structure is as below

spagent
--_version.py
--main.py
--main.sepec
--other directories

pyinstaller main.spec fails to execute the script as it can not import the _version module.

Traceback (most recent call last):
  File "C:\Users\chaudm05\AppData\Local\Programs\Python\Python37-32\Scripts\pyinstaller-script.py", line 11, in <module>
    load_entry_point('PyInstaller==3.5', 'console_scripts', 'pyinstaller')()
  File "c:\users\chaudm05\appdata\local\programs\python\python37-32\lib\site-packages\PyInstaller\__main__.py", line 111, in run
    run_build(pyi_config, spec_file, **vars(args))
  File "c:\users\chaudm05\appdata\local\programs\python\python37-32\lib\site-packages\PyInstaller\__main__.py", line 63, in run_build
    PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
  File "c:\users\chaudm05\appdata\local\programs\python\python37-32\lib\site-packages\PyInstaller\building\build_main.py", line 844, in main
    build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
  File "c:\users\chaudm05\appdata\local\programs\python\python37-32\lib\site-packages\PyInstaller\building\build_main.py", line 791, in build
    exec(code, spec_namespace)
  File "main.spec", line 8, in <module>
    from _version import write_version_file
ModuleNotFoundError: No module named '_version'

I suspect it is, because the pyinstaller script is executing at different location (c:\users\chaudm05\appdata\local\programs\python\python37-32\lib\site-packages\PyInstaller\building\build_main.py) thus it can not find the _version.py. If that is true the how can I achieve it ?

0

There are 0 best solutions below