Skip to content

Commit

Permalink
Assorted environment checks. (#6361)
Browse files Browse the repository at this point in the history
* Windows: Catch/re-raise failure to load win32ctypes under -OO.

  PyInstaller can no longer run under Python's optimised mode due to the
  dependency chain PyInstaller -> win32ctypes -> cffi -> pycparser which
  has started using/ Yacc which interprets grammars from docstrings.

* Docs: Remove running with optimisations section (#6345).

  Running with -OO no longer works on Windows, makes such an insignificant
  difference to the overall output size and as generally agreed to be more trouble
  than it's worth.

* Linux: Explicitly check that binutils tools are available.

  This should catch issues like:
  #6358 (comment)

* Abort build if any obsolete stdlib backports are installed.

  Most prominently, check for `enum34` - the backport of `enum` - which masks the
  stdlib variant causing  issues like #5728.

Co-authored-by: Jasper Harrison <legorooj@protonmail.com>
  • Loading branch information
bwoodsend and Legorooj committed Nov 10, 2021
1 parent f2fbcb8 commit f0f63da
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 43 deletions.
36 changes: 36 additions & 0 deletions PyInstaller/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import site
import subprocess
import sys
import shutil

from PyInstaller._shared_with_waf import _pyi_machine
from PyInstaller.exceptions import ExecCommandFailed
Expand Down Expand Up @@ -206,6 +207,14 @@
'Please install pywin32-ctypes.\n\n'
'pip install pywin32-ctypes\n'
)
except Exception:
if sys.flags.optimize == 2:
raise SystemExit(
"pycparser, a Windows only indirect dependency of PyInstaller, is incompatible with "
"Python's \"discard docstrings\" (-OO) flag mode. For more information see:\n"
" https://github.com/pyinstaller/pyinstaller/issues/6345"
)
raise

# macOS's platform.architecture() can be buggy, so we do this manually here. Based off the python documentation:
# https://docs.python.org/3/library/platform.html#platform.architecture
Expand Down Expand Up @@ -731,3 +740,30 @@ def check_requirements():
# Fail hard if Python does not have minimum required version
if sys.version_info < (3, 6):
raise EnvironmentError('PyInstaller requires at Python 3.6 or newer.')

# There are some old packages which used to be backports of libraries which are now part of the standard library.
# These backports are now unmaintained and contain only an older subset of features leading to obscure errors like
# "enum has not attribute IntFlag" if installed.
if is_py38:
from importlib.metadata import distribution, PackageNotFoundError
else:
from importlib_metadata import distribution, PackageNotFoundError

for name in ["enum34", "typing"]:
try:
distribution(name)
except PackageNotFoundError:
pass
else:
raise SystemExit(
f"The '{name}' package is an obsolete backport of a standard library package and is "
f"incompatible with PyInstaller. Please "
f"`{'conda remove' if is_conda else 'pip uninstall'} {name}` then try again."
)

# Bail out if binutils is not installed.
if is_linux and shutil.which("objdump") is None:
raise SystemExit(
"On Linux, objdump is required. It is typically provided by the 'binutils' package "
"installable via your Linux distribution's package manager."
)
43 changes: 0 additions & 43 deletions doc/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -120,49 +120,6 @@ Is equivalent to:
pyinstaller my_script.py --onefile --windowed
Running |PyInstaller| with Python optimizations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. Note::

When using this feature, you should be aware of how the Python bytecode
optimization mechanism works. When using ``-O``, ``__debug__`` is set
to ``False`` and ``assert`` statements are removed from the bytecode.
The ``-OO`` flag additionally removes docstrings.

Using this feature affects not only your main script, but *all* modules
included by |PyInstaller|. If your code (or any module imported by your
script) relies on these features, your program may break or have
unexpected behavior.

|PyInstaller| can be run with Python optimization flags (``-O`` or ``-OO``)
by executing it as a Python module, rather than using the ``pyinstaller``
command::

# run with basic optimizations
python -O -m PyInstaller myscript.py

# also discard docstrings
python -OO -m PyInstaller myscript.py

Or, by explicitly setting the ``PYTHONOPTIMIZE`` environment variable
to a non-zero value::

# Unix
PYTHONOPTIMIZE=1 pyinstaller myscript.py

# Windows
set PYTHONOPTIMIZE=1 && pyinstaller myscript.py

You can use any |PyInstaller| options that are otherwise available with
the ``pyinstaller`` command. For example::

python -O -m PyInstaller --onefile myscript.py

Alternatively, you can also use the path to pyinstaller::

python -O /path/to/pyinstaller myscript.py

Using UPX
~~~~~~~~~~~~~~~~~~~

Expand Down

0 comments on commit f0f63da

Please sign in to comment.