Pyinstaller seems to struggle with formulas package - python-3.x

There is some code I want to turn into an exe. I have used Pyinstaller and I manage getting an exe that runs. The platform is Win10, Python version 3.6, devs with Spyder.
At some point in the code, the following lines pose an issue with the exe (not in script mode):
from formulas import parser as formulasparser
# code including classes
# in a function:
t = 'x<1' # any string that is a 'formula', here provided for the example
parser_ = formulasparser.Parser()
# the exe works so far, I have traced the code and can read the messages in the windows cmd
func = parser_.ast(t)
# nothing happens and no way to get a trace; there is an issue, and I have no clue which one as there
# is no error message.
So, it seems that the ast function won't work for some reason. Can anyone help me? I need to distribute this application and it does not work because of this right now.
Thanks for your help.

Well, someone seems to have faced a somewhat similar issue on the Pyinstaller mailing list.
So: a hook file is actually needed. I created a directory called pyinstallerhooks with a file called hook-formulas.py inside.
The file itself contains:
from PyInstaller.utils.hooks import collect_all
datas, binaries, hiddenimports = collect_all('formulas')
and this is it.
When calling pyinstaller, use the following command:
pyinstaller --additional-hooks-dir pathtoyourdir -F yoursrcipt.py
Pyinstaller fetches the relevant dependencies for the formulas package and it shoudl work.

Related

Pyinstaller executable fails with pkg_resources.DistributionNotFound error

I'm making a PDF Tool executable using tkinter. Anyways, the executable was successfully created by pyinstaller, but it won't run. I flagged --onedir and added the necessary dependency files --add-data. I also added the paths to my non standard library packages using --paths flag. When I run the executable from the command prompt, I get this:
The problem appears to come from the ocrmypdf module and says pkg_resources.DistributionNotFound. I tried searching for the fix, but all the problems I saw were a bit different from my issue because the .py script runs just fine for me. Is this a pyinstaller issue, or am I missing a module? I'm using pyinstaller 4.0 as well.
After researching a little bit more, I've found the solution. The problem lies with pyinstaller, not the ocrmypdf module. The solution is that you have to create hook py scripts within a folder in your project. It's a little bit different depending on which module you use, but for this case, I had to create two hook py scripts within a folder that I called 'hooks'. These are the two scripts I made:
hook-ocrmypdf.py
from PyInstaller.utils.hooks import collect_all
datas, binaries, hiddenimports = collect_all('ocrmypdf')
hook-pikepdf.py
from PyInstaller.utils.hooks import collect_all
datas, binaries, hiddenimports = collect_all('pikepdf')
For more information go here.
Additionally, you must add the --additional-hooks-dir HookFolderPath flag to the pyinstaller command.

Why can't I compile a script that contains pyttsx3?

I have been working using pyttsx3 on win7 64bit python 3.4.3. Everything is good with the .py script I made using pyttsx3 module (works fine alone).
The problem comes when I compile it with pyinstaller. I got an error saying "pyttsx3.drivers not found" and I fixed that by using a .spec file with hiddenimports. Then I got an error that says pywintypes.com_error:(-2147352573,member not found,none,none).
I found on github that someone by the name #natambashat fixed it by commenting out the pyi-rth-win32comgenpy.py runtime hook because that's only needed for pyttsx. But that didnt work for me, I still get the same error. Can you please help me?
You cannot compile a script that contains pyttsx3 with pyinstaller because, pyinstaller like all compilers do not have every single python module. Here is a link that shows you all the compatible packages for pyinstaller.
Another option is py2exe. I am not a Windows user, so I don't know how to use it. But it supposedly supports pyttsx.
Another option though untested by me, is to download the pyttsx source code, put it into your project directory, import it in the code that uses pyttsx, then compile it with pyinstaller using:
pyinstaller --onefile app.py
Eureka!!i fixed it! Am gonna write what i did step by step in case some one come-across to the same problem.
1.i made a hook-pyttsx3.py file and commented out the pyi-rth-win32comgenpy.py file(have a look at this link of github.( instead of commenting out,you can also remove the line "win32:pyi-rth-win32comgenpy.py" from the rthooks.DAT file in ...Lib/sitepackages/pyinstaller/loader/rthooks).
2.go to ...Lib/sitepackages/Win32com/client/dynamic.py and to the _GetDeskInvokeType function.Replace the last line(return invoke_type) with return varkind.
->For some people just step 1 works,but for me i need to apply step2.I found somewhere in sourceforge(i dont remember the link),when compiling a script that involves win32,pywin32 version 221 and 220 gives the pywintypes error i mentioned above.But pywin32 version 219 doesnt give this error(i am using pywin32 v221).And the reason behind that is,in the function i mentioned in step2,return invoke_type is only on version 221 and 220 but the return on v219 is return varkind.I don't know why this differece came if it gives such errors!
EDIT:This link Is better than the above i gave.

Run a python script with Popen with PyInstaller

I need to run a script inside a Popen inside a packaged project (with pyinstaller). The command NEEDS to run in python3 and I (obviously) need it to be portable, which means that I can't rely on the config (python/python3 notation) used on the machine I've used to generate the package neither the one where I am using it (I can't also guarantee that there will be any python in the deployment machine...).
I have computers where python is already the correct version, and others where the correct one is python3. I tried to insert #!/usr/bin python3 in the beginning of the file and then run as python but it didn't work.
subprocess.Popen(['python', 'internal.py', arg1, arg2], universal_newlines=True)
In the non-frozen environment I am able to run using sys.executable instead of python. I tried to "pyinstall" the internal.py then, "pyinstall" the rest copying the internal folder to the new folder and then call:
subprocess.Popen(['./internal/internal', arg1, arg2], universal_newlines=True)
But this doesn't work... In the console (moving to the bigger project folder) it does, but when running the package, it doesn't...
Any idea?
Ps. I can't just import the script as a class or whatever. I can't modify system environment vars (except the ones inside the pyinstaller thing...)
I saw something about the PyInstaller.compat that has a exec_python and a __wrap_python, but I couldn't use it I get errors when trying to run the package due to pkg_resources.DistributionNotFound: The 'PyInstaller' distribution was not found and is required by the application, I tried to create a hook, to add as hidden import... None worked (but the hook part maybe I got it wrong...)

How do I distribute my Python 3.6 application with all dependencies like in SqueezeTool

I have a python application that I built on Kivy for the GUI, and I separated that file from the RNN model. I just import that file directly with:
from keras_network import Network
I tried using the official trick to deploying using pyinstaller, but that doesn't work, as my application crashes, when running the final .exe file generated. I even made appropriate changes to the .spec file.
Isn't there an easier way to package this application in Python 3.6? (like SqueezeTool, which is too old, and isn't working in Python 3.6)
Can I compile the python files to .pyc files and have all dependencies statically linked? And why is this still such a big pain, when Python is so popular?
Ok... I finally got it to work.
I came up with this solution after I implemented the whole project in PyQt5, and while trying to package it with PyInstaller.
Here is how I got it to work (for people who could have any problems later):
Used python 3.5
Install Windows 10 SDK for some missing files that should've been with MSVC 2015.
Install the dev version PyInstaller from:
pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip --upgrade
Used the command to include my data files, as well as including hidden import h5py:
pyinstaller --add-data keras_model.h5;. --add-data TrainingData.txt;. --hidden-import=h5py --hidden-import=h5py.defs --hidden-import=h5py.utils --hidden-import=h5py.h5ac --hidden-import=h5py._proxy project-name.py
Then edited the .spec file generated. Added "from kivy.deps import sdl2, glew" without the quotes in the beginning of the file after the comment. Also added "*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)]," without the quotes in the COLLECT() function call as the 6th argument.
Then used the following command to rebuild using .spec file:
pyinstaller --add-data keras_model.h5;. --add-data TrainingData.txt;. --hidden-import=h5py --hidden-import=h5py.defs --hidden-import=h5py.utils --hidden-import=h5py.h5ac --hidden-import=h5py._proxy project-name.spec
Then the built application's executable was present in the 'dist\project-name\' directory. Double clicking the application lead to the application executing perfectly.
Hope this helps anyone stuck in the same place.

Python 3.5 App to .exe or copy libraries to another PC

I got the next problem.
During the last 3 months, I was building an application in Python 3.5 to test luminaries.
For this application I used the next libraries, "tkinter", "sys", "threading", "os", "time", "shutil" that are included on the main Python 3.5 interpreter. In addition to this system libraries, I use "pyserial", "PyGreSQL", "PIL", "win32com", and "qrcode".
The program will be used on many PCs, so I need to compile all the code to make a fully functional application in every PC that is installed.
I tried using PyInstaller, but it not works for me, for a reason that I don't understand, I can not make it work.
So, due that I think there is no more way to "compile" my python 3.5 app to an exe (all the solutions only works in Python 2.x), I think the solution is only two ways to resolve.
The first solution is, to copy the Python35 folder, that got all the libraries that I have already installed into another PC(this is because every single that I installed give me problems at the installation, specially pygresql) and if I can make an "Installer" that overwrite this Python35 folder into the new PC and create a link icon to the desktop that runs the .py script. (Simulate an APP is installed).
Or the second solution, rewrite all code into 2.x syntax and try installing again libraries for python 2.x, and make all the code functional again...
Which one do you recommend me... Or if you know any way that I could do this... I would be very grateful if you help me.
Thanks!
I've used CX_Freeze on my programs in the past, so far I have only used it with python 3.4.3, but I see no reason why it shouldn't work with python 3.5.
You can also install it with pip:
pip install CX_Freeze
See here for a tutorial.
I'm out at the moment, so I'll comment the code I use when I next have my computer.
I hope this helps.
EDIT:
Here is a version of the code (for batch):
set PATH=%PATH%;C:\Python34\
python "setup.py" build
pause
to use this code, you will need to make a setup script pointing to your program, an example is below:
import sys
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need fine tuning. This example will include the os package, and omit the tkinter package
build_exe_options = {"packages": ["os"], "excludes": ["tkinter"]}
# GUI applications require a different base on Windows (the default is for a
# console application).
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup( name = "test",
version = "0.1",
description = "My GUI application!",
options = {"build_exe": build_exe_options},
executables = [Executable("test.py", base=base)])
EDIT2:
Although the above code does work, the code I use is:
cxfreeze "%cd%\File.py" --target-dir "%cd%\File\"

Resources