How can I partly compile a python file? - linux

How can I compile a python file exclude a certain module?
Let's see a example:
there is def b() in b.py called in main.py, how can I just compile main.py, because I need to modify def b() in b.py afterward. Or can I compile them separately?
I am using pyinstaller now, but I can change to other compile tools if it can implement this.
Thanks

It's a bad idea to do this: pyinstaller is meant for packaging and distribution, not for development. Packaged file aren't meant to be changed. If part of the program is modified, you should release a new version of the whole package. If you would like to do runtime configuration, then you should use a configuration file, rather than changing the program.
However, if you insist on doing it, you could use the --exclude-module flag. Run
pyinstaller --exclude-module b main.py
so that b is not bundled with main. If you try to run the bundled package now, a ModuleNotFoundError: No module named 'b' would show. Copy b.py to the directory (dist/main), run main, and everything would work again. Now you could change b.py, and the difference would show during the execution.

For single .exe file output for .py file :
python -m pip install pyinstaller
pyinstaller -D -F --debug [.py file path]

Related

I cannot run pyinstaller on my computer even though I have installed it

This is the problem right here, do you have any advice for that?
installed pip and pyinstaller, but still got this error message when I tried to convert my project into an .exe.
From Pyinstaller installation guide:
If you cannot use the pyinstaller command due to the scripts directory not being in PATH, you can instead invoke the PyInstaller module, by running python -m PyInstaller (pay attention to the module name, which is case sensitive). This form of invocation is also useful when you have PyInstaller installed in multiple python environments, and you cannot be sure from which installation the pyinstaller command will be ran.
So you may run it as e.g.:
python -m PyInstaller some_system.py
Or, as the issue seems that PATH Windows environment variable doesn't include Python's Script folder, it'd better to fix it. From the same guide:
If the command is not found, make sure the execution path includes the proper directory:
Windows: C:\PythonXY\Scripts where XY stands for the major and minor Python version number, for example C:\Python38\Scripts for Python 3.8)
To fix you may run where python to get exact location of Python on your machine (let's say it shows C:\Python38\). Then add to PATH env variable Scripts folder inside it (in this example it'd be C:\Python38\Scripts\)

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.

f2py does not properly import, despite successfully compiling

I am successfully compiling my Fortran subroutine with f2py. However, a folder is created as well as a pyd file.
If I do not put the created pyd file in the generated folder I get this error
ImportError: DLL load failed: The specified module could not be found.
If I put the generated .pyd file in the generated folder, my python script will run, and the import seems to work. However, if I run print(energy_f2py.__doc__) None is the output, and when I try to use the subroutine I get an error AttributeError: module 'energy_f2py' has no attribute 'potential_3'
potential_3 is the name of the subroutine inside energy_f2py.f90
I have also tried making energy_f2py.f90 a module containing the subroutine, with no difference in results.
This is the pyd file that is generated energy_f2py.cp36-win_amd64.pyd. I am using the commandline in Pycharm (windows 10 64 bit) to compile the Fortran file using
f2py -c -m energy_f2py energy_f2py.f90
python -m numpy.f2py -c -m energy_f2py energy_f2py.f90
The same thing happens.
It seems weird to me that both the pyd file is created as well as a folder, see the below image
I am stuck at this point... it seems like it is 95% of the way to working...
Lastly, this other post had a solution saying to name the Python and Fortran modules different names. I have tried this, and it did not make a difference either.
The best solution I found which worked was to partition my hardrive and install Linux. I chose to use Lubuntu, but you could use anything.
Everything works as it should on Linux.
Anther option to is to make it a static build, with the -static flag. This builds everything needed into a single file:
python -m numpy.f2py -c -m energy_f2py energy_f2py.f90 -static
You should then be able to use that .pyd file no matter what folder you've placed it in.
If you are using windows, I think adding --compiler=mingw32 may help. The defualt compiler is msvc on windows.
It occurs to me that the resulting .pyd module is looking for the DLL library in the same directory it itself resides in. Therefore, try moving the DLL from .libs directory to energy_f2py - it worked for me on Windows 10.

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.

Allow my friends to run my python script? [duplicate]

This question already has answers here:
Create a single executable from a Python project [closed]
(3 answers)
Closed 1 year ago.
I'm building a Python application and don't want to force my clients to install Python and modules.
So, is there a way to compile a Python script to be a standalone executable?
You can use PyInstaller to package Python programs as standalone executables. It works on Windows, Linux, and Mac.
PyInstaller Quickstart
Install PyInstaller from PyPI:
pip install pyinstaller
Go to your program’s directory and run:
pyinstaller yourprogram.py
This will generate the bundle in a subdirectory called dist.
pyinstaller -F yourprogram.py
Adding -F (or --onefile) parameter will pack everything into single "exe".
pyinstaller -F --paths=<your_path>\Lib\site-packages yourprogram.py
running into "ImportError" you might consider side-packages.
pip install pynput==1.6.8
still runing in Import-Erorr - try to downgrade pyinstaller - see Getting error when using pynput with pyinstaller
For a more detailed walkthrough, see the manual.
You can use py2exe as already answered and use Cython to convert your key .py files in .pyc, C compiled files, like .dll in Windows and .so on Linux.
It is much harder to revert than common .pyo and .pyc files (and also gain in performance!).
You might wish to investigate Nuitka. It takes Python source code and converts it in to C++ API calls. Then it compiles into an executable binary (ELF on Linux). It has been around for a few years now and supports a wide range of Python versions.
You will probably also get a performance improvement if you use it. It is recommended.
Yes, it is possible to compile Python scripts into standalone executables.
PyInstaller can be used to convert Python programs into stand-alone executables, under Windows, Linux, Mac OS X, FreeBSD, Solaris, and AIX. It is one of the recommended converters.
py2exe converts Python scripts into only executable on the Windows platform.
Cython is a static compiler for both the Python programming language and the extended Cython programming language.
I would like to compile some useful information about creating standalone files on Windows using Python 2.7.
I have used py2exe and it works, but I had some problems.
It has shown some problems for creating single files in Windows 64 bits: Using bundle_files = 1 with py2exe is not working;
It is necessary to create a setup.py file for it to work. http://www.py2exe.org/index.cgi/Tutorial#Step2;
I have had problems with dependencies that you have to solve by importing packages in the setup file;
I was not able to make it work together with PyQt.
This last reason made me try PyInstaller http://www.pyinstaller.org/.
In my opinion, it is much better because:
It is easier to use.
I suggest creating a .bat file with the following lines for example (pyinstaller.exe must be in in the Windows path):
pyinstaller.exe --onefile MyCode.py
You can create a single file, among other options (https://pyinstaller.readthedocs.io/en/stable/usage.html#options).
I had only one problem using PyInstaller and multiprocessing package that was solved by using this recipe: https://github.com/pyinstaller/pyinstaller/wiki/Recipe-Multiprocessing.
So, I think that, at least for python 2.7, a better and simpler option is PyInstaller.
And a third option is cx_Freeze, which is cross-platform.
pyinstaller yourfile.py -F --onefile
This creates a standalone EXE file on Windows.
Important note 1: The EXE file will be generated in a folder named 'dist'.
Important note 2: Do not forget --onefile flag
You can install PyInstaller using pip install PyInstaller
NOTE: In rare cases there are hidden dependencies...so if you run the EXE file and get missing library error (win32timezone in the example below) then use something like this:
pyinstaller --hiddenimport win32timezone -F "Backup Program.py"
I like PyInstaller - especially the "windowed" variant:
pyinstaller --onefile --windowed myscript.py
It will create one single *.exe file in a distination/folder.
You may like py2exe. You'll also find information in there for doing it on Linux.
Use py2exe.... use the below set up files:
from distutils.core import setup
import py2exe
from distutils.filelist import findall
import matplotlib
setup(
console = ['PlotMemInfo.py'],
options = {
'py2exe': {
'packages': ['matplotlib'],
'dll_excludes': ['libgdk-win32-2.0-0.dll',
'libgobject-2.0-0.dll',
'libgdk_pixbuf-2.0-0.dll']
}
},
data_files = matplotlib.get_py2exe_datafiles()
)
I also recommend PyInstaller for better backward compatibility such as Python 2.3 - 2.7.
For py2exe, you have to have Python 2.6.
For Python 3.2 scripts, the only choice is cx_Freeze. Build it from sources; otherwise it won't work.
For Python 2.x I suggest PyInstaller as it can package a Python program in a single executable, unlike cx_Freeze which outputs also libraries.
Since it seems to be missing from the current list of answers, I think it is worth mentioning that the standard library includes a zipapp module that can be used for this purpose. Its basic usage is just compressing a bunch of Python files into a zip file with extension .pyz than can be directly executed as python myapp.pyz, but you can also make a self-contained package from a requirements.txt file:
$ python -m pip install -r requirements.txt --target myapp
$ python -m zipapp -p "interpreter" myapp
Where interpreter can be something like /usr/bin/env python (see Specifying the Interpreter).
Usually, the generated .pyz / .pyzw file should be executable, in Unix because it gets marked as such and in Windows because Python installation usually registers those extensions. However, it is relatively easy to make a Windows executable that should work as long as the user has python3.dll in the path.
If you don't want to require the end user to install Python, you can distribute the application along with the embeddable Python package.
py2exe will make the EXE file you want, but you need to have the same version of MSVCR90.dll on the machine you're going to use your new EXE file.
See Tutorial for more information.
You can find the list of distribution utilities listed at Distribution Utilities.
I use bbfreeze and it has been working very well (yet to have Python 3 support though).
Not exactly a packaging of the Python code, but there is now also Grumpy from Google, which transpiles the code to Go.
It doesn't support the Python C API, so it may not work for all projects.
Using PyInstaller, I found a better method using shortcut to the .exe rather than making --onefile. Anyway, there are probably some data files around and if you're running a site-based app then your program depends on HTML, JavaScript, and CSS files too. There isn't any point in moving all these files somewhere... Instead what if we move the working path up?
Make a shortcut to the EXE file, move it at top and set the target and start-in paths as specified, to have relative paths going to dist\folder:
Target: %windir%\system32\cmd.exe /c start dist\web_wrapper\web_wrapper.exe
Start in: "%windir%\system32\cmd.exe /c start dist\web_wrapper\"
We can rename the shortcut to anything, so renaming to "GTFS-Manager".
Now when I double-click the shortcut, it's as if I python-ran the file! I found this approach better than the --onefile one as:
In onefile's case, there's a problem with a .dll missing for the Windows 7 OS which needs some prior installation, etc. Yawn. With the usual build with multiple files, no such issues.
All the files that my Python script uses (it's deploying a tornado web server and needs a whole freakin' website worth of files to be there!) don't need to be moved anywhere: I simply create the shortcut at top.
I can actually use this exact same folder on Ubuntu (run python3 myfile.py) and Windows (double-click the shortcut).
I don't need to bother with the overly complicated hacking of .spec file to include data files, etc.
Oh, remember to delete off the build folder after building. It will save on size.
Use Cython to convert to C, compile, and link with GCC.
Another could be, make the core functions in C (the ones you want to make hard to reverse), compile them and use Boost.Python to import the compiled code (plus you get a much faster code execution). Then use any tool mentioned to distribute.
I'm told that PyRun is also an option. It currently supports Linux, FreeBSD and Mac OS X.

Resources