6

I've got an open source python command line program that runs on Python 2.7, Python3+, and is cross platform.

I'm trying to package it up into an executable for my windows users more easily. The source for this package is up on Github here: https://github.com/stormpath/stormpath-cli

I'm trying to package my Python program up using pyinstaller, but am having issues.

I'm running the following commands from a Windows 8 box:

$ pyinstaller --onefile setup.py

This successfully generates an EXE file for me, but when I go to run it, I get the following errors:

Traceback (most recent call last):
  File "setup.py", line 4, in <module>
  File "c:\python27\Lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 389, in load_module
    exec(bytecode, module.__dict__)
  File "site-packages\setuptools\__init__.py", line 160, in <module>
  File "site-packages\setuptools\monkey.py", line 93, in patch_all
  File "site-packages\setuptools\monkey.py", line 145, in patch_for_msvc_specialized_compiler
  File "importlib\__init__.py", line 37, in import_module
ImportError: No module named msvc
Failed to execute script setup

For testing purposes, to help narrow the issue down, I created a test.py script that contains the following code:

print('hello, world!')

And then packaged that into an exe as well:

$ pyinstaller --onefile test.py

When I run this resulting exe, everything works great! Hello world is output as expected.

I believe what's happening is that I'm not telling pyinstaller how to properly 'detect' that my project is a python package, and not a single file script.

I've read through the docs a lot, and have googled around, but haven't found a way to specify a package for pyinstaller to analyze.

What am I missing?

martineau
  • 119,623
  • 25
  • 170
  • 301
rdegges
  • 32,786
  • 20
  • 85
  • 109
  • 1
    I don't think you should be pointing to the setuptools script. That's just for installing it, you should instead point towards the module stormpath-cli. `main.py` may need to be renamed to `__main__.py` I believe this issue is coming up because setuptools does some dynamic system-specific stuff and when it's bundled it can't access it properly... – GRAYgoose124 Jan 19 '17 at 00:41
  • Yah, I agree. I think this is the problem. Just not sure what I *should* point it to :o How will it know how to install the script to the correct place without a setup script? oO – rdegges Jan 19 '17 at 00:45
  • It won't, the exe created will be the functioning program. When you run it, it won't install, it will just execute the stormpath-cli. I.E. an all-in-one portable app. I think it's a lot easier to do that, then bundle that exe inside of an installer. (Which really could just be a batch file adding it to path, moving it to the proper program directory, etc) I don't think setuptools was ever intended to run from a frozen environment and without going into it I can imagine there being a lot of problems there. I think setuptools checks if the python path is read-only, among other things. – GRAYgoose124 Jan 19 '17 at 00:46
  • PyInstaller is for installing a "Python **application** and all its dependencies into a single package", not for installing a Python package. You need to use something else, like the [`distutils`](https://docs.python.org/2/library/distutils.html#module-distutils) package, to do that. – martineau Jan 19 '17 at 01:58
  • @martineau A Python package *can be* an application -- just add `__main__.py` and now you can "run" a package. – Jonathon Reinhart Apr 13 '17 at 14:42
  • I've [opened an issue](https://github.com/pyinstaller/pyinstaller/issues/2560) with PyInstaller. – Jonathon Reinhart Apr 13 '17 at 14:42
  • @Jonathon: Thank you for pointing-out a somewhat obscure fact about Python packages to me. Suggest you post the workaround here as an answer to the OP's question (so they don't have to wait for PyInstaller to be fixed). – martineau Apr 13 '17 at 15:02

3 Answers3

3

While I think it is a perfectly reasonable thing to do, it looks like PyInstaller simply doesn't support building an application from a package (with __main__.py).

See https://github.com/pyinstaller/pyinstaller/issues/2560.

As a workaround, you can write a small stub (outside of the package) that does the same the same thing as your __main__.py. Then point PyInstaller at that.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • 2
    Note that instead of adding yet another file you can simple use `__main__.py` as your script for PyInstaller, and make sure that all imports are absolute (not relative). This is [mentioned in a comment](https://github.com/pyinstaller/pyinstaller/issues/2560#issuecomment-377917879) on GitHub. – Peterino Oct 02 '18 at 09:10
0

I think you forgot "pyinstaller -w --onefile test.py". You forgot '-w'.

0

Firstly install pyinstaller

pip install pyinstaller 

To create exe executable folder, just run the following command:

pyinstaller exam_browser.py

If you want single exe file with a logo run this command:

pyinstaller exam_browser.py --onefile -F --icon logo.ico
Turcia
  • 653
  • 1
  • 12
  • 29