The information above covers most normal uses of PyInstaller.
However, the variations of Python and third-party libraries are
endless and unpredictable.
It may happen that when you attempt to bundle your app either
PyInstaller itself, or your bundled app, terminates with a Python traceback.
Then please consider the following actions in sequence, before
asking for technical help.
Recipes and Examples for Specific Problems¶
The PyInstaller FAQ page has work-arounds for some common problems.
Code examples for some advanced uses and some common
problems are available on our PyInstaller Recipes page.
Some of the recipes there include:
-
A more sophisticated way of collecting data files
than the one shown above (Adding Files to the Bundle). -
Bundling a typical Django app.
-
A use of a run-time hook to set the PyQt5 API level.
-
A workaround for a multiprocessing constraint under Windows.
and others.
Many of these Recipes were contributed by users.
Please feel free to contribute more recipes!
Finding out What Went Wrong¶
Build-time Messages¶
When the Analysis
step runs, it produces error and warning messages.
These display after the command line if the --log-level
option allows it.
Analysis also puts messages in a warnings file
named build/name/warn-name.txt
in the
work-path=
directory.
Analysis creates a message when it detects an import
and the module it names cannot be found.
A message may also be produced when a class or function is declared in
a package (an __init__.py
module), and the import specifies
package.name
. In this case, the analysis can’t tell if name is supposed to
refer to a submodule or package.
The “module not found” messages are not classed as errors because
typically there are many of them.
For example, many standard modules
conditionally import modules for different platforms that may or may
not be present.
All “module not found” messages are written to the
build/name/warn-name.txt
file.
They are not displayed to standard output because there are many of them.
Examine the warning file; often there will be dozens of modules not found,
but their absence has no effect.
When you run the bundled app and it terminates with an ImportError,
that is the time to examine the warning file.
Then see Helping PyInstaller Find Modules below for how to proceed.
Build-Time Dependency Graph¶
On each run PyInstaller writes a cross-referencing file about dependencies
into the build folder:
build/name/xref-name.html
in the
work-path=
directory is an HTML file that lists the full
contents of the import graph, showing which modules are imported
by which ones.
You can open it in any web browser.
Find a module name, then keep clicking the “imported by” links
until you find the top-level import that causes that module to be included.
If you specify --log-level=DEBUG
to the pyinstaller
command,
PyInstaller additionally generates a GraphViz input file representing the
dependency graph.
The file is build/name/graph-name.dot
in the
work-path=
directory.
You can process it with any GraphViz command, e.g. dot,
to produce
a graphical display of the import dependencies.
These files are very large because even the simplest “hello world”
Python program ends up including a large number of standard modules.
For this reason the graph file is not very useful in this release.
Build-Time Python Errors¶
PyInstaller sometimes terminates by raising a Python exception.
In most cases the reason is clear from the exception message,
for example “Your system is not supported”, or “Pyinstaller
requires at least Python 3.7”.
Others clearly indicate a bug that should be reported.
One of these errors can be puzzling, however:
IOError("Python library not found!")
PyInstaller needs to bundle the Python library, which is the
main part of the Python interpreter, linked as a dynamic load library.
The name and location of this file varies depending on the platform in use.
Some Python installations do not include a dynamic Python library
by default (a static-linked one may be present but cannot be used).
You may need to install a development package of some kind.
Or, the library may exist but is not in a folder where PyInstaller
is searching.
The places where PyInstaller looks for the python library are
different in different operating systems, but /lib
and /usr/lib
are checked in most systems.
If you cannot put the python library there,
try setting the correct path in the environment variable
LD_LIBRARY_PATH
in GNU/Linux or
DYLD_LIBRARY_PATH
in macOS.
Getting Debug Messages¶
The --debug=all
option (and its choices) provides a significant amount of diagnostic information.
This can be useful during development of a complex package,
or when your app doesn’t seem to be starting,
or just to learn how the runtime works.
Normally the debug progress messages go to standard output.
If the --windowed
option is used when bundling a Windows app,
they are sent to any attached debugger. If you are not using a debugger
(or don’t have one), the DebugView the free (beer) tool can be used to
display such messages. It has to be started before running the bundled
application.
For a --windowed
macOS app they are not displayed.
Consider bundling without --debug
for your production version.
Debugging messages require system calls and have an impact on performance.
Getting Python’s Verbose Imports¶
You can build the app with the --debug=imports
option
(see Getting Debug Messages above),
which will pass the -v
(verbose imports) flag
to the embedded Python interpreter.
This can be extremely useful.
It can be informative even with apps that are apparently working,
to make sure that they are getting all imports from the bundle,
and not leaking out to the local installed Python.
Python verbose and warning messages always go to standard output
and are not visible when the --windowed
option is used.
Remember to not use this for your production version.
Figuring Out Why Your GUI Application Won’t Start¶
If you are using the --windowed
option,
your bundled application may fail to start with an error message like
Failed to execute script my_gui
.
In this case, you will want to get more verbose output to find out
what is going on.
-
For macOS, you can run your application on the command line,
i.e../dist/my_gui
in Terminal instead of clicking onmy_gui.app
. -
For Windows, you will need to re-bundle your application without the
--windowed
option.
Then you can run the resulting executable from the command line,
i.e.my_gui.exe
. -
For Unix and GNU/Linux there in no
--windowed
option.
Anyway, if a your GUI application fails,
you can run your application on the command line,
i.e../dist/my_gui
.
This should give you the relevant error that is preventing your
application from initializing, and you can then move on to other
debugging steps.
Operation not permitted error¶
If you use the –onefile and it fails to run you program with error like:
./hello: error while loading shared libraries: libz.so.1: failed to map segment from shared object: Operation not permitted
This can be caused by wrong permissions for the /tmp directory
(e.g. the filesystem is mounted with noexec
flags).
A simple way to solve this issue is to set,
in the environment variable TMPDIR,
a path to a directory in a filesystem mounted without noexec
flags, e.g.:
Helping PyInstaller Find Modules¶
Extending the Path¶
If Analysis recognizes that a module is needed, but cannot find that module,
it is often because the script is manipulating sys.path
.
The easiest thing to do in this case is to use the --paths
option
to list all the other places that the script might be searching for imports:
pyi-makespec --paths=/path/to/thisdir --paths=/path/to/otherdir myscript.py
These paths will be noted in the spec file in the pathex
argument.
They will be added to the current sys.path
during analysis.
Extending a Package’s __path__
¶
Python allows a script to extend the search path used for imports
through the __path__
mechanism.
Normally, the __path__
of an imported module has only one entry,
the directory in which the __init__.py
was found.
But __init__.py
is free to extend its __path__
to include other directories.
For example, the win32com.shell.shell
module actually resolves to
win32com/win32comext/shell/shell.pyd
.
This is because win32com/__init__.py
appends ../win32comext
to its __path__
.
Because the __init__.py
of an imported module
is not actually executed during analysis,
changes it makes to __path__
are not seen by PyInstaller.
We fix the problem with the same hook mechanism we use for hidden imports,
with some additional logic; see Understanding PyInstaller Hooks below.
Note that manipulations of __path__
hooked in this way apply only
to the Analysis.
At runtime all imports are intercepted and satisfied from within the
bundle. win32com.shell
is resolved the same
way as win32com.anythingelse
, and win32com.__path__
knows nothing of ../win32comext
.
Once in a while, that’s not enough.
Changing Runtime Behavior¶
More bizarre situations can be accommodated with runtime hooks.
These are small scripts that manipulate the environment before your main script runs,
effectively providing additional top-level code to your script.
There are two ways of providing runtime hooks.
You can name them with the option --runtime-hook
=path-to-script.
Second, some runtime hooks are provided.
At the end of an analysis,
the names in the module list produced by the Analysis phase are looked up in
loader/rthooks.dat
in the PyInstaller install folder.
This text file is the string representation of a
Python dictionary. The key is the module name, and the value is a list
of hook-script pathnames.
If there is a match, those scripts are included in the bundled app
and will be called before your main script starts.
Hooks you name with the option are executed
in the order given, and before any installed runtime hooks.
If you specify --runtime-hook=file1.py --runtime-hook=file2.py
then the execution order at runtime will be:
-
Code of
file1.py
. -
Code of
file2.py
. -
Any hook specified for an included module that is found
inrthooks/rthooks.dat
. -
Your main script.
Hooks called in this way, while they need to be careful of what they import,
are free to do almost anything.
One reason to write a run-time hook is to
override some functions or variables from some modules.
A good example of this is the Django runtime
hook (see loader/rthooks/pyi_rth_django.py
in the
PyInstaller folder).
Django imports some modules dynamically and it is looking
for some .py
files.
However .py
files are not available in the one-file bundle.
We need to override the function
django.core.management.find_commands
in a way that will just return a list of values.
The runtime hook does this as follows:
import django.core.management def _find_commands(_): return """cleanup shell runfcgi runserver""".split() django.core.management.find_commands = _find_commands
Getting the Latest Version¶
If you have some reason to think you have found a bug in PyInstaller
you can try downloading the latest development version.
This version might have fixes or features that are not yet at PyPI.
You can download the latest stable version and the latest development
version from the PyInstaller Downloads page.
You can also install the latest version of PyInstaller directly
using pip:
pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip
Asking for Help¶
When none of the above suggestions help,
do ask for assistance on the PyInstaller Email List.
Then, if you think it likely that you see a bug in PyInstaller,
refer to the How to Report Bugs page.
Когда я пытаюсь скомпилировать код, у меня выходит вот такая ошибка:
110 INFO: PyInstaller: 3.4
110 INFO: Python: 3.5.2
110 INFO: Platform: Windows-7-6.1.7601-SP1
112 INFO: wrote C:UsersSheihDesktopprogrammerSvoeChangeDataDateChangeData
Date.spec
113 INFO: UPX is not available.
115 INFO: Extending PYTHONPATH with paths
['C:\Users\Sheih\Desktop\programmer\Svoe\ChangeDataDate',
'C:\Users\Sheih\Desktop\programmer\Svoe\ChangeDataDate']
116 INFO: checking Analysis
116 INFO: Building Analysis because Analysis-00.toc is non existent
116 INFO: Initializing module dependency graph...
119 INFO: Initializing module graph hooks...
121 INFO: Analyzing base_library.zip ...
5075 INFO: running Analysis Analysis-00.toc
5568 INFO: Caching module hooks...
5577 INFO: Analyzing C:UsersSheihDesktopprogrammerSvoeChangeDataDateChang
eDataDate.py
5605 INFO: Loading module hooks...
5605 INFO: Loading module hook "hook-PyQt5.py"...
5715 WARNING: Cannot read QLibraryInfo output: raised Expecting value: line 1 co
lumn 1 (char 0) when decoding:
Traceback (most recent call last):
File "<string>", line 11, in <module>
TypeError: __call__() got an unexpected keyword argument 'qualname'
Traceback (most recent call last):
File "c:python35librunpy.py", line 184, in _run_module_as_main
"__main__", mod_spec)
File "c:python35librunpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:Python35Scriptspyinstaller.exe__main__.py", line 9, in <module>
File "c:python35libsite-packagesPyInstaller__main__.py", line 111, in run
run_build(pyi_config, spec_file, **vars(args))
File "c:python35libsite-packagesPyInstaller__main__.py", line 63, in run_
build
PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
File "c:python35libsite-packagesPyInstallerbuildingbuild_main.py", line
838, in main
build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'
))
File "c:python35libsite-packagesPyInstallerbuildingbuild_main.py", line
784, in build
exec(text, spec_namespace)
File "<string>", line 17, in <module>
File "c:python35libsite-packagesPyInstallerbuildingbuild_main.py", line
241, in __init__
self.__postinit__()
File "c:python35libsite-packagesPyInstallerbuildingdatastruct.py", line
158, in __postinit__
self.assemble()
File "c:python35libsite-packagesPyInstallerbuildingbuild_main.py", line
500, in assemble
module_hook.post_graph()
File "c:python35libsite-packagesPyInstallerbuildingimphook.py", line 410
, in post_graph
self._load_hook_module()
File "c:python35libsite-packagesPyInstallerbuildingimphook.py", line 377
, in _load_hook_module
self.hook_module_name, self.hook_filename)
File "c:python35libsite-packagesPyInstallercompat.py", line 736, in impor
tlib_load_source
return mod_loader.load_module()
File "<frozen importlib._bootstrap_external>", line 388, in _check_name_wrappe
r
File "<frozen importlib._bootstrap_external>", line 809, in load_module
File "<frozen importlib._bootstrap_external>", line 668, in load_module
File "<frozen importlib._bootstrap>", line 268, in _load_module_shim
File "<frozen importlib._bootstrap>", line 693, in _load
File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 665, in exec_module
File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
File "c:python35libsite-packagesPyInstallerhookshook-PyQt5.py", line 23,
in <module>
collect_system_data_files(pyqt5_library_info.location['PrefixPath'],
File "c:python35libsite-packagesPyInstallerutilshooksqt.py", line 67, i
n __getattr__
qli = json.loads(json_str)
File "c:python35libjson__init__.py", line 319, in loads
return _default_decoder.decode(s)
File "c:python35libjsondecoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "c:python35libjsondecoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Сам код:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import time, sys, os
class Folder(QWidget):
def __init__(self):
super().__init__()
self.setFixedSize(400, 225)
self.way = 0
self.calendar = QDateTimeEdit(self)
self.calendar.setGeometry(10, 10, 380, 35)
self.calendar.setDisplayFormat("dd.MM.yyyy | H:mm:ss")
btnOpen = QPushButton(self)
btnOpen.setText("Открыть папку")
btnOpen.setGeometry(10, 55, 380, 50)
btnOpen.clicked.connect(self.openFolder)
self.wayText = QLineEdit(self)
self.wayText.setGeometry(10, 115, 380, 40)
self.wayText.setReadOnly(True)
btnChange = QPushButton(self)
btnChange.setText("Изменить")
btnChange.setGeometry(10, 165, 380, 50)
btnChange.clicked.connect(self.change)
def change(self):
if self.way != "":
year = self.calendar.dateTime().toString("yyyy")
month = self.calendar.dateTime().toString("MM")
day = self.calendar.dateTime().toString("dd")
hour = self.calendar.dateTime().toString("hh")
minute = self.calendar.dateTime().toString("mm")
second = self.calendar.dateTime().toString("ss")
if year.startswith("0"):
year = year[1:]
if month.startswith("0"):
month = month[1:]
if day.startswith("0"):
day = day[1:]
if hour.startswith("0"):
hour = hour[1:]
if minute.startswith("0"):
minute = minute[1:]
if second.startswith("0"):
second = second[1:]
def openFolder(self):
fname = QFileDialog.getExistingDirectory(self, "Select directory")
self.way = fname
self.wayText.setText(fname)
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Folder()
ex.show()
sys.exit(app.exec_())
Ввожу для компиляции:
pyinstaller --onefile --icon=name.ico --noconsole myscript.py
Как это исправить?
125 INFO: PyInstaller: 3.5
126 INFO: Python: 3.7.4
126 INFO: Platform: Windows-8.1-6.3.9600-SP0
128 INFO: wrote C:UsersМаксимDesktopxxxapp.spec
140 INFO: UPX is not available.
141 INFO: Extending PYTHONPATH with paths
['C:\Users\Максим\Desktop', 'C:\Users\Максим\Desktop']
142 INFO: checking Analysis
142 INFO: Building Analysis because Analysis-00.toc is non existent
142 INFO: Initializing module dependency graph...
146 INFO: Initializing module graph hooks...
150 INFO: Analyzing base_library.zip ...
5315 INFO: running Analysis Analysis-00.toc
5318 INFO: Adding Microsoft.Windows.Common-Controls to dependent assemblies of final executable
required by d:program files (x86)python37-32python.exe
5687 INFO: Caching module hooks...
5698 INFO: Analyzing C:UsersМаксимDesktopxxxapp.py
6368 INFO: Processing pre-safe import module hook urllib3.packages.six.moves
9078 INFO: Processing pre-find module path hook distutils
11438 INFO: Processing pre-find module path hook site
11440 INFO: site: retargeting to fake-dir 'C:\Users\Максим\AppData\Roaming\Python\Python37\site-packages\PyInstaller\fake-modules'
13260 INFO: Processing pre-safe import module hook setuptools.extern.six.moves
17811 INFO: Loading module hooks...
17812 INFO: Loading module hook "hook-certifi.py"...
17820 INFO: Loading module hook "hook-distutils.py"...
17823 INFO: Loading module hook "hook-encodings.py"...
17960 INFO: Loading module hook "hook-lib2to3.py"...
17966 INFO: Loading module hook "hook-numpy.core.py"...
Traceback (most recent call last):
File "d:program files (x86)python37-32librunpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "d:program files (x86)python37-32librunpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:UsersМаксимAppDataRoamingPythonPython37Scriptspyinstaller.exe__main__.py", line 9, in <module>
File "C:UsersМаксимAppDataRoamingPythonPython37site-packagesPyInstaller__main__.py", line 111, in run
run_build(pyi_config, spec_file, **vars(args))
File "C:UsersМаксимAppDataRoamingPythonPython37site-packagesPyInstaller__main__.py", line 63, in run_build
PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
File "C:UsersМаксимAppDataRoamingPythonPython37site-packagesPyInstallerbuildingbuild_main.py", line 844, in main
build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
File "C:UsersМаксимAppDataRoamingPythonPython37site-packagesPyInstallerbuildingbuild_main.py", line 791, in build
exec(code, spec_namespace)
File "C:UsersМаксимDesktopxxxapp.spec", line 17, in <module>
noarchive=False)
File "C:UsersМаксимAppDataRoamingPythonPython37site-packagesPyInstallerbuildingbuild_main.py", line 243, in __init__
self.__postinit__()
File "C:UsersМаксимAppDataRoamingPythonPython37site-packagesPyInstallerbuildingdatastruct.py", line 158, in __postinit__
self.assemble()
File "C:UsersМаксимAppDataRoamingPythonPython37site-packagesPyInstallerbuildingbuild_main.py", line 502, in assemble
module_hook.post_graph()
File "C:UsersМаксимAppDataRoamingPythonPython37site-packagesPyInstallerbuildingimphook.py", line 410, in post_graph
self._load_hook_module()
File "C:UsersМаксимAppDataRoamingPythonPython37site-packagesPyInstallerbuildingimphook.py", line 377, in _load_hook_module
self.hook_module_name, self.hook_filename)
File "C:UsersМаксимAppDataRoamingPythonPython37site-packagesPyInstallercompat.py", line 793, in importlib_load_source
return mod_loader.load_module()
File "<frozen importlib._bootstrap_external>", line 407, in _check_name_wrapper
File "<frozen importlib._bootstrap_external>", line 907, in load_module
File "<frozen importlib._bootstrap_external>", line 732, in load_module
File "<frozen importlib._bootstrap>", line 265, in _load_module_shim
File "<frozen importlib._bootstrap>", line 696, in _load
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "C:UsersМаксимAppDataRoamingPythonPython37site-packagesPyInstallerhookshook-numpy.core.py", line 27, in <module>
pkg_base, pkg_dir = get_package_paths('numpy.core')
File "C:UsersМаксимAppDataRoamingPythonPython37site-packagesPyInstallerutilshooks__init__.py", line 535, in get_package_paths
file_attr = get_module_file_attribute(package)
File "C:UsersМаксимAppDataRoamingPythonPython37site-packagesPyInstallerutilshooks__init__.py", line 318, in get_module_file_attribute
loader = pkgutil.find_loader(package)
File "d:program files (x86)python37-32libpkgutil.py", line 493, in find_loader
spec = importlib.util.find_spec(fullname)
File "d:program files (x86)python37-32libimportlibutil.py", line 94, in find_spec
parent = __import__(parent_name, fromlist=['__path__'])
File "d:program files (x86)python37-32libsite-packagesnumpy__init__.py", line 142, in <module>
from . import core
File "d:program files (x86)python37-32libsite-packagesnumpycore__init__.py", line 23, in <module>
WinDLL(os.path.abspath(filename))
File "d:program files (x86)python37-32libctypes__init__.py", line 364, in __init__
self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 не является приложением Win32
Mediapipe library requires certain files to run (these are mainly TensorFlow files with .tflite
extension.)
Since these are loaded dynamically, PyInstaller doesn’t know about these and during the compilation phase you need to copy them over to the dist
directory.
This can be achieved via datas
property in PyInstaller spec file.
You can read more about it in the PyInstaller docs
Here is my spec file. See under datas
property and ensure that path is correct since directories under venv
are OS specific.
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['main.py'],
pathex=['.'],
binaries=[],
datas=[('venv\Lib\site-packages\mediapipe\modules', 'mediapipe\modules'),],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='main')
Pyinstaller is a really great library in Python, used to create an EXE for your Python code. However, it is quite error prone, and many people have run into alot of constant errors and problems while using Pyinstaller. This article was created for the purpose of addressing many of these commons problems and errors in Pyinstaller, and how to fix them.
Compiling an EXE is quite a complicated task, and even a slight misstep can ruin it. Furthermore, there are some actual problems with Pyinstaller itself that we need to discuss.
There are in total 5 different solutions that we have for resolving problems and errors in Pyinstaller. Ideally you should implement all 5 of these changes/solutions into your code and setup for an idea experience.
Using Auto-py-to-exe
Perhaps you have heard of Auto-py-to-exe before? It’s an alternative library that you can use to compile Python code into EXE’s. But here’s the fun part, it actually uses Pyinstaller in the backend to do everything! So what’s the point of this library then?
Well, it actually just does one thing. It provides you with a GUI interface through you can use Pyinstaller commands. It even generates a Pyinstaller command after you have picked which options you want. You can directly copy paste that command and use it like you would normally use Pyinstaller, or just click the Compile button on Auto-py-to-exe, which automatically does that for you.
Here’s a look at the GUI for auto-py-to-exe.
The reason why I’m suggesting this, is because it makes it much easier to use Pyinstaller and is actually less error-prone. It’s also faster to use and is generally considered to be more stable. All in all, a great option for anyone using Pyinstaller.
Developers version of Pyinstaller
Another big problem with Pyinstaller itself, is that there is an issue present with the default pyinstaller version that gets installed when you use “pip”. What you need to do, is run the two below commands in your terminal. This will remove the problem version, and install the developers version which does not have this issue.
pip uninstall pyinstaller
pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip
Relative File Paths, not Absolute
One mistake I see alot of people doing is hard-coding their file paths when including additional files and folders. That is a terrible mistake to make, because when distributing your exe to other people, there is a very small chance that the filepath will remain valid.
For example, in your code you used the following filepath to load in Image. (Where PythonProgram
is the name of the folder with the script + files)
Image.open("C:/Users/JohnSmith/PythonProgram/Images/image1.jpg")
Now you compiled this into an exe, and gave it to a friend of yours called “Hubbard”. Now Hubbard does not have a user called “John Smith” on his PC, so he is going to run into an error.
Instead we use relative paths. While Hubbard will not have a User called John smith, he will have the PythonProgram
Folder that you give him. So what you can do, is the use the following filepath.
Image.open("/Images/image.jpg")
This removes the need to specify the full file path, and keep it relative. This will ensure it runs on any computer, and in any directory, as long as the contents of the PythonProgram
folder remain the same.
Generate Correct Path when using OneFile
When using the --onefile
option in pyinstaller, there is a slight problem that can occur when including additional files. The correct file is not generated, which results in the additional file you included, not being found.
To resolve this, add the following function to your code, and use it whenever you are using a filepath in your code.
def resource_path(relative_path): """ Get absolute path to resource, works for dev and for PyInstaller """ try: # PyInstaller creates a temp folder and stores path in _MEIPASS base_path = sys._MEIPASS except Exception: base_path = os.path.abspath(".") return os.path.join(base_path, relative_path)
For example, I want to load an image here, so I will pass it through the above function first.
img = Image.open(resource_path("M_Cat_Loaf.jpeg"))
This generates a proper path, that will not cause any errors with Pyinstaller.
Using the OneFile Option
If nothing is working out for you, you can try using the OneFile option instead. Many people have reported this option to work, where as the OneDir option didn’t. So it’s definitely worth trying.
If you are using Auto-py-to-Exe, just click on the OneFile option. Otherwise include the following option in the Pyinstaller command, --onefile
, when you run it in the terminal.
For example:
pyinstaller --onefile pythonfile.py
This marks the end of the “Solving Common Problems and Errors in Pyinstaller” Tutorial. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the tutorial content can be asked in the comments section below.