What is the correct way on converting a python script to binary using pyinstaller and opencl? How do I setup the name.spec file? See my pyinstaller settings below
Usage: pyinstaller --clean --noconfirm --log-level=DEBUG --onefile --paths=/home/testuser/projects/tool --paths=/usr/local/lib/python3.8/dist-packages/pyopencl-2018.2.2-py3.8-linux-x86_64.egg --hidden-import=pyopencl --name=toolexe tool.py
From my main script(myscript.py), I am calling "import tool as *", which is my tool package, and it's calling "import pyopencl as cl" in several tool package scripts. When I run the compiled binary version on my scripts, I see "pyopencl.init.py" being called multiple times.. (see diagram below)
I am wondering if it's the relative import of "tool as *", that screwing up the binary version. Note: This code does work as python script code.
#myscript -- "import tool as *"
└── tool
├── common.py ... #"import pyopencl as cl"
├── engine.py ... #"import pyopencl as cl"
├── traffic.py... #"import pyopencl as cl"
├── init.py
I found two issue with my conversion python scripts to binary
The python script import tool/tool.py was wrong, you can't have import script with the same name as the directory it's in.
In linux, there is a warning with threading when converting to binary..
https://docs.python.org/3/library/multiprocessing.html
Warning The 'spawn' and 'forkserver' start methods cannot currently be used with “frozen” executables (i.e., binaries produced by packages like PyInstaller and cx_Freeze) on Unix. The 'fork' start method does work
Related
I have a python file that I am trying to create an executable out of using Pyinstaller on my Mac. This python file imports several different python files. When I run the unix executable that was generated, I get this error:
File "main/__init__.py", line 4, in <module>
ModuleNotFoundError: No module named 'game'
Line 4 reads:
from game.scripts.gui import creator
The command I used to create the executable:
pyinstaller __init__.py --onefile --clean --windowed
The directory:
__init__.py
game
scripts
gui
creator.py
Any ideas on how I could fix this? Thanks
The subdirs are not included by creating an *.exe, so the creator.py is not found inside your *.exe. To avoid that, you have to include the extra files/folders by specifying them. This can be done by a *.spec file
By calling pyinstaller with your *.py file it will create a default *.spec file which you can edit and use next time to create your *.exe. Every option you used when calling
pyinstaller __init__.py --onefile --clean --windowed
is configured here so calling
pyinstaller *.spec
the next time gives the same result.
Edit this in your spec-file to fit your needs by copying single files or even whole folders including their content into the *.exe:
a = Analysis(['your.py'],
pathex=['.'],
binaries=[],
datas=[('some.dll', '.'),
('configurationfile.ini', '.'),
('data.xlsx', '.'),
('../../anotherfile.pdf', '.')
],
....some lines cut ....
a.datas += Tree('./thisfoldershouldbecopied', prefix='foldernameinexe')
More infos to that are found in the docs of pyinstaller regarding spec-files and including data files
https://pyinstaller.readthedocs.io/en/stable/spec-files.html
and for example in this post here:
Pyinstaller adding data files
Which paths are added to sys.path when the command is run, what are the factors that affect it?
My Python version is 3.6.4, and I also tried it on version 3.7.
Directory structure is
.
├── __init__.py
└── src
├── a.py
└── b.py
code is
# a.py
class A: pass
# b.py
from sys
print(sys.path)
from src.a import A
a = A()
print(a)
I tried to run python3 src/b.py on two machines with the same Python version. One of them did not report an error and the other error occurred.
In the correct running result, there are two directories in sys.path, one is the current directory and the other is the src directory;
The correct output is:
['/home/work/test/testimport/src', '/home/work/test/testimport',...]
<src.a.A object at 0x7f8b71535ac8>
The wrong result is:
['/home/work/test/testimport/src', ...]
Traceback (most recent call last):
File "src/b.py", line 3, in <module>
from src.a import A
ModuleNotFoundError: No module named 'src'
sys.path contains only the src directory.
Which path will be appended to sys.path when i run python3 src/b.py?
src is indeed not a module (does not contain __init__.py) and it does not matter if it is in your path or not. In addition, b.py "sees" the directory it is in (src) anyway, so
from a import A
would work no matter where are you executing B from (python3 /path/to/src/b.py) should work. Note even if you did create
`src/__init__.py`
your b.py would fail if you did not add the directory src to your path (or PYTHONPATH, which is the recommended way to add python modules to your path).
So, the title basically covers my question. I've created a project using virtualenv, e.g. I have to
source ./env/bin/activate
to run my script.
When I try creating an executable using:
pyinstaller --onefile <myscript.py>
None of the virtualenv packages are included; just the ones that are installed globally. I have a requirements.txt file that contains all of the modules I need. Is there a way to have pyinstaller point to that for the needed modules, or is there another way?
As Valentino pointed out by looking at How can I create the minimum size executable with pyinstaller?
You have to run PyIntaller from inside the virtual environment:
(venv_test) D:\testenv>pyinstaller
How to solve the not importing modules from the virtual environment
The virtual environment saves modules in a different directory than the global module directory. If you are using Windows like me, you can find the modules directory here:
C:\Users\<your username>\.virtualenvs\<your project name>\Lib\site-packages
When you find your virtualenv directory, run this command instead of this simple command(pyinstaller <script>.py):
pyinstaller --paths "C:\Users\<your username>\.virtualenvs\<your project name>\Lib\site-packages" --hidden-import <module name that should be import> <your script name>.py
To export just one file you can add this: -F or --onefile
As many modules as you can add to be imported by adding more --hidden-import flags and module name
Flag description
--paths: The pyinstaller will search for imports here
--hidden-import: Which modules should be imported by pyinstaller from the path
im trying to use py2exe (0.9.2.0) to convert a python script into an executable.
I've failed so far because py2exe does not find the module Qt:
C:\Users\Tobias\eclipse\workspace\pydevTest>python setup.py py2exe
running py2exe
5 missing Modules
------------------
? Qt imported from __SCRIPT__
? WizardPage imported from __SCRIPT__
? readline imported from cmd, code, pdb
? win32api imported from platform
? win32con imported from platform
Building 'dist\Test.exe'.
Building shared code archive 'dist\library.zip'.
Copy c:\windows\system32\python34.dll to dist
Copy C:\Python34\DLLs\_hashlib.pyd to dist\_hashlib.pyd
Copy C:\Python34\lib\site-packages\PyQt5\QtGui.pyd to dist\PyQt5.QtGui.pyd
Copy C:\Python34\lib\site-packages\PyQt5\QtCore.pyd to dist\PyQt5.QtCore.pyd
Copy C:\Python34\DLLs\unicodedata.pyd to dist\unicodedata.pyd
Copy C:\Python34\DLLs\_ssl.pyd to dist\_ssl.pyd
Copy C:\Python34\DLLs\_elementtree.pyd to dist\_elementtree.pyd
Copy C:\Python34\DLLs\select.pyd to dist\select.pyd
Copy C:\Python34\lib\site-packages\sip.pyd to dist\sip.pyd
Copy C:\Python34\lib\site-packages\PyQt5\QtWidgets.pyd to dist\PyQt5.QtWidgets.pyd
Copy C:\Python34\DLLs\pyexpat.pyd to dist\pyexpat.pyd
Copy C:\Python34\DLLs\_lzma.pyd to dist\_lzma.pyd
Copy C:\Python34\DLLs\_socket.pyd to dist\_socket.pyd
Copy C:\Python34\DLLs\_bz2.pyd to dist\_bz2.pyd
Copy C:\Python34\DLLs\_ctypes.pyd to dist\_ctypes.pyd
Copy DLL C:\Python34\lib\site-packages\PyQt5\Qt5Core.dll to dist\
Copy DLL C:\Python34\lib\site-packages\PyQt5\icudt53.dll to dist\
Copy DLL C:\Python34\lib\site-packages\PyQt5\icuuc53.dll to dist\
Copy DLL C:\Python34\lib\site-packages\PyQt5\icuin53.dll to dist\
Copy DLL C:\Python34\lib\site-packages\PyQt5\Qt5Gui.dll to dist\
Copy DLL C:\Python34\lib\site-packages\PyQt5\Qt5Widgets.dll to dist\
My setup.py looks as follows:
import py2exe
from distutils.core import setup
setup(windows=["./src/Test.py"], options={"py2exe" : {"includes" : ["sip", "PyQt5.QtGui","PyQt5.QtWidgets","PyQt5.QtCore","PyQt5.QtCore"]}})
The script is rather simple. After getting rid of the first error, I might also help with the four other missing modules...
Thanks a lot!
you need to add the following dlls:
C:\Windows\SYSTEM32\msvcp100.dll
C:\Windows\SYSTEM32\msvcr100.dll
C:\Python34\Lib\site-packages\PyQt4\plugins\platforms\qwindows.dll
somethings like this:
data_files = (
('', glob(r'C:\Windows\SYSTEM32\msvcp100.dll')),
('', glob(r'C:\Windows\SYSTEM32\msvcr100.dll')),
('platforms', glob(r'C:\Python34\Lib\site-packages\PyQt4\plugins\platforms\qwindows.dll')),
),
Sorry, the previous answer did not work for me: https://stackoverflow.com/a/37622355/7426109
(and I have different versions)
What did work on the other hand is to add this to your path: "C:\Program Files (x86)\Python38-32\Lib\site-packages\PyQt5\Qt\bin".
My temporary fix:
You copy the "Qt" ("C:\Program Files (x86)\Python38-32\Lib\site-packages\PyQt5\Qt") folder to "dist", and use a batch script to add ".dist\Qt\bin" to PATH in the current CMD window. (of course, this is not perfect, but at least can be executed on another machine)
Info
Windows 10 x64, Python 3.8.6 x32, PyQt5==5.15.1, py2exe==0.10.0.2
I'm new to jython and failing utterly at importing a java class within a jar.
What I am trying to do is write a wrapper shell script which calls a jython script. I can not allowed to edit the jython at all, so adding jars to sys.path within that jython script is not possible.
Error
y", line 17, in
from com.polarland.testModule.cache import CacheInterface
ImportError: No module named polarland
I've added the jar which contains the above package with name of TestModule.jar to PATH, ClASSPATH and JYTHONPATH with no avail. I'm worried this is due to the name of the jar but am not sure.
Any advice would be greatly appreciated!!
In your shell script use:
export CLASSPATH=TestModule.jar:$CLASSPATH
jython ...
In my case setting CLASSPATH is enough. Remember to use full path name and remember to use good .jar name (testmodule.jar and TestModul.jar are different). Maybe you use wrong file rights. Try file command to check if you can read that file. Example for one of jars I use:
mn$ file junit-4.1.jar
junit-4.1.jar: Zip archive data, at least v2.0 to extract
I was getting same issue.
I tried below function and worked well!
>>> import sys
>>> sys.path.append('/path/to/helloworld.jar')
>>> from com.leosoto import HelloWorld
For more info:
http://blog.leosoto.com/2008/07/jython-import-logic.html