Pyinstaller with relative imports

蹲街弑〆低调 提交于 2021-02-06 10:49:40

问题


I'm attempting to make a Pyinstaller build for Windows 7 using Pyinstaller 2.1. The module uses relative imports because the package is typically used in Linux as a 'regular' Python package. Is there a way to create a spec file to handle this type of setup? Ideally I would like to have a Python package that I can make a Pyinstaller exe with for Windows and have a 'regular' pip-installable Python package in Linux/OS X.

I was thinking of maybe using hidden imports or something to achieve this.

I've tried using the default Pyinstaller settings and pointing it at my 'main' python script. I get the following from the resulting exe:

'Attempted relative import in non-package'

This makes sense because I'm pointing Pyinstaller at my main.py file in the package and Pyinstaller is NOT picking up my entire package. This is just the starting point for using the module from the command-line. However, you can import it and use it in your own code as well.

Sidenote:

The reasoning is this package requires numpy and scipy. Yes, I know there are good ways to get these working in Windows with Anaconda, etc. However, I'm stuck with an exe setup now for legacy reasons.


回答1:


I can't find a way to get Pyinstaller to do this. However, I don't think it's the fault of Pyinstaller. It's more of a problem with the way I structured my package.

I was passing a script to Pyinstaller that was a part of my package. The better way to do that would be to provide a simple Python script outside of the package that serves as the cli front-end to the package.

For example, consider a package layout like this (assume files use relative imports):

repo_dir/
    setup.py
    README.md
    package_a/
        main.py
        support_module.py
        __init__.py

My previous attempt was trying to build main.py by passing it to Pyinstaller. This resulted in the error mentioned in the above question.

However, I later added a cli.py script that does something like this:

from package_a.main import main
if __name__ == '__main__':
    main()

Now, I can pass cli.py to Pyinstaller and my explicit relative imports are only used inside of the package. So, it all works. Here's a sample directory layout that works just for reference:

repo_dir/
    setup.py
    cli.py
    README.md
    package_a/
        main.py
        support_module.py
        __init__.py


来源:https://stackoverflow.com/questions/22457809/pyinstaller-with-relative-imports

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!