26 November 2022
Nuitka Release 1.2
This is to inform you about the new stable release of Nuitka. It is the extremely compatible Python compiler, “download now”.
This release contains a large amount of new compatibility features and a few new optimization, while again consolidating what we have. Scalability should be better in many cases.
Bug Fixes
Standalone: Added implicit dependency of
thinc
backend. Fixed in 1.1.1 already.Python3.10: Fix,
match
statements with unnamed star matches could give incorrect results. Fixed in 1.1.1 already.match x: case [*_, y]: ... # y had wrong value here.
Python3.9+: Fix, file reader objects must convert to
str
objects. Fixed in 1.1.1 already.# This was the `repr` rather than a path value, but it must be usable # like that too. str(importlib.resources.files("package_name").joinpath("lala"))
Standalone: Added data file of
echopype
package. Fixed in 1.1.1 already.Anti-Bloat: Remove non-sense warning of compiled
pyscf
. Fixed in 1.1.1 already.macOS: Fix, in LTO mode using
incbin
can fail, switch to source mode for constants resources. Fixed in 1.1.2 already.Standalone: Add support for
sv_ttk
module. Fixed in 1.1.2 already.macOS: Fix, was no longer correcting
libpython
path, this was a regression preventing CPython for creating properly portable binary. Fixed in 1.1.2 already.macOS: Fix, main binary was not included in signing command. Fixed in 1.1.3 already.
Standalone: Added implicit dependency of
orjson
. Due tozoneinfo
not being automatically included anymore, this was having a segfault. Fixed in 1.1.3 already.Standalone: Added support for new
shapely
. Fixed in 1.1.4 already.macOS: Ignore extension module of non-matching architecture. Some wheels contain extension modules for only
x86_64
arch, and others contain them only forarm64
, preventing the standalone build. Fixed in 1.1.4 already.Standalone: Added missing
sklearn
dependencies. Fixed in 1.1.4 already.Fix, packages available through relative import paths could be confused with the same ones imported by absolute paths. This should be very hard to trigger, by normal users, but was seen during development. Fixed in 1.1.4 already.
Standalone: Apply import hacks for
pywin32
modules only on Windows, otherwise it can break e.g. macOS compilation. Fixed in 1.1.4 already.Windows: More robust DLL dependency caching, otherwise e.g. a Windows update can break things. Also consider plugin contribution, and Nuitka version, to be absolutely sure, much like we already do for bytecode caching. Fixed in 1.1.4 already.
Standalone: Fix,
seaborn
needs the same workaround asscipy
for corruption with MSVC. Fixed in 1.1.4 already.UI: Fix, the
options-nanny
was no longer functional and therefore failed to warn about non working options and package usages. Fixed in 1.1.5 already.macOS: Do not use extension modules of non-matching architecture. Fixed in 1.1.5 already.
Windows: Fix, resolving symlinks could fail for spaces in paths. Fixed in 1.1.6 already.
Standalone: Added missing DLL for
lightgbm
module. Fixed in 1.1.6 already.Compatibility: Respect
super
module variable. It is now possible to have a module level change ofsuper
but still get compatible behavior with Nuitka. Fixed in 1.1.6 already.Compatibility: Make sure we respect
super
overloads in the builtin module. Fixed in 1.1.6 already.Fix, the anti-bloat replacement code for
numpy.testing
was missing a required function. Fixed in 1.1.6 already.Fix,
importlib.import_module
static optimization was mishandling a module name of.
with a package name given. Fixed in 1.1.6 already.macOS: Fix, some extension modules use wrong suffixes in self references, we need to not complain about this kind of error. Fixed in 1.1.6 already.
Fix, do not make
ctypes.wintypes
a hard import on non-Windows. Nuitka asserted against it failing, where some code handles it failing on non-Windows platforms. Fixed in 1.1.6 already.Standalone: Added data files for
vedo
package. Fixed in 1.1.7 already.Plugins: Fix, the
gi
plugin did always setGI_TYPELIB_PATH
even if already present from user code. Also it did not handle errors to detect its value during compile time. Fixed in 1.1.7 already.Standalone: Added missing dependencies for
sqlalchemy
to have all SQL backends working. Fixed in 1.1.7 already.Added support Nixpkgs’s default non-writable
HOME
directory. Fixed in 1.1.8 already.Fix, distribution metadata name and package name need not align, need to preserve the original looked up name from
importlib.metadata.distribution
call. Fixed in 1.1.8 already.Windows: Fix, catch usage of unsupported
CLCACHE_MEMCACHED
mode with MSVC compilation. It is just unsupported.Windows: Fix, file version was spoiled from product version if it was the only version given.
Windows: The default for file description in version information was not as intended.
Plugins: Workaround for PyQt5 as contained in Anaconda providing wrong paths from the build machine.
macOS: After signing a binary with a certificate, compiling the next one was crashing on a warning about initially creating an ad-hoc binary.
Fix, detect case of non-writable cache path, make explaining error exit rather than crashing attempting to write to the cache.
macOS: Added support for
pyobjc
in version 9.0 or higher.
New Features
Python3.11: For now prevent the execution with 3.11 and give a warning to the user for a not yet supported version. This can be overridden with
--experimental=python311
but at this times will not compile anything yet due to required and at this time missing core changes.macOS: Added option
--macos-sign-notarization
that signs with runtime signature, but requires a developer certificate from Apple. As its name implies, this is for use with notarization for their App store.DLLs used via
delvewheel
were so far only handled in thezmq
plugin, but this has been generalized to cover any package using it. With that, e.g.shapely
just works. This probably helps many other packages as well.Added
__compiled__
and__compiled_constant__
attributes to compiled functions.With this, it can be decided per function what it is and bridges like
pyobjc
can use it to create better code on their side for constant value returning functions.Added
support_info
check to Nuitka package format. Make it clear thatpyobjc
is only supported after9.0
by erroring out if it has a too low version. It will not work at all before that version added support in upstream. Also using this to make it clear thatopencv-python
is best supported in version 4.6 or higher. It seems e.g. that video capture is not working with 4.5 at this time.Added
--report-template
which can be used to provide Jinja2 templates to create custom reports, and refer to built-in reports, at this time e.g. a license reports.
Optimization
Trust the absence of a few selected hard modules and convert those to static raises of import errors.
For conditional nodes where only one branch exits, and the other does not, no merging of the trace collection should happen. This should enhance the scalability and leads to more static optimization being done after these kinds of branches on variables assigned in such branches.
if condition1: a = 1 else: raise KeyError if condition2: b = 1 # Here, "a" is known to be assigned, but before it was only "maybe" # assigned, like "b" would have to be since, the branch may or may # not have been taken.
Do not merge tried blocks that are aborting with an exception handler that is not aborting. This is very similar to the change for conditional statements, again there is a control flow branch, that may have to be merged with an optional part, but sometimes that part is not optional from the perspective of the code following.
try: ... # potentially raising, but not aborting code return something() # this aborts except Exception: a = 1 try: ... # potentially raising, but not aborting code except Exception: b = 1 # Here, "a" is known to be assigned, but before it was only "maybe" # assigned, like "b" would have to be since, the branch may or may # not have been taken.
Exception matches were annotating a control flow escape and an exception exit, even when it is known that no error is possible to be happening that comparison.
try: ... except ImportError: # an exception match is done here, that cannot raise ...
Trust
importlib.metadata.PackageNotFoundError
to exist, with this some more metadata usages are statically optimized. Added in 1.1.4 already.Handle constant values from trusted imports as trusted values. So far, trusted import values were on equal footing to regular variables, which on the module level could mean that no optimization was done, due to control flow escapes happening.
# Known to be False at compile time. from typing import TYPE_CHECKING ... if TYPE_CHECKING: from something import normally_unused_unless_type_checking
In this code example above, the static optimization was not done because the value may be changed on the outside. However, for trusted constants, this is no longer assumed to be happening. So far only
if typing.TYPE_CHECKING:
using code had been optimized.macOS: Use sections for main binary constants binary blob rather than C source code (which we started in a recent hotfix due to LTO issues with incbin) and onefile payload. The latter enables notarization of the onefile binary as well and makes it faster to unpack as well.
Windows: Do not include DLLs from SxS. For PyPI packages these are generally unused, and self compiled modules won’t be SxS installations either. We can add it back where it turns out needed. This avoids including
comctl32
and similar DLLs, which ought to come from the OS, and might impede backward compatibility only.Disabled C compilation of very large
azure
modules.The per module usage information of other modules was only updated in first pass was used in later passes. But since they can get optimized away, we have to update every time, avoiding to still include unused modules.
Anti-Bloat: Fight the use of
dask
inxarray
andpint
, adding a mode controlling its use. This is however still incomplete and needs more work.Fix, the anti-bloat configuration for
rich.pretty
introduced aSyntaxError
that went unnoticed. In the future compilation will abort when this happens.Standalone: Added support for including DLLs of
llvmlite.binding
package.Anti-Bloat: Avoid using
pywin32
throughpkg_resources
import. This seems rather pointless and follows an optimization done for the inline copy of Nuitka already, thectypes
code path works just fine, and this may well be the only reason whypywin32
is included, which is by itself relatively large.Cache directory contents when scanning for modules. The
sys.path
and package directories were listed over and over, wasting time during the import analysis.Optimization: Was not caching not found modules, but retrying every time for each usage, potentially wasting time during import analysis.
Anti-Bloat: Initial work to avoid
pytest
in patsy, it is however incomplete.
Organizational
User Manual: Explain how to create 64/32 bits binaries on Windows, with there being no option to control it, this can otherwise be a bit unobvious that you have to just use the matching Python binary.
UI: Added an example for a cached onefile temporary location spec to the help output of
--onefile-tempdir-spec
to make cached more easy to achieve in the proper way.UI: Quote command line options with space in value better, no need to quote an affected command line option in its entirety, and it looks strange.
macOS: Catch user error of disabling the console without using the bundle mode, as it otherwise it has no effect.
macOS: Warn about not providing an icon with disabled console, otherwise the dock icon is empty, which just looks bad.
Debian: Also need to depend on
glob2
packages which the yaml engine expects to use when searching for DLLs.Debian: Pertain inline copies of modules in very old builds, there is e.g. no
glob2
for older releases, but only recent Debian releases need very pure packages, our backport doesn’t have to do it right.macOS: More reliable detection of Homebrew based Python. Rather than checking file system via its
sitecustomize
contents. The environment variables are only present to some usages.Installations with pip did not include all license, README files, etc. which however was intended. Also the attempt to disable bytecode compilation for some inline copies was not effective yet.
Renamed
pyzmq
plugin todelvewheel
as it is now absolutely generic and covers all uses of said packaging technique.Caching: Use cache directory for cached downloads, rather than application directory, which is just wrong. This will cause all previously cached downloads to become unused and repeated.
Quality: Updated development requirements to latest
black
,isort
,yamllint
, andtqdm
.Visual Code: Added recommendation for extension for Debian packaging files.
Added warning for
PyQt5
usage, since its support is very incomplete. Made thePyQt6
warning more concrete. It seems only Qt threading does not work, which is of course still significant. Instead PySide2 and PySide6 are recommended.UI: Have dedicated options group for onefile, the spec for the temporary files is not a Windows option at all anymore. Also move the warnings group to the end, people need to see the inclusion related group first.
User Manual: Explain how to create 64/32 bits binaries on Windows, which is not too obvious.
Cleanups
Moved PySide plugins DLL search extra paths to the Yaml configuration. In this way it is not dependent on the plugin being active, avoiding cryptic errors on macOS when they are not found.
Plugins: Avoid duplicate link libraries due to casing. We are now normalizing the link library names, which avoids e.g.
Shell32
andshell32
to be in the result.Cleanups to prepare a PyLint update that so otherwise failed due to encountered issues.
Plugins: Pass so called build definitions for generically. Rather than having dedicated code for each, and plugins can now provide them and pass their index to the scons builds.
Onefile: Moved file handling code to common code reducing code duplication and heavily cleaning up the bootstrap code generally.
Onefile: The CRC32 checksum code was duplicated between constants blob and onefile, and has moved to shared code, with an actual interface to take the checksum.
Spelling cleanups resumed, e.g. this time more clearly distinguishing between
run time
andruntime
, the first is when the program executes, but the latter can be an environment provided by a C compiler.
Tests
Tests: Added test that applies anti-bloat configuration to all found modules.
Tests: Tests: Avoid including unused
nuitka.tools
code in reflected test, which should make it faster. The compiler itself doesn’t use that code.
Summary
This release is again mainly a consolidation of previous release, as well as finishing off existing features. Optimization added in previous releases should have all regressions fixed now, again with a strong series of hotfixes.
New optimization was focused around findings with static optimization not being done, but still resulting in general improvements. Letting static optimization drive the effort is still paying off.
Scalability has seen improvements through some of the optimization, this time a lot less anti-bloat work has been done, and some things are only started. The focus will clearly now shift to making this a community effort. Expect postings that document the Yaml format we use.
For macOS specifically, with the sections work, onefile should launch faster, should be more compatible with signing, and can now be used in notarization, so for that platform, things are more round.
For Windows, a few issues with version information and onefile have been addressed. We should be able to use memory mapped view on this platform too, for faster unpacking of the payload, since it doesn’t have to go through the file anymore.