Compiled package hidden by existing package
The Problem in a Few Words
When Nuitka produces a compiled package right next to its source code, might not be loaded. This happens when a directory with the same name as the package exists alongside the compiled package. place.
Background
Python has a priority system that will prefer a directory something
with __init__.py
of the proper name over an extension module
something.pyd
/ something.so
located in the same place.
This means that if you have a directory named kitty
and Nuitka
compiles a package (with Python 3.10 on Windows for example) named
kitty
into kitty.cp310-win_amd64.pyd
, Python will prioritize the
kitty
directory over the compiled kitty.cp310-win_amd64.pyd
.
Therefore, the compiled code will not be used. This is different from
plain Python files, where something.py
can be replaced by
something.pyd
/ something.so
in the same location. In that case,
the compiled code will be used.
Example
cd tests/packages/sub_package
python -m nuitka --mode=package --remove-output --no-pyi-file kitty
...
Nuitka:WARNING: The compilation result is hidden by package directory 'kitty'.
Nuitka:WARNING: Importing will not use compiled code while it exists because it
Nuitka:WARNING: has precedence while both exist, out e.g. '--output-dir=output' to
Nuitka:WARNING: sure is importable.
Nuitka:WARNING: Complex topic! More information can be found at
Nuitka:WARNING: https://nuitka.net/info/compiled-package-hidden-by-package.html
Nuitka: Successfully created
Nuitka: '~\repos\Py2C\tests\packages\sub_package\kitty.cp310-win_amd64.pyd'.
$ ls
kitty/ kitty.cp310-win_amd64.pyd*
python3.10
>>> import kitty
...
>>> kitty.__compiled__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'kitty' has no attribute '__compiled__'
Consequence
When compiling packages, replacing source code with its compiled form is more complex in package mode.
Recommendation
To avoid this issue, use the --output-dir
option to place the
compiled package into a dedicated folder, such as build
. Then,
ensure you import the package from this directory.
For example, if you compile the kitty
package with
--output-dir=build
, you should import it from the build
directory.
You can verify that the compiled code is being used by checking for the
__compiled__
attribute on the imported module. If it’s present, the
compiled code is being used.