Repository: wasmerio/py2wasm Branch: develop Commit: 3136f77ae018 Files: 1940 Total size: 22.9 MB Directory structure: gitextract_8msbk7ao/ ├── .editorconfig ├── .gitattributes ├── .githooks/ │ └── pre-commit ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE.md │ ├── PULL_REQUEST_TEMPLATE.md │ └── workflows/ │ └── testing.yml ├── .gitignore ├── .gitmodules ├── .sourcery.yaml ├── .vscode/ │ ├── c_cpp_properties.json │ ├── extensions.json │ └── settings.json ├── CODE_OF_CONDUCT.rst ├── CONTRIBUTING.md ├── Changelog.rst ├── Developer_Manual.rst ├── LICENSE.txt ├── MANIFEST.in ├── README.rst ├── SECURITY.md ├── Standard-Plugins-Documentation.rst ├── UserPlugin-Creation.rst ├── Using-Plugin-Options.rst ├── bin/ │ ├── autoformat-nuitka-source │ ├── check-nuitka-with-codespell │ ├── check-nuitka-with-pylint │ ├── check-nuitka-with-restlint │ ├── check-nuitka-with-yamllint │ ├── check-reference-counts │ ├── compare_with_cpython │ ├── compare_with_xml │ ├── find_sxs_modules │ ├── generate-specialized-c-code │ ├── generate-specialized-python-code │ ├── measure-construct-performance │ ├── nuitka │ ├── nuitka-run │ ├── nuitka-watch │ ├── nuitka3 │ ├── nuitka3-run │ └── run-inside-nuitka-container ├── debian/ │ ├── README.source │ ├── changelog │ ├── compat │ ├── control │ ├── copyright │ ├── nuitka.docs │ ├── nuitka.manpages │ ├── pbuilder-hookdir/ │ │ └── B92test-installed-nuitka │ ├── rules │ ├── source/ │ │ ├── format │ │ └── lintian-overrides │ ├── upstream-signing-key.pgp │ └── watch ├── doc/ │ ├── Doxyfile.template │ ├── custom.css │ ├── nuitka-man-include.txt │ ├── nuitka-run.1 │ ├── nuitka.1 │ └── uml/ │ ├── standalone-overview.plantuml │ └── use-cases.plantuml ├── lib/ │ └── hints.py ├── misc/ │ ├── codespell-ignore.txt │ ├── create-pbuilder-image.py │ ├── dump-config-options.py │ ├── install-git-hooks.py │ ├── make-apidoc.py │ ├── make-coverage-rendering.py │ ├── make-deb-mentors-release.py │ ├── make-deb-release.py │ ├── make-pypi-upload.py │ ├── make-release.py │ ├── make-upload.py │ ├── make-version-bump.py │ ├── nuitka-package-config-schema.json │ ├── nuitka-run.bat │ ├── nuitka.bat │ ├── run-valgrind.py │ └── update-doc.py ├── nuitka/ │ ├── Builtins.py │ ├── BytecodeCaching.py │ ├── Bytecodes.py │ ├── CacheCleanup.py │ ├── Constants.py │ ├── Errors.py │ ├── HardImportRegistry.py │ ├── MainControl.py │ ├── ModuleRegistry.py │ ├── OptionParsing.py │ ├── Options.py │ ├── OutputDirectories.py │ ├── PostProcessing.py │ ├── Progress.py │ ├── PythonFlavors.py │ ├── PythonOperators.py │ ├── PythonVersions.py │ ├── Serialization.py │ ├── SourceCodeReferences.py │ ├── Tracing.py │ ├── TreeXML.py │ ├── Variables.py │ ├── Version.py │ ├── __init__.py │ ├── __main__.py │ ├── __past__.py │ ├── build/ │ │ ├── Backend.scons │ │ ├── CCompilerVersion.scons │ │ ├── DataComposerInterface.py │ │ ├── Onefile.scons │ │ ├── SconsCaching.py │ │ ├── SconsCompilerSettings.py │ │ ├── SconsHacks.py │ │ ├── SconsInterface.py │ │ ├── SconsProgress.py │ │ ├── SconsSpawn.py │ │ ├── SconsUtils.py │ │ ├── __init__.py │ │ ├── include/ │ │ │ └── nuitka/ │ │ │ ├── allocator.h │ │ │ ├── builtins.h │ │ │ ├── calling.h │ │ │ ├── checkers.h │ │ │ ├── checksum_tools.h │ │ │ ├── compiled_asyncgen.h │ │ │ ├── compiled_cell.h │ │ │ ├── compiled_coroutine.h │ │ │ ├── compiled_frame.h │ │ │ ├── compiled_function.h │ │ │ ├── compiled_generator.h │ │ │ ├── compiled_method.h │ │ │ ├── constants.h │ │ │ ├── constants_blob.h │ │ │ ├── environment_variables.h │ │ │ ├── environment_variables_system.h │ │ │ ├── exception_groups.h │ │ │ ├── exceptions.h │ │ │ ├── filesystem_paths.h │ │ │ ├── freelists.h │ │ │ ├── hedley.h │ │ │ ├── helper/ │ │ │ │ ├── attributes.h │ │ │ │ ├── boolean.h │ │ │ │ ├── bytearrays.h │ │ │ │ ├── bytes.h │ │ │ │ ├── calling_generated.h │ │ │ │ ├── comparisons_eq.h │ │ │ │ ├── comparisons_ge.h │ │ │ │ ├── comparisons_gt.h │ │ │ │ ├── comparisons_le.h │ │ │ │ ├── comparisons_lt.h │ │ │ │ ├── comparisons_ne.h │ │ │ │ ├── complex.h │ │ │ │ ├── dictionaries.h │ │ │ │ ├── floats.h │ │ │ │ ├── import_hard.h │ │ │ │ ├── indexes.h │ │ │ │ ├── ints.h │ │ │ │ ├── iterators.h │ │ │ │ ├── lists.h │ │ │ │ ├── lists_generated.h │ │ │ │ ├── mappings.h │ │ │ │ ├── operations.h │ │ │ │ ├── operations_binary_add.h │ │ │ │ ├── operations_binary_bitand.h │ │ │ │ ├── operations_binary_bitor.h │ │ │ │ ├── operations_binary_bitxor.h │ │ │ │ ├── operations_binary_divmod.h │ │ │ │ ├── operations_binary_floordiv.h │ │ │ │ ├── operations_binary_lshift.h │ │ │ │ ├── operations_binary_matmult.h │ │ │ │ ├── operations_binary_mod.h │ │ │ │ ├── operations_binary_mult.h │ │ │ │ ├── operations_binary_olddiv.h │ │ │ │ ├── operations_binary_pow.h │ │ │ │ ├── operations_binary_rshift.h │ │ │ │ ├── operations_binary_sub.h │ │ │ │ ├── operations_binary_truediv.h │ │ │ │ ├── operations_builtin_types.h │ │ │ │ ├── operations_inplace_add.h │ │ │ │ ├── operations_inplace_bitand.h │ │ │ │ ├── operations_inplace_bitor.h │ │ │ │ ├── operations_inplace_bitxor.h │ │ │ │ ├── operations_inplace_floordiv.h │ │ │ │ ├── operations_inplace_lshift.h │ │ │ │ ├── operations_inplace_matmult.h │ │ │ │ ├── operations_inplace_mod.h │ │ │ │ ├── operations_inplace_mult.h │ │ │ │ ├── operations_inplace_olddiv.h │ │ │ │ ├── operations_inplace_pow.h │ │ │ │ ├── operations_inplace_rshift.h │ │ │ │ ├── operations_inplace_sub.h │ │ │ │ ├── operations_inplace_truediv.h │ │ │ │ ├── raising.h │ │ │ │ ├── rangeobjects.h │ │ │ │ ├── richcomparisons.h │ │ │ │ ├── sequences.h │ │ │ │ ├── sets.h │ │ │ │ ├── slices.h │ │ │ │ ├── strings.h │ │ │ │ ├── subscripts.h │ │ │ │ └── tuples.h │ │ │ ├── helpers.h │ │ │ ├── importing.h │ │ │ ├── incbin.h │ │ │ ├── jit_sources.h │ │ │ ├── prelude.h │ │ │ ├── printing.h │ │ │ ├── python_pgo.h │ │ │ ├── safe_string_ops.h │ │ │ ├── threading.h │ │ │ ├── tracing.h │ │ │ └── unfreezing.h │ │ ├── inline_copy/ │ │ │ ├── appdirs/ │ │ │ │ ├── LICENSE.txt │ │ │ │ └── appdirs.py │ │ │ ├── atomicwrites/ │ │ │ │ ├── LICENSE │ │ │ │ └── atomicwrites.py │ │ │ ├── bin/ │ │ │ │ └── scons.py │ │ │ ├── clcache/ │ │ │ │ └── clcache/ │ │ │ │ ├── LICENSE │ │ │ │ ├── __init__.py │ │ │ │ └── caching.py │ │ │ ├── colorama/ │ │ │ │ ├── LICENSE.txt │ │ │ │ └── colorama/ │ │ │ │ ├── __init__.py │ │ │ │ ├── ansi.py │ │ │ │ ├── ansitowin32.py │ │ │ │ ├── initialise.py │ │ │ │ ├── win32.py │ │ │ │ └── winterm.py │ │ │ ├── glob2/ │ │ │ │ ├── LICENSE │ │ │ │ └── glob2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── compat.py │ │ │ │ ├── fnmatch.py │ │ │ │ └── impl.py │ │ │ ├── jinja2/ │ │ │ │ ├── LICENSE.rst │ │ │ │ ├── README.rst │ │ │ │ └── jinja2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── _compat.py │ │ │ │ ├── _identifier.py │ │ │ │ ├── bccache.py │ │ │ │ ├── compiler.py │ │ │ │ ├── constants.py │ │ │ │ ├── debug.py │ │ │ │ ├── defaults.py │ │ │ │ ├── environment.py │ │ │ │ ├── exceptions.py │ │ │ │ ├── ext.py │ │ │ │ ├── filters.py │ │ │ │ ├── idtracking.py │ │ │ │ ├── lexer.py │ │ │ │ ├── loaders.py │ │ │ │ ├── meta.py │ │ │ │ ├── nativetypes.py │ │ │ │ ├── nodes.py │ │ │ │ ├── optimizer.py │ │ │ │ ├── parser.py │ │ │ │ ├── runtime.py │ │ │ │ ├── sandbox.py │ │ │ │ ├── tests.py │ │ │ │ ├── utils.py │ │ │ │ └── visitor.py │ │ │ ├── jinja2_35/ │ │ │ │ ├── LICENSE.rst │ │ │ │ ├── README.rst │ │ │ │ └── jinja2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── _compat.py │ │ │ │ ├── _identifier.py │ │ │ │ ├── bccache.py │ │ │ │ ├── compiler.py │ │ │ │ ├── constants.py │ │ │ │ ├── debug.py │ │ │ │ ├── defaults.py │ │ │ │ ├── environment.py │ │ │ │ ├── exceptions.py │ │ │ │ ├── ext.py │ │ │ │ ├── filters.py │ │ │ │ ├── idtracking.py │ │ │ │ ├── lexer.py │ │ │ │ ├── loaders.py │ │ │ │ ├── meta.py │ │ │ │ ├── nativetypes.py │ │ │ │ ├── nodes.py │ │ │ │ ├── optimizer.py │ │ │ │ ├── parser.py │ │ │ │ ├── runtime.py │ │ │ │ ├── sandbox.py │ │ │ │ ├── tests.py │ │ │ │ ├── utils.py │ │ │ │ └── visitor.py │ │ │ ├── lib/ │ │ │ │ ├── scons-2.3.2/ │ │ │ │ │ └── SCons/ │ │ │ │ │ ├── Action.py │ │ │ │ │ ├── Builder.py │ │ │ │ │ ├── CacheDir.py │ │ │ │ │ ├── Conftest.py │ │ │ │ │ ├── Debug.py │ │ │ │ │ ├── Defaults.py │ │ │ │ │ ├── Environment.py │ │ │ │ │ ├── Errors.py │ │ │ │ │ ├── Executor.py │ │ │ │ │ ├── Job.py │ │ │ │ │ ├── Memoize.py │ │ │ │ │ ├── Node/ │ │ │ │ │ │ ├── Alias.py │ │ │ │ │ │ ├── FS.py │ │ │ │ │ │ ├── Python.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Options/ │ │ │ │ │ │ ├── BoolOption.py │ │ │ │ │ │ ├── EnumOption.py │ │ │ │ │ │ ├── ListOption.py │ │ │ │ │ │ ├── PackageOption.py │ │ │ │ │ │ ├── PathOption.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── PathList.py │ │ │ │ │ ├── Platform/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── aix.py │ │ │ │ │ │ ├── cygwin.py │ │ │ │ │ │ ├── darwin.py │ │ │ │ │ │ ├── hpux.py │ │ │ │ │ │ ├── irix.py │ │ │ │ │ │ ├── os2.py │ │ │ │ │ │ ├── posix.py │ │ │ │ │ │ ├── sunos.py │ │ │ │ │ │ └── win32.py │ │ │ │ │ ├── SConf.py │ │ │ │ │ ├── SConsign.py │ │ │ │ │ ├── Scanner/ │ │ │ │ │ │ ├── C.py │ │ │ │ │ │ ├── Dir.py │ │ │ │ │ │ ├── Prog.py │ │ │ │ │ │ ├── RC.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Script/ │ │ │ │ │ │ ├── Interactive.py │ │ │ │ │ │ ├── Main.py │ │ │ │ │ │ ├── SConsOptions.py │ │ │ │ │ │ ├── SConscript.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Sig.py │ │ │ │ │ ├── Subst.py │ │ │ │ │ ├── Taskmaster.py │ │ │ │ │ ├── Tool/ │ │ │ │ │ │ ├── 386asm.py │ │ │ │ │ │ ├── BitKeeper.py │ │ │ │ │ │ ├── CVS.py │ │ │ │ │ │ ├── GettextCommon.py │ │ │ │ │ │ ├── MSCommon/ │ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ │ ├── arch.py │ │ │ │ │ │ │ ├── common.py │ │ │ │ │ │ │ ├── netframework.py │ │ │ │ │ │ │ ├── sdk.py │ │ │ │ │ │ │ ├── vc.py │ │ │ │ │ │ │ └── vs.py │ │ │ │ │ │ ├── Perforce.py │ │ │ │ │ │ ├── PharLapCommon.py │ │ │ │ │ │ ├── RCS.py │ │ │ │ │ │ ├── SCCS.py │ │ │ │ │ │ ├── Subversion.py │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── aixc++.py │ │ │ │ │ │ ├── aixcc.py │ │ │ │ │ │ ├── aixf77.py │ │ │ │ │ │ ├── aixlink.py │ │ │ │ │ │ ├── applelink.py │ │ │ │ │ │ ├── ar.py │ │ │ │ │ │ ├── as.py │ │ │ │ │ │ ├── bcc32.py │ │ │ │ │ │ ├── c++.py │ │ │ │ │ │ ├── cc.py │ │ │ │ │ │ ├── cyglink.py │ │ │ │ │ │ ├── default.py │ │ │ │ │ │ ├── dmd.py │ │ │ │ │ │ ├── docbook/ │ │ │ │ │ │ │ └── __init__.py │ │ │ │ │ │ ├── filesystem.py │ │ │ │ │ │ ├── g++.py │ │ │ │ │ │ ├── g77.py │ │ │ │ │ │ ├── gas.py │ │ │ │ │ │ ├── gcc.py │ │ │ │ │ │ ├── gdc.py │ │ │ │ │ │ ├── gettext.py │ │ │ │ │ │ ├── gfortran.py │ │ │ │ │ │ ├── gnulink.py │ │ │ │ │ │ ├── hpc++.py │ │ │ │ │ │ ├── hpcc.py │ │ │ │ │ │ ├── hplink.py │ │ │ │ │ │ ├── icc.py │ │ │ │ │ │ ├── icl.py │ │ │ │ │ │ ├── ilink.py │ │ │ │ │ │ ├── ilink32.py │ │ │ │ │ │ ├── install.py │ │ │ │ │ │ ├── intelc.py │ │ │ │ │ │ ├── lex.py │ │ │ │ │ │ ├── link.py │ │ │ │ │ │ ├── linkloc.py │ │ │ │ │ │ ├── m4.py │ │ │ │ │ │ ├── masm.py │ │ │ │ │ │ ├── mingw.py │ │ │ │ │ │ ├── msgfmt.py │ │ │ │ │ │ ├── msginit.py │ │ │ │ │ │ ├── msgmerge.py │ │ │ │ │ │ ├── mslib.py │ │ │ │ │ │ ├── mslink.py │ │ │ │ │ │ ├── mssdk.py │ │ │ │ │ │ ├── msvc.py │ │ │ │ │ │ ├── msvs.py │ │ │ │ │ │ ├── mwcc.py │ │ │ │ │ │ ├── mwld.py │ │ │ │ │ │ ├── nasm.py │ │ │ │ │ │ ├── rmic.py │ │ │ │ │ │ ├── rpcgen.py │ │ │ │ │ │ ├── sgiar.py │ │ │ │ │ │ ├── sgic++.py │ │ │ │ │ │ ├── sgicc.py │ │ │ │ │ │ ├── sgilink.py │ │ │ │ │ │ ├── sunar.py │ │ │ │ │ │ ├── sunc++.py │ │ │ │ │ │ ├── suncc.py │ │ │ │ │ │ ├── sunlink.py │ │ │ │ │ │ ├── tar.py │ │ │ │ │ │ ├── textfile.py │ │ │ │ │ │ ├── tlib.py │ │ │ │ │ │ ├── wix.py │ │ │ │ │ │ ├── xgettext.py │ │ │ │ │ │ └── zip.py │ │ │ │ │ ├── Util.py │ │ │ │ │ ├── Variables/ │ │ │ │ │ │ ├── BoolVariable.py │ │ │ │ │ │ ├── EnumVariable.py │ │ │ │ │ │ ├── ListVariable.py │ │ │ │ │ │ ├── PackageVariable.py │ │ │ │ │ │ ├── PathVariable.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Warnings.py │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── compat/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── _scons_builtins.py │ │ │ │ │ │ ├── _scons_collections.py │ │ │ │ │ │ ├── _scons_dbm.py │ │ │ │ │ │ ├── _scons_hashlib.py │ │ │ │ │ │ ├── _scons_io.py │ │ │ │ │ │ ├── _scons_sets.py │ │ │ │ │ │ └── _scons_subprocess.py │ │ │ │ │ ├── cpp.py │ │ │ │ │ ├── dblite.py │ │ │ │ │ └── exitfuncs.py │ │ │ │ ├── scons-3.1.2/ │ │ │ │ │ └── SCons/ │ │ │ │ │ ├── Action.py │ │ │ │ │ ├── Builder.py │ │ │ │ │ ├── CacheDir.py │ │ │ │ │ ├── Conftest.py │ │ │ │ │ ├── Debug.py │ │ │ │ │ ├── Defaults.py │ │ │ │ │ ├── Environment.py │ │ │ │ │ ├── Errors.py │ │ │ │ │ ├── Executor.py │ │ │ │ │ ├── Job.py │ │ │ │ │ ├── Memoize.py │ │ │ │ │ ├── Node/ │ │ │ │ │ │ ├── Alias.py │ │ │ │ │ │ ├── FS.py │ │ │ │ │ │ ├── Python.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── PathList.py │ │ │ │ │ ├── Platform/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── aix.py │ │ │ │ │ │ ├── cygwin.py │ │ │ │ │ │ ├── darwin.py │ │ │ │ │ │ ├── hpux.py │ │ │ │ │ │ ├── irix.py │ │ │ │ │ │ ├── mingw.py │ │ │ │ │ │ ├── os2.py │ │ │ │ │ │ ├── posix.py │ │ │ │ │ │ ├── sunos.py │ │ │ │ │ │ ├── virtualenv.py │ │ │ │ │ │ └── win32.py │ │ │ │ │ ├── SConf.py │ │ │ │ │ ├── SConsign.py │ │ │ │ │ ├── Scanner/ │ │ │ │ │ │ ├── C.py │ │ │ │ │ │ ├── Dir.py │ │ │ │ │ │ ├── Prog.py │ │ │ │ │ │ ├── RC.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Script/ │ │ │ │ │ │ ├── Interactive.py │ │ │ │ │ │ ├── Main.py │ │ │ │ │ │ ├── SConsOptions.py │ │ │ │ │ │ ├── SConscript.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Subst.py │ │ │ │ │ ├── Taskmaster.py │ │ │ │ │ ├── Tool/ │ │ │ │ │ │ ├── 386asm.py │ │ │ │ │ │ ├── GettextCommon.py │ │ │ │ │ │ ├── MSCommon/ │ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ │ ├── arch.py │ │ │ │ │ │ │ ├── common.py │ │ │ │ │ │ │ ├── netframework.py │ │ │ │ │ │ │ ├── sdk.py │ │ │ │ │ │ │ ├── vc.py │ │ │ │ │ │ │ └── vs.py │ │ │ │ │ │ ├── PharLapCommon.py │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── aixc++.py │ │ │ │ │ │ ├── aixcc.py │ │ │ │ │ │ ├── aixcxx.py │ │ │ │ │ │ ├── aixlink.py │ │ │ │ │ │ ├── applelink.py │ │ │ │ │ │ ├── ar.py │ │ │ │ │ │ ├── as.py │ │ │ │ │ │ ├── bcc32.py │ │ │ │ │ │ ├── c++.py │ │ │ │ │ │ ├── cc.py │ │ │ │ │ │ ├── clang.py │ │ │ │ │ │ ├── clangCommon/ │ │ │ │ │ │ │ └── __init__.py │ │ │ │ │ │ ├── clangxx.py │ │ │ │ │ │ ├── cxx.py │ │ │ │ │ │ ├── cyglink.py │ │ │ │ │ │ ├── default.py │ │ │ │ │ │ ├── docbook/ │ │ │ │ │ │ │ └── __init__.py │ │ │ │ │ │ ├── filesystem.py │ │ │ │ │ │ ├── g++.py │ │ │ │ │ │ ├── gas.py │ │ │ │ │ │ ├── gcc.py │ │ │ │ │ │ ├── gettext_tool.py │ │ │ │ │ │ ├── gnulink.py │ │ │ │ │ │ ├── gxx.py │ │ │ │ │ │ ├── hpc++.py │ │ │ │ │ │ ├── hpcc.py │ │ │ │ │ │ ├── hpcxx.py │ │ │ │ │ │ ├── hplink.py │ │ │ │ │ │ ├── icc.py │ │ │ │ │ │ ├── icl.py │ │ │ │ │ │ ├── ilink.py │ │ │ │ │ │ ├── ilink32.py │ │ │ │ │ │ ├── install.py │ │ │ │ │ │ ├── intelc.py │ │ │ │ │ │ ├── link.py │ │ │ │ │ │ ├── linkloc.py │ │ │ │ │ │ ├── m4.py │ │ │ │ │ │ ├── masm.py │ │ │ │ │ │ ├── mingw.py │ │ │ │ │ │ ├── msgfmt.py │ │ │ │ │ │ ├── msginit.py │ │ │ │ │ │ ├── msgmerge.py │ │ │ │ │ │ ├── mslib.py │ │ │ │ │ │ ├── mslink.py │ │ │ │ │ │ ├── mssdk.py │ │ │ │ │ │ ├── msvc.py │ │ │ │ │ │ ├── msvs.py │ │ │ │ │ │ ├── mwcc.py │ │ │ │ │ │ ├── mwld.py │ │ │ │ │ │ ├── nasm.py │ │ │ │ │ │ ├── rmic.py │ │ │ │ │ │ ├── rpcgen.py │ │ │ │ │ │ ├── sgiar.py │ │ │ │ │ │ ├── sgic++.py │ │ │ │ │ │ ├── sgicc.py │ │ │ │ │ │ ├── sgicxx.py │ │ │ │ │ │ ├── sgilink.py │ │ │ │ │ │ ├── sunar.py │ │ │ │ │ │ ├── sunc++.py │ │ │ │ │ │ ├── suncc.py │ │ │ │ │ │ ├── suncxx.py │ │ │ │ │ │ ├── sunlink.py │ │ │ │ │ │ ├── tar.py │ │ │ │ │ │ ├── textfile.py │ │ │ │ │ │ ├── tlib.py │ │ │ │ │ │ ├── wix.py │ │ │ │ │ │ ├── xgettext.py │ │ │ │ │ │ └── zip.py │ │ │ │ │ ├── Util.py │ │ │ │ │ ├── Variables/ │ │ │ │ │ │ ├── BoolVariable.py │ │ │ │ │ │ ├── EnumVariable.py │ │ │ │ │ │ ├── ListVariable.py │ │ │ │ │ │ ├── PackageVariable.py │ │ │ │ │ │ ├── PathVariable.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Warnings.py │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── compat/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ └── _scons_dbm.py │ │ │ │ │ ├── cpp.py │ │ │ │ │ ├── dblite.py │ │ │ │ │ └── exitfuncs.py │ │ │ │ └── scons-4.3.0/ │ │ │ │ └── SCons/ │ │ │ │ ├── Action.py │ │ │ │ ├── Builder.py │ │ │ │ ├── CacheDir.py │ │ │ │ ├── Conftest.py │ │ │ │ ├── Debug.py │ │ │ │ ├── Defaults.py │ │ │ │ ├── Environment.py │ │ │ │ ├── EnvironmentValues.py │ │ │ │ ├── Errors.py │ │ │ │ ├── Executor.py │ │ │ │ ├── Job.py │ │ │ │ ├── Memoize.py │ │ │ │ ├── Node/ │ │ │ │ │ ├── Alias.py │ │ │ │ │ ├── FS.py │ │ │ │ │ ├── Python.py │ │ │ │ │ └── __init__.py │ │ │ │ ├── PathList.py │ │ │ │ ├── Platform/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── aix.py │ │ │ │ │ ├── cygwin.py │ │ │ │ │ ├── darwin.py │ │ │ │ │ ├── hpux.py │ │ │ │ │ ├── irix.py │ │ │ │ │ ├── mingw.py │ │ │ │ │ ├── os2.py │ │ │ │ │ ├── posix.py │ │ │ │ │ ├── sunos.py │ │ │ │ │ ├── virtualenv.py │ │ │ │ │ └── win32.py │ │ │ │ ├── SConf.py │ │ │ │ ├── SConsign.py │ │ │ │ ├── Scanner/ │ │ │ │ │ ├── C.py │ │ │ │ │ ├── Dir.py │ │ │ │ │ ├── Prog.py │ │ │ │ │ ├── RC.py │ │ │ │ │ └── __init__.py │ │ │ │ ├── Script/ │ │ │ │ │ ├── Interactive.py │ │ │ │ │ ├── Main.py │ │ │ │ │ ├── SConsOptions.py │ │ │ │ │ ├── SConscript.py │ │ │ │ │ └── __init__.py │ │ │ │ ├── Subst.py │ │ │ │ ├── Taskmaster.py │ │ │ │ ├── Tool/ │ │ │ │ │ ├── 386asm.py │ │ │ │ │ ├── GettextCommon.py │ │ │ │ │ ├── MSCommon/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── arch.py │ │ │ │ │ │ ├── common.py │ │ │ │ │ │ ├── netframework.py │ │ │ │ │ │ ├── sdk.py │ │ │ │ │ │ ├── vc.py │ │ │ │ │ │ └── vs.py │ │ │ │ │ ├── PharLapCommon.py │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── aixc++.py │ │ │ │ │ ├── aixcc.py │ │ │ │ │ ├── aixcxx.py │ │ │ │ │ ├── aixlink.py │ │ │ │ │ ├── applelink.py │ │ │ │ │ ├── ar.py │ │ │ │ │ ├── as.py │ │ │ │ │ ├── asm.py │ │ │ │ │ ├── bcc32.py │ │ │ │ │ ├── c++.py │ │ │ │ │ ├── cc.py │ │ │ │ │ ├── clang.py │ │ │ │ │ ├── clangCommon/ │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── clangxx.py │ │ │ │ │ ├── cxx.py │ │ │ │ │ ├── cyglink.py │ │ │ │ │ ├── default.py │ │ │ │ │ ├── filesystem.py │ │ │ │ │ ├── g++.py │ │ │ │ │ ├── gas.py │ │ │ │ │ ├── gcc.py │ │ │ │ │ ├── gettext_tool.py │ │ │ │ │ ├── gnulink.py │ │ │ │ │ ├── gxx.py │ │ │ │ │ ├── hpc++.py │ │ │ │ │ ├── hpcc.py │ │ │ │ │ ├── hpcxx.py │ │ │ │ │ ├── hplink.py │ │ │ │ │ ├── icc.py │ │ │ │ │ ├── icl.py │ │ │ │ │ ├── ilink.py │ │ │ │ │ ├── ilink32.py │ │ │ │ │ ├── install.py │ │ │ │ │ ├── intelc.py │ │ │ │ │ ├── link.py │ │ │ │ │ ├── linkCommon/ │ │ │ │ │ │ ├── LoadableModule.py │ │ │ │ │ │ ├── SharedLibrary.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── linkloc.py │ │ │ │ │ ├── m4.py │ │ │ │ │ ├── masm.py │ │ │ │ │ ├── mingw.py │ │ │ │ │ ├── msgfmt.py │ │ │ │ │ ├── msginit.py │ │ │ │ │ ├── msgmerge.py │ │ │ │ │ ├── mslib.py │ │ │ │ │ ├── mslink.py │ │ │ │ │ ├── mssdk.py │ │ │ │ │ ├── msvc.py │ │ │ │ │ ├── msvs.py │ │ │ │ │ ├── mwcc.py │ │ │ │ │ ├── mwld.py │ │ │ │ │ ├── nasm.py │ │ │ │ │ ├── rmic.py │ │ │ │ │ ├── rpcgen.py │ │ │ │ │ ├── sgiar.py │ │ │ │ │ ├── sgic++.py │ │ │ │ │ ├── sgicc.py │ │ │ │ │ ├── sgicxx.py │ │ │ │ │ ├── sgilink.py │ │ │ │ │ ├── sunar.py │ │ │ │ │ ├── sunc++.py │ │ │ │ │ ├── suncc.py │ │ │ │ │ ├── suncxx.py │ │ │ │ │ ├── sunlink.py │ │ │ │ │ ├── tar.py │ │ │ │ │ ├── textfile.py │ │ │ │ │ ├── tlib.py │ │ │ │ │ ├── wix.py │ │ │ │ │ ├── xgettext.py │ │ │ │ │ └── zip.py │ │ │ │ ├── Util.py │ │ │ │ ├── Utilities/ │ │ │ │ │ ├── ConfigureCache.py │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── sconsign.py │ │ │ │ ├── Variables/ │ │ │ │ │ ├── BoolVariable.py │ │ │ │ │ ├── EnumVariable.py │ │ │ │ │ ├── ListVariable.py │ │ │ │ │ ├── PackageVariable.py │ │ │ │ │ ├── PathVariable.py │ │ │ │ │ └── __init__.py │ │ │ │ ├── Warnings.py │ │ │ │ ├── __init__.py │ │ │ │ ├── compat/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── _scons_dbm.py │ │ │ │ │ └── win32.py │ │ │ │ ├── cpp.py │ │ │ │ ├── dblite.py │ │ │ │ └── exitfuncs.py │ │ │ ├── libbacktrace/ │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ └── backtrace/ │ │ │ │ ├── alloc.c │ │ │ │ ├── backtrace-supported.h │ │ │ │ ├── backtrace.c │ │ │ │ ├── backtrace.h │ │ │ │ ├── config.h │ │ │ │ ├── dwarf.c │ │ │ │ ├── elf.c │ │ │ │ ├── fileline.c │ │ │ │ ├── filenames.h │ │ │ │ ├── internal.h │ │ │ │ ├── macho.c │ │ │ │ ├── mmap.c │ │ │ │ ├── pecoff.c │ │ │ │ ├── posix.c │ │ │ │ ├── read.c │ │ │ │ ├── sort.c │ │ │ │ ├── state.c │ │ │ │ └── xcoff.c │ │ │ ├── markupsafe/ │ │ │ │ ├── LICENSE.rst │ │ │ │ └── markupsafe/ │ │ │ │ ├── __init__.py │ │ │ │ ├── _compat.py │ │ │ │ ├── _constants.py │ │ │ │ └── _native.py │ │ │ ├── pkg_resources/ │ │ │ │ └── pkg_resources/ │ │ │ │ ├── __init__.py │ │ │ │ └── py31compat.py │ │ │ ├── pkg_resources_27/ │ │ │ │ └── pkg_resources/ │ │ │ │ └── __init__.py │ │ │ ├── tqdm/ │ │ │ │ ├── LICENCE │ │ │ │ └── tqdm/ │ │ │ │ ├── __init__.py │ │ │ │ ├── _main.py │ │ │ │ ├── _monitor.py │ │ │ │ ├── _tqdm.py │ │ │ │ ├── _tqdm_notebook.py │ │ │ │ ├── _tqdm_pandas.py │ │ │ │ ├── _utils.py │ │ │ │ ├── auto.py │ │ │ │ ├── autonotebook.py │ │ │ │ ├── dask.py │ │ │ │ ├── notebook.py │ │ │ │ ├── std.py │ │ │ │ ├── tk.py │ │ │ │ ├── utils.py │ │ │ │ └── version.py │ │ │ ├── wax_off/ │ │ │ │ ├── LICENSE │ │ │ │ └── wax_off.py │ │ │ ├── yaml/ │ │ │ │ ├── LICENSE │ │ │ │ └── yaml/ │ │ │ │ ├── __init__.py │ │ │ │ ├── composer.py │ │ │ │ ├── constructor.py │ │ │ │ ├── cyaml.py │ │ │ │ ├── dumper.py │ │ │ │ ├── emitter.py │ │ │ │ ├── error.py │ │ │ │ ├── events.py │ │ │ │ ├── loader.py │ │ │ │ ├── nodes.py │ │ │ │ ├── parser.py │ │ │ │ ├── reader.py │ │ │ │ ├── representer.py │ │ │ │ ├── resolver.py │ │ │ │ ├── scanner.py │ │ │ │ ├── serializer.py │ │ │ │ └── tokens.py │ │ │ ├── yaml_27/ │ │ │ │ ├── LICENSE │ │ │ │ └── yaml/ │ │ │ │ ├── __init__.py │ │ │ │ ├── composer.py │ │ │ │ ├── constructor.py │ │ │ │ ├── cyaml.py │ │ │ │ ├── dumper.py │ │ │ │ ├── emitter.py │ │ │ │ ├── error.py │ │ │ │ ├── events.py │ │ │ │ ├── loader.py │ │ │ │ ├── nodes.py │ │ │ │ ├── parser.py │ │ │ │ ├── reader.py │ │ │ │ ├── representer.py │ │ │ │ ├── resolver.py │ │ │ │ ├── scanner.py │ │ │ │ ├── serializer.py │ │ │ │ └── tokens.py │ │ │ ├── yaml_35/ │ │ │ │ ├── LICENSE │ │ │ │ └── yaml/ │ │ │ │ ├── __init__.py │ │ │ │ ├── composer.py │ │ │ │ ├── constructor.py │ │ │ │ ├── cyaml.py │ │ │ │ ├── dumper.py │ │ │ │ ├── emitter.py │ │ │ │ ├── error.py │ │ │ │ ├── events.py │ │ │ │ ├── loader.py │ │ │ │ ├── nodes.py │ │ │ │ ├── parser.py │ │ │ │ ├── reader.py │ │ │ │ ├── representer.py │ │ │ │ ├── resolver.py │ │ │ │ ├── scanner.py │ │ │ │ ├── serializer.py │ │ │ │ └── tokens.py │ │ │ ├── zlib/ │ │ │ │ ├── LICENSE │ │ │ │ ├── crc32.c │ │ │ │ ├── crc32.h │ │ │ │ ├── zconf.h │ │ │ │ ├── zlib.h │ │ │ │ └── zutil.h │ │ │ └── zstd/ │ │ │ ├── LICENSE.txt │ │ │ ├── common/ │ │ │ │ ├── bitstream.h │ │ │ │ ├── compiler.h │ │ │ │ ├── cpu.h │ │ │ │ ├── debug.h │ │ │ │ ├── entropy_common.c │ │ │ │ ├── error_private.c │ │ │ │ ├── error_private.h │ │ │ │ ├── fse.h │ │ │ │ ├── fse_decompress.c │ │ │ │ ├── huf.h │ │ │ │ ├── mem.h │ │ │ │ ├── xxhash.c │ │ │ │ ├── xxhash.h │ │ │ │ ├── zstd_common.c │ │ │ │ ├── zstd_deps.h │ │ │ │ ├── zstd_errors.h │ │ │ │ └── zstd_internal.h │ │ │ ├── decompress/ │ │ │ │ ├── huf_decompress.c │ │ │ │ ├── zstd_ddict.c │ │ │ │ ├── zstd_ddict.h │ │ │ │ ├── zstd_decompress.c │ │ │ │ ├── zstd_decompress_block.c │ │ │ │ ├── zstd_decompress_block.h │ │ │ │ └── zstd_decompress_internal.h │ │ │ └── zstd.h │ │ └── static_src/ │ │ ├── CompiledAsyncgenType.c │ │ ├── CompiledCellType.c │ │ ├── CompiledCodeHelpers.c │ │ ├── CompiledCoroutineType.c │ │ ├── CompiledFrameType.c │ │ ├── CompiledFunctionType.c │ │ ├── CompiledGeneratorType.c │ │ ├── CompiledGeneratorTypeUncompiledIntegration.c │ │ ├── CompiledMethodType.c │ │ ├── HelpersAllocator.c │ │ ├── HelpersAttributes.c │ │ ├── HelpersBuiltin.c │ │ ├── HelpersBuiltinTypeMethods.c │ │ ├── HelpersBytes.c │ │ ├── HelpersCalling.c │ │ ├── HelpersCallingGenerated.c │ │ ├── HelpersChecksumTools.c │ │ ├── HelpersClasses.c │ │ ├── HelpersComparisonEq.c │ │ ├── HelpersComparisonEqUtils.c │ │ ├── HelpersComparisonGe.c │ │ ├── HelpersComparisonGt.c │ │ ├── HelpersComparisonLe.c │ │ ├── HelpersComparisonLt.c │ │ ├── HelpersComparisonNe.c │ │ ├── HelpersConstantsBlob.c │ │ ├── HelpersDeepcopy.c │ │ ├── HelpersDictionaries.c │ │ ├── HelpersDictionariesGenerated.c │ │ ├── HelpersDumpBacktraces.c │ │ ├── HelpersEnvironmentVariables.c │ │ ├── HelpersEnvironmentVariablesSystem.c │ │ ├── HelpersExceptions.c │ │ ├── HelpersFiles.c │ │ ├── HelpersFilesystemPaths.c │ │ ├── HelpersFloats.c │ │ ├── HelpersHeapStorage.c │ │ ├── HelpersImport.c │ │ ├── HelpersImportHard.c │ │ ├── HelpersJitSources.c │ │ ├── HelpersLists.c │ │ ├── HelpersListsGenerated.c │ │ ├── HelpersMappings.c │ │ ├── HelpersMatching.c │ │ ├── HelpersOperationBinaryAdd.c │ │ ├── HelpersOperationBinaryAddUtils.c │ │ ├── HelpersOperationBinaryBitand.c │ │ ├── HelpersOperationBinaryBitor.c │ │ ├── HelpersOperationBinaryBitxor.c │ │ ├── HelpersOperationBinaryDivmod.c │ │ ├── HelpersOperationBinaryDivmodUtils.c │ │ ├── HelpersOperationBinaryFloordiv.c │ │ ├── HelpersOperationBinaryInplaceAdd.c │ │ ├── HelpersOperationBinaryLshift.c │ │ ├── HelpersOperationBinaryMatmult.c │ │ ├── HelpersOperationBinaryMod.c │ │ ├── HelpersOperationBinaryMult.c │ │ ├── HelpersOperationBinaryMultUtils.c │ │ ├── HelpersOperationBinaryOlddiv.c │ │ ├── HelpersOperationBinaryPow.c │ │ ├── HelpersOperationBinaryPowUtils.c │ │ ├── HelpersOperationBinaryRshift.c │ │ ├── HelpersOperationBinarySub.c │ │ ├── HelpersOperationBinaryTruediv.c │ │ ├── HelpersOperationInplaceAdd.c │ │ ├── HelpersOperationInplaceAddUtils.c │ │ ├── HelpersOperationInplaceBitand.c │ │ ├── HelpersOperationInplaceBitor.c │ │ ├── HelpersOperationInplaceBitxor.c │ │ ├── HelpersOperationInplaceFloordiv.c │ │ ├── HelpersOperationInplaceLshift.c │ │ ├── HelpersOperationInplaceMatmult.c │ │ ├── HelpersOperationInplaceMod.c │ │ ├── HelpersOperationInplaceMult.c │ │ ├── HelpersOperationInplaceOlddiv.c │ │ ├── HelpersOperationInplacePow.c │ │ ├── HelpersOperationInplaceRshift.c │ │ ├── HelpersOperationInplaceSub.c │ │ ├── HelpersOperationInplaceTruediv.c │ │ ├── HelpersProfiling.c │ │ ├── HelpersPythonPgo.c │ │ ├── HelpersRaising.c │ │ ├── HelpersSafeStrings.c │ │ ├── HelpersSequences.c │ │ ├── HelpersSlices.c │ │ ├── HelpersStrings.c │ │ ├── HelpersTuples.c │ │ ├── HelpersTypes.c │ │ ├── InspectPatcher.c │ │ ├── MainProgram.c │ │ ├── MetaPathBasedLoader.c │ │ ├── MetaPathBasedLoaderImportlibMetadataDistribution.c │ │ ├── MetaPathBasedLoaderResourceReader.c │ │ ├── MetaPathBasedLoaderResourceReaderFiles.c │ │ ├── OnefileBootstrap.c │ │ └── OnefileSplashScreen.cpp │ ├── code_generation/ │ │ ├── AsyncgenCodes.py │ │ ├── AttributeCodes.py │ │ ├── BinaryOperationHelperDefinitions.py │ │ ├── BranchCodes.py │ │ ├── BuiltinCodes.py │ │ ├── CallCodes.py │ │ ├── ClassCodes.py │ │ ├── CodeGeneration.py │ │ ├── CodeHelperSelection.py │ │ ├── CodeHelpers.py │ │ ├── CodeObjectCodes.py │ │ ├── ComparisonCodes.py │ │ ├── ComparisonHelperDefinitions.py │ │ ├── ConditionalCodes.py │ │ ├── ConstantCodes.py │ │ ├── Contexts.py │ │ ├── CoroutineCodes.py │ │ ├── CtypesCodes.py │ │ ├── DictCodes.py │ │ ├── Emission.py │ │ ├── ErrorCodes.py │ │ ├── EvalCodes.py │ │ ├── ExceptionCodes.py │ │ ├── ExpressionCTypeSelectionHelpers.py │ │ ├── ExpressionCodes.py │ │ ├── FrameCodes.py │ │ ├── FunctionCodes.py │ │ ├── GeneratorCodes.py │ │ ├── GlobalConstants.py │ │ ├── GlobalsLocalsCodes.py │ │ ├── IdCodes.py │ │ ├── ImportCodes.py │ │ ├── Indentation.py │ │ ├── IndexCodes.py │ │ ├── InjectCCodes.py │ │ ├── IntegerCodes.py │ │ ├── IteratorCodes.py │ │ ├── LabelCodes.py │ │ ├── LineNumberCodes.py │ │ ├── ListCodes.py │ │ ├── LoaderCodes.py │ │ ├── LocalsDictCodes.py │ │ ├── LoopCodes.py │ │ ├── MatchCodes.py │ │ ├── ModuleCodes.py │ │ ├── Namify.py │ │ ├── OperationCodes.py │ │ ├── PackageResourceCodes.py │ │ ├── PrintCodes.py │ │ ├── PythonAPICodes.py │ │ ├── RaisingCodes.py │ │ ├── Reports.py │ │ ├── ReturnCodes.py │ │ ├── SetCodes.py │ │ ├── SliceCodes.py │ │ ├── StringCodes.py │ │ ├── SubscriptCodes.py │ │ ├── TensorflowCodes.py │ │ ├── TryCodes.py │ │ ├── TupleCodes.py │ │ ├── VariableCodes.py │ │ ├── VariableDeclarations.py │ │ ├── YieldCodes.py │ │ ├── __init__.py │ │ ├── c_types/ │ │ │ ├── CTypeBases.py │ │ │ ├── CTypeBooleans.py │ │ │ ├── CTypeCFloats.py │ │ │ ├── CTypeCLongs.py │ │ │ ├── CTypeModuleDictVariables.py │ │ │ ├── CTypeNuitkaBooleans.py │ │ │ ├── CTypeNuitkaInts.py │ │ │ ├── CTypeNuitkaVoids.py │ │ │ ├── CTypePyObjectPointers.py │ │ │ ├── CTypeVoids.py │ │ │ └── __init__.py │ │ ├── templates/ │ │ │ ├── CodeTemplatesAsyncgens.py │ │ │ ├── CodeTemplatesConstants.py │ │ │ ├── CodeTemplatesCoroutines.py │ │ │ ├── CodeTemplatesExceptions.py │ │ │ ├── CodeTemplatesFrames.py │ │ │ ├── CodeTemplatesFunction.py │ │ │ ├── CodeTemplatesGeneratorFunction.py │ │ │ ├── CodeTemplatesIterators.py │ │ │ ├── CodeTemplatesLoader.py │ │ │ ├── CodeTemplatesModules.py │ │ │ ├── CodeTemplatesVariables.py │ │ │ ├── TemplateDebugWrapper.py │ │ │ └── __init__.py │ │ └── templates_c/ │ │ ├── CodeTemplateCallsMethodPositional.c.j2 │ │ ├── CodeTemplateCallsMixed.c.j2 │ │ ├── CodeTemplateCallsPositional.c.j2 │ │ ├── CodeTemplateCallsPositionalMethodDescr.c.j2 │ │ ├── CodeTemplateMakeListHinted.c.j2 │ │ ├── CodeTemplateMakeListSmall.c.j2 │ │ ├── HelperBuiltinMethodOperation.c.j2 │ │ ├── HelperDictionaryCopy.c.j2 │ │ ├── HelperImportHard.c.j2 │ │ ├── HelperLongTools.c.j2 │ │ ├── HelperObjectTools.c.j2 │ │ ├── HelperOperationBinary.c.j2 │ │ ├── HelperOperationComparison.c.j2 │ │ ├── HelperOperationComparisonBytes.c.j2 │ │ ├── HelperOperationComparisonFloat.c.j2 │ │ ├── HelperOperationComparisonInt.c.j2 │ │ ├── HelperOperationComparisonList.c.j2 │ │ ├── HelperOperationComparisonLong.c.j2 │ │ ├── HelperOperationComparisonStr.c.j2 │ │ ├── HelperOperationComparisonTuple.c.j2 │ │ ├── HelperOperationComparisonUnicode.c.j2 │ │ ├── HelperOperationInplace.c.j2 │ │ ├── HelperSlotsBinary.c.j2 │ │ ├── HelperSlotsBytes.c.j2 │ │ ├── HelperSlotsCommon.c.j2 │ │ ├── HelperSlotsFloat.c.j2 │ │ ├── HelperSlotsInt.c.j2 │ │ ├── HelperSlotsList.c.j2 │ │ ├── HelperSlotsLong.c.j2 │ │ ├── HelperSlotsSet.c.j2 │ │ ├── HelperSlotsStr.c.j2 │ │ ├── HelperSlotsTuple.c.j2 │ │ └── HelperSlotsUnicode.c.j2 │ ├── containers/ │ │ ├── Namedtuples.py │ │ ├── OrderedDicts.py │ │ ├── OrderedSets.py │ │ ├── OrderedSetsFallback.py │ │ └── __init__.py │ ├── distutils/ │ │ ├── Build.py │ │ ├── DistutilCommands.py │ │ └── __init__.py │ ├── finalizations/ │ │ ├── Finalization.py │ │ ├── FinalizeMarkups.py │ │ └── __init__.py │ ├── freezer/ │ │ ├── DependsExe.py │ │ ├── DllDependenciesCommon.py │ │ ├── DllDependenciesMacOS.py │ │ ├── DllDependenciesPosix.py │ │ ├── DllDependenciesWin32.py │ │ ├── ImportDetection.py │ │ ├── IncludedDataFiles.py │ │ ├── IncludedEntryPoints.py │ │ ├── Onefile.py │ │ ├── Standalone.py │ │ └── __init__.py │ ├── importing/ │ │ ├── IgnoreListing.py │ │ ├── ImportCache.py │ │ ├── ImportResolving.py │ │ ├── Importing.py │ │ ├── PreloadedPackages.py │ │ ├── Recursion.py │ │ ├── StandardLibrary.py │ │ └── __init__.py │ ├── nodes/ │ │ ├── AsyncgenNodes.py │ │ ├── AttributeLookupNodes.py │ │ ├── AttributeNodes.py │ │ ├── AttributeNodesGenerated.py │ │ ├── BuiltinAllNodes.py │ │ ├── BuiltinAnyNodes.py │ │ ├── BuiltinComplexNodes.py │ │ ├── BuiltinDecodingNodes.py │ │ ├── BuiltinDecoratorNodes.py │ │ ├── BuiltinDictNodes.py │ │ ├── BuiltinFormatNodes.py │ │ ├── BuiltinHashNodes.py │ │ ├── BuiltinInputNodes.py │ │ ├── BuiltinIntegerNodes.py │ │ ├── BuiltinIteratorNodes.py │ │ ├── BuiltinLenNodes.py │ │ ├── BuiltinNextNodes.py │ │ ├── BuiltinOpenNodes.py │ │ ├── BuiltinOperationNodeBasesGenerated.py │ │ ├── BuiltinRangeNodes.py │ │ ├── BuiltinRefNodes.py │ │ ├── BuiltinSumNodes.py │ │ ├── BuiltinTypeNodes.py │ │ ├── BuiltinVarsNodes.py │ │ ├── BytesNodes.py │ │ ├── CallNodes.py │ │ ├── Checkers.py │ │ ├── ChildrenHavingMixins.py │ │ ├── ClassNodes.py │ │ ├── CodeObjectSpecs.py │ │ ├── ComparisonNodes.py │ │ ├── ConditionalNodes.py │ │ ├── ConstantRefNodes.py │ │ ├── ContainerMakingNodes.py │ │ ├── ContainerOperationNodes.py │ │ ├── CoroutineNodes.py │ │ ├── CtypesNodes.py │ │ ├── DictionaryNodes.py │ │ ├── ExceptionNodes.py │ │ ├── ExecEvalNodes.py │ │ ├── ExpressionBases.py │ │ ├── ExpressionBasesGenerated.py │ │ ├── ExpressionShapeMixins.py │ │ ├── FrameNodes.py │ │ ├── FunctionAttributeNodes.py │ │ ├── FunctionNodes.py │ │ ├── FutureSpecs.py │ │ ├── GeneratorNodes.py │ │ ├── GlobalsLocalsNodes.py │ │ ├── HardImportNodesGenerated.py │ │ ├── ImportHardNodes.py │ │ ├── ImportNodes.py │ │ ├── IndicatorMixins.py │ │ ├── InjectCNodes.py │ │ ├── IterationHandles.py │ │ ├── KeyValuePairNodes.py │ │ ├── ListOperationNodes.py │ │ ├── LocalsDictNodes.py │ │ ├── LocalsScopes.py │ │ ├── LoopNodes.py │ │ ├── MatchNodes.py │ │ ├── ModuleAttributeNodes.py │ │ ├── ModuleNodes.py │ │ ├── NodeBases.py │ │ ├── NodeMakingHelpers.py │ │ ├── NodeMetaClasses.py │ │ ├── OperatorNodes.py │ │ ├── OperatorNodesUnary.py │ │ ├── OsSysNodes.py │ │ ├── OutlineNodes.py │ │ ├── PackageMetadataNodes.py │ │ ├── PackageResourceNodes.py │ │ ├── PrintNodes.py │ │ ├── ReturnNodes.py │ │ ├── SideEffectNodes.py │ │ ├── SliceNodes.py │ │ ├── StatementBasesGenerated.py │ │ ├── StatementNodes.py │ │ ├── StrNodes.py │ │ ├── StringConcatenationNodes.py │ │ ├── SubscriptNodes.py │ │ ├── TensorflowNodes.py │ │ ├── TryNodes.py │ │ ├── TypeMatchNodes.py │ │ ├── TypeNodes.py │ │ ├── VariableAssignNodes.py │ │ ├── VariableDelNodes.py │ │ ├── VariableNameNodes.py │ │ ├── VariableRefNodes.py │ │ ├── VariableReleaseNodes.py │ │ ├── YieldNodes.py │ │ ├── __init__.py │ │ └── shapes/ │ │ ├── BuiltinTypeShapes.py │ │ ├── ControlFlowDescriptions.py │ │ ├── ShapeMixins.py │ │ ├── StandardShapes.py │ │ └── __init__.py │ ├── optimizations/ │ │ ├── BytecodeDemotion.py │ │ ├── FunctionInlining.py │ │ ├── Graphs.py │ │ ├── Optimization.py │ │ ├── OptimizeBuiltinCalls.py │ │ ├── Tags.py │ │ ├── TraceCollections.py │ │ ├── ValueTraces.py │ │ └── __init__.py │ ├── pgo/ │ │ ├── PGO.py │ │ └── __init__.py │ ├── plugins/ │ │ ├── PluginBase.py │ │ ├── Plugins.py │ │ ├── __init__.py │ │ └── standard/ │ │ ├── AntiBloatPlugin.py │ │ ├── ConsiderPyLintAnnotationsPlugin.py │ │ ├── DataFilesPlugin.py │ │ ├── DelvewheelPlugin.py │ │ ├── DillPlugin/ │ │ │ ├── DillPlugin.c │ │ │ └── dill-postLoad.py │ │ ├── DillPlugin.py │ │ ├── DllFilesPlugin.py │ │ ├── EnumPlugin.py │ │ ├── EventletPlugin.py │ │ ├── GeventPlugin.py │ │ ├── GiPlugin.py │ │ ├── GlfwPlugin.py │ │ ├── ImplicitImports.py │ │ ├── KivyPlugin.py │ │ ├── MatplotlibPlugin.py │ │ ├── MultiprocessingPlugin.py │ │ ├── NumpyPlugin.py │ │ ├── OptionsNannyPlugin.py │ │ ├── PbrPlugin.py │ │ ├── PkgResourcesPlugin.py │ │ ├── PmwPlugin.py │ │ ├── PySidePyQtPlugin.py │ │ ├── PywebViewPlugin.py │ │ ├── TensorflowPlugin.py │ │ ├── TkinterPlugin.py │ │ ├── TorchPlugin.py │ │ ├── TransformersPlugin.py │ │ ├── TrioPlugin.py │ │ ├── UpxPlugin.py │ │ ├── __init__.py │ │ ├── standard.nuitka-package.config.yml │ │ ├── stdlib2.nuitka-package.config.yml │ │ └── stdlib3.nuitka-package.config.yml │ ├── reports/ │ │ ├── CompilationReportReader.py │ │ ├── LicenseReport.rst.j2 │ │ ├── Reports.py │ │ └── __init__.py │ ├── specs/ │ │ ├── BuiltinBytesOperationSpecs.py │ │ ├── BuiltinDictOperationSpecs.py │ │ ├── BuiltinListOperationSpecs.py │ │ ├── BuiltinParameterSpecs.py │ │ ├── BuiltinStrOperationSpecs.py │ │ ├── BuiltinTypeOperationSpecs.py │ │ ├── BuiltinUnicodeOperationSpecs.py │ │ ├── HardImportSpecs.py │ │ ├── ParameterSpecs.py │ │ └── __init__.py │ ├── tools/ │ │ ├── Basics.py │ │ ├── __init__.py │ │ ├── commercial/ │ │ │ └── __init__.py │ │ ├── data_composer/ │ │ │ ├── DataComposer.py │ │ │ ├── __init__.py │ │ │ └── __main__.py │ │ ├── environments/ │ │ │ ├── CreateEnvironment.py │ │ │ ├── Virtualenv.py │ │ │ └── __init__.py │ │ ├── general/ │ │ │ ├── __init__.py │ │ │ ├── dll_report/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ └── find_module/ │ │ │ ├── FindModuleCode.py │ │ │ └── __init__.py │ │ ├── onefile_compressor/ │ │ │ ├── OnefileCompressor.py │ │ │ ├── __init__.py │ │ │ └── __main__.py │ │ ├── podman/ │ │ │ ├── Podman.py │ │ │ ├── __init__.py │ │ │ ├── __main__.py │ │ │ └── containers/ │ │ │ ├── CI.containerfile │ │ │ └── Python-Minor-Versions.containerfile │ │ ├── profiler/ │ │ │ ├── __init__.py │ │ │ └── __main__.py │ │ ├── quality/ │ │ │ ├── Git.py │ │ │ ├── ScanSources.py │ │ │ ├── __init__.py │ │ │ ├── apidoc/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ ├── auto_format/ │ │ │ │ ├── AutoFormat.py │ │ │ │ ├── YamlFormatter.py │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ ├── codespell/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ ├── pylint/ │ │ │ │ ├── PyLint.py │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ ├── restlint/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ └── yamllint/ │ │ │ ├── YamlChecker.py │ │ │ ├── __init__.py │ │ │ └── __main__.py │ │ ├── release/ │ │ │ ├── Debian.py │ │ │ ├── Documentation.py │ │ │ ├── Release.py │ │ │ ├── __init__.py │ │ │ ├── bump/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ ├── debian/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ ├── debian_mentors/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ ├── osc_check/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ ├── osc_upload/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ ├── pypi/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ ├── rpm/ │ │ │ │ ├── __init__.py │ │ │ │ ├── __main__.py │ │ │ │ └── nuitka.spec │ │ │ └── sync_doc/ │ │ │ ├── __init__.py │ │ │ └── __main__.py │ │ ├── scanning/ │ │ │ ├── DisplayPackageDLLs.py │ │ │ ├── DisplayPackageData.py │ │ │ └── __init__.py │ │ ├── specialize/ │ │ │ ├── CTypeDescriptions.py │ │ │ ├── Common.py │ │ │ ├── SpecializeC.py │ │ │ ├── SpecializePython.py │ │ │ ├── __init__.py │ │ │ └── templates_python/ │ │ │ ├── AttributeNodeFixed.py.j2 │ │ │ ├── BuiltinOperationNodeBases.py.j2 │ │ │ ├── ChildrenHavingMixin.py.j2 │ │ │ ├── HardImportCallNode.py.j2 │ │ │ └── HardImportReferenceNode.py.j2 │ │ ├── testing/ │ │ │ ├── Common.py │ │ │ ├── Constructs.py │ │ │ ├── OutputComparison.py │ │ │ ├── Pythons.py │ │ │ ├── RuntimeTracing.py │ │ │ ├── SearchModes.py │ │ │ ├── Valgrind.py │ │ │ ├── __init__.py │ │ │ ├── check_reference_counts/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ ├── compare_with_cpython/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ ├── find_sxs_modules/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ ├── measure_construct_performance/ │ │ │ │ ├── __init__.py │ │ │ │ └── __main__.py │ │ │ └── run_nuitka_tests/ │ │ │ ├── __init__.py │ │ │ └── __main__.py │ │ └── watch/ │ │ ├── GitHub.py │ │ ├── __init__.py │ │ └── __main__.py │ ├── tree/ │ │ ├── Building.py │ │ ├── ComplexCallHelperFunctions.py │ │ ├── Extractions.py │ │ ├── InternalModule.py │ │ ├── Operations.py │ │ ├── ReformulationAssertStatements.py │ │ ├── ReformulationAssignmentStatements.py │ │ ├── ReformulationBooleanExpressions.py │ │ ├── ReformulationCallExpressions.py │ │ ├── ReformulationClasses.py │ │ ├── ReformulationClasses3.py │ │ ├── ReformulationComparisonExpressions.py │ │ ├── ReformulationContractionExpressions.py │ │ ├── ReformulationDictionaryCreation.py │ │ ├── ReformulationExecStatements.py │ │ ├── ReformulationForLoopStatements.py │ │ ├── ReformulationFunctionStatements.py │ │ ├── ReformulationImportStatements.py │ │ ├── ReformulationLambdaExpressions.py │ │ ├── ReformulationMatchStatements.py │ │ ├── ReformulationMultidist.py │ │ ├── ReformulationNamespacePackages.py │ │ ├── ReformulationPrintStatements.py │ │ ├── ReformulationSequenceCreation.py │ │ ├── ReformulationSubscriptExpressions.py │ │ ├── ReformulationTryExceptStatements.py │ │ ├── ReformulationTryFinallyStatements.py │ │ ├── ReformulationWhileLoopStatements.py │ │ ├── ReformulationWithStatements.py │ │ ├── ReformulationYieldExpressions.py │ │ ├── SourceHandling.py │ │ ├── SyntaxErrors.py │ │ ├── TreeHelpers.py │ │ ├── VariableClosure.py │ │ └── __init__.py │ └── utils/ │ ├── AppDirs.py │ ├── CStrings.py │ ├── CommandLineOptions.py │ ├── Distributions.py │ ├── Download.py │ ├── Execution.py │ ├── FileOperations.py │ ├── Hashing.py │ ├── Images.py │ ├── Importing.py │ ├── InstalledPythons.py │ ├── InstanceCounters.py │ ├── Jinja2.py │ ├── Json.py │ ├── MacOSApp.py │ ├── MemoryUsage.py │ ├── ModuleNames.py │ ├── ReExecute.py │ ├── Rest.py │ ├── SharedLibraries.py │ ├── Shebang.py │ ├── Signing.py │ ├── SlotMetaClasses.py │ ├── StaticLibraries.py │ ├── ThreadedExecutor.py │ ├── Timing.py │ ├── Utils.py │ ├── WindowsFileUsage.py │ ├── WindowsResources.py │ ├── Yaml.py │ └── __init__.py ├── pyproject.toml ├── requirements-devel.txt ├── requirements.txt ├── rpm/ │ ├── check-osc-status.py │ ├── make-osc-upload.py │ ├── nuitka-rpmlintrc │ └── nuitka.spec ├── setup.py └── tests/ ├── PyPI-pytest/ │ ├── README.rst │ ├── packages.json │ └── run_all.py ├── README.txt ├── basics/ │ ├── AssertsTest.py │ ├── AssignmentsTest.py │ ├── AssignmentsTest32.py │ ├── BranchingTest.py │ ├── BuiltinOverload.py │ ├── BuiltinSuperTest.py │ ├── BuiltinsTest.py │ ├── ClassMinimalTest.py │ ├── ClassesTest.py │ ├── ClassesTest32.py │ ├── ClassesTest34.py │ ├── ComparisonChainsTest.py │ ├── ConstantsTest.py │ ├── ConstantsTest27.py │ ├── DecoratorsTest.py │ ├── DefaultParametersTest.py │ ├── DoubleDeletionsTest.py │ ├── EmptyModuleTest.py │ ├── ExceptionRaisingTest.py │ ├── ExceptionRaisingTest32.py │ ├── ExceptionRaisingTest33.py │ ├── ExecEvalTest.py │ ├── ExtremeClosureTest.py │ ├── FunctionObjectsTest.py │ ├── FunctionsTest.py │ ├── FunctionsTest32.py │ ├── FunctionsTest_2.py │ ├── FutureTest32.py │ ├── GeneratorExpressionsTest.py │ ├── GeneratorExpressionsTest_37.py │ ├── GlobalStatementTest.py │ ├── HelloWorldTest_2.py │ ├── ImportingTest.py │ ├── InplaceOperationsTest.py │ ├── InspectionTest.py │ ├── InspectionTest_35.py │ ├── InspectionTest_36.py │ ├── LambdasTest.py │ ├── LateClosureAssignmentTest.py │ ├── ListContractionsTest.py │ ├── LoopingTest.py │ ├── MainProgramsTest.py │ ├── ModuleAttributesTest.py │ ├── OperatorsTest.py │ ├── OrderChecksTest.py │ ├── OrderChecksTest27.py │ ├── OverflowFunctionsTest_2.py │ ├── ParameterErrorsTest.py │ ├── ParameterErrorsTest32.py │ ├── PrintFutureTest.py │ ├── PrintingTest_2.py │ ├── README.rst │ ├── RecursionTest.py │ ├── ReferencingTest.py │ ├── ReferencingTest27.py │ ├── ReferencingTest33.py │ ├── ReferencingTest35.py │ ├── ReferencingTest36.py │ ├── ReferencingTest_2.py │ ├── SlotsTest.py │ ├── ThreadedGeneratorsTest.py │ ├── TrickAssignmentsTest32.py │ ├── TrickAssignmentsTest35.py │ ├── TrickAssignmentsTest_2.py │ ├── TryContinueFinallyTest.py │ ├── TryExceptContinueTest.py │ ├── TryExceptFinallyTest.py │ ├── TryExceptFramesTest.py │ ├── TryReturnFinallyTest.py │ ├── TryYieldFinallyTest.py │ ├── UnicodeTest.py │ ├── UnpackingTest35.py │ ├── VarargsTest.py │ ├── WithStatementsTest.py │ ├── YieldFromTest33.py │ ├── run_all.py │ └── run_xml.py ├── benchmarks/ │ ├── binary-trees.py │ ├── comparisons/ │ │ └── GeneratorFunctionVsGeneratorExpression.py │ ├── constructs/ │ │ ├── BuiltinSumWithGenerator.py │ │ ├── BuiltinSumWithList.py │ │ ├── BuiltinSumWithTuple.py │ │ ├── CallCompiledClassCreationPosArgsConstant6.py │ │ ├── CallCompiledFunctionKwArgsConstant.py │ │ ├── CallCompiledFunctionKwArgsVariable.py │ │ ├── CallCompiledFunctionKwArgsVariableStarDict.py │ │ ├── CallCompiledFunctionPosArgsConstant.py │ │ ├── CallCompiledFunctionPosArgsDefaults.py │ │ ├── CallCompiledFunctionPosArgsMutable.py │ │ ├── CallCompiledFunctionPosArgsVariable.py │ │ ├── CallCompiledFunctionPosKwArgsVariable.py │ │ ├── CallCompiledInstanceMethodNoArgs_27.py │ │ ├── CallCompiledInstanceMethodPosArgsConstant1_27.py │ │ ├── CallCompiledInstanceMethodPosArgsConstant6_27.py │ │ ├── CallCompiledInstanceMethodPosArgsDefaults_27.py │ │ ├── CallCompiledInstanceMethodPosArgsVariable_27.py │ │ ├── CallCompiledObjectMethodNoArgs.py │ │ ├── CallCompiledObjectMethodPosArgsConstant1.py │ │ ├── CallCompiledObjectMethodPosArgsConstant6.py │ │ ├── CallCompiledObjectMethodPosArgsDefaults.py │ │ ├── CallCompiledObjectMethodPosArgsVariable.py │ │ ├── CallLambdaExpressionDirectly.py │ │ ├── CallUncompiledFunctionComplexArgs.py │ │ ├── CallUncompiledFunctionPosArgs.py │ │ ├── ClosureVariableAccess.py │ │ ├── DictCreation.py │ │ ├── FunctionCreationClosure.py │ │ ├── FunctionCreationGeneratorClosure.py │ │ ├── FunctionCreationGeneratorLocal.py │ │ ├── FunctionCreationLocal.py │ │ ├── FunctionEmpty.py │ │ ├── FunctionRaise.py │ │ ├── GeneratorExit.py │ │ ├── GeneratorExpressionCreation.py │ │ ├── GeneratorExpressionExit.py │ │ ├── GeneratorExpressionUsage.py │ │ ├── GeneratorUsage.py │ │ ├── GlobalVariableAccess.py │ │ ├── InplaceOperationFloatAdd.py │ │ ├── InplaceOperationInstanceStringAdd.py │ │ ├── InplaceOperationIntegerAdd.py │ │ ├── InplaceOperationIntegerMul.py │ │ ├── InplaceOperationListAdd.py │ │ ├── InplaceOperationLongAdd_27.py │ │ ├── InplaceOperationStringAdd.py │ │ ├── InplaceOperationTupleAdd.py │ │ ├── InplaceOperationUnicodeAdd_27.py │ │ ├── ListContraction.py │ │ ├── ListCreation.py │ │ ├── ListCreationConstant.py │ │ ├── LocalVariableAccess.py │ │ ├── LocalVariableDeletion.py │ │ ├── LoopSmallRange.py │ │ ├── LoopSmallXrange.py │ │ ├── NumpyArrayConstruction.py │ │ ├── OperationAttributeLookup.py │ │ ├── OperationFloatAdd.py │ │ ├── OperationIntegerAdd.py │ │ ├── OperationIntegerMul.py │ │ ├── OperationIntegerPower.py │ │ ├── OperationListIntegerIndexLookup.py │ │ ├── RichComparisonConditionStrings.py │ │ ├── RichComparisonStrings.py │ │ ├── SetCreation.py │ │ ├── TupleCreation.py │ │ └── UnpackIterator.py │ ├── mandelbrot.py │ ├── pybench/ │ │ ├── Arithmetic.py │ │ ├── Calls.py │ │ ├── CommandLine.py │ │ ├── Constructs.py │ │ ├── Dict.py │ │ ├── Exceptions.py │ │ ├── Imports.py │ │ ├── Instances.py │ │ ├── LICENSE │ │ ├── Lists.py │ │ ├── Lookups.py │ │ ├── NewInstances.py │ │ ├── Numbers.py │ │ ├── README │ │ ├── Setup.py │ │ ├── Strings.py │ │ ├── Tuples.py │ │ ├── Unicode.py │ │ ├── With.py │ │ ├── clockres.py │ │ ├── package/ │ │ │ ├── __init__.py │ │ │ └── submodule.py │ │ ├── pybench.py │ │ └── systimes.py │ ├── pystone.py │ ├── pystone3.py │ └── recipe-577834-1.py ├── codegen-analysis/ │ └── README.txt ├── distutils/ │ ├── .gitignore │ ├── example_1_pyproject/ │ │ ├── data_files/ │ │ │ └── some_datafile.txt │ │ ├── example1_package/ │ │ │ ├── __init__.py │ │ │ └── data/ │ │ │ └── package_data.txt │ │ ├── pyproject.cpython.toml │ │ ├── pyproject.nuitka.toml │ │ ├── runner │ │ └── setup.cfg │ ├── example_1_setuptools/ │ │ ├── data_files/ │ │ │ └── some_datafile.txt │ │ ├── example1_package/ │ │ │ ├── __init__.py │ │ │ └── data/ │ │ │ └── package_data.txt │ │ ├── runner │ │ └── setup.py │ ├── example_2_pyproject/ │ │ ├── pyproject.cpython.toml │ │ ├── pyproject.nuitka.toml │ │ └── src/ │ │ └── main.py │ ├── example_2_setuptools/ │ │ ├── package1/ │ │ │ ├── __init__.py │ │ │ ├── main.py │ │ │ ├── module1.py │ │ │ ├── module2.py │ │ │ ├── subpackage1/ │ │ │ │ ├── __init__.py │ │ │ │ ├── data.txt │ │ │ │ └── submodule11.py │ │ │ └── subpackage2/ │ │ │ ├── __init__.py │ │ │ └── submodule21.py │ │ └── setup.py │ ├── example_3_pyproject/ │ │ ├── pyproject.cpython.toml │ │ ├── pyproject.nuitka.toml │ │ └── src/ │ │ ├── runner │ │ └── some_namespace/ │ │ └── some_package/ │ │ ├── __init__.py │ │ └── sub_package/ │ │ └── __init__.py │ ├── example_3_setuptools32/ │ │ ├── outer/ │ │ │ └── inner/ │ │ │ ├── __init__.py │ │ │ └── main.py │ │ └── setup.py │ ├── example_4_setuptools_cfg/ │ │ ├── data_files/ │ │ │ └── some_datafile.txt │ │ ├── example1_package/ │ │ │ ├── __init__.py │ │ │ └── data/ │ │ │ └── package_data.txt │ │ ├── runner │ │ ├── setup.cfg │ │ └── setup.py │ ├── example_5_versioneer_setuptools32/ │ │ ├── runner │ │ ├── setup.cfg │ │ ├── setup.py │ │ ├── some_package/ │ │ │ ├── __init__.py │ │ │ └── _version.py │ │ └── versioneer.py │ ├── example_multiple_packages/ │ │ ├── main_module.py │ │ ├── other_package/ │ │ │ └── __init__.py │ │ ├── other_package_a/ │ │ │ └── __init__.py │ │ ├── runner │ │ ├── setup.py │ │ ├── some_package/ │ │ │ └── __init__.py │ │ ├── some_package_a/ │ │ │ └── __init__.py │ │ └── some_package_b/ │ │ └── __init__.py │ ├── example_nested_namespaces32/ │ │ ├── a/ │ │ │ └── b/ │ │ │ └── pkg/ │ │ │ └── __init__.py │ │ └── setup.py │ ├── example_package_and_module/ │ │ ├── runner │ │ ├── setup.py │ │ ├── some_module.py │ │ └── some_package/ │ │ └── __init__.py │ ├── example_pymodules_only/ │ │ ├── py_modules_only.py │ │ ├── runner │ │ └── setup.py │ └── run_all.py ├── generated/ │ ├── BigConstantsTest.py.j2 │ ├── BytesMethodsTest.py.j2 │ ├── BytesMethodsTest32.py.j2 │ ├── DictMethodsTest.py.j2 │ ├── InplaceTest.py.j2 │ ├── OperationsTest.py.j2 │ ├── StrMethodsTest.py.j2 │ └── run_all.py ├── library/ │ ├── check_yaml_anti_bloat_modules.py │ ├── compile_extension_modules.py │ └── compile_python_modules.py ├── onefile/ │ ├── HelloWorldTest.py │ ├── KeyboardInterruptTest.py │ └── run_all.py ├── optimizations/ │ ├── ArgumentTypes.py │ ├── AttributesTest.py │ ├── CallsTest.py │ ├── ConditionsTest.py │ ├── DecodingOperationsTest.py │ ├── FormatStringsTest36.py │ ├── HardImportsTest.py │ ├── HardImportsTest_2.py │ ├── Iterations.py │ ├── LenTest.py │ ├── MatchingTest310.py │ ├── OperationsTest.py │ ├── SubscriptsTest.py │ └── run_all.py ├── packages/ │ ├── package_data_files_embedding/ │ │ ├── PackageDataFilesEmbedding.py │ │ ├── __init__.py │ │ ├── lala.txt │ │ └── sub_dir/ │ │ └── lulu.txt │ ├── package_import_success_after_failure/ │ │ ├── PackageImportSuccessAfterFailure.py │ │ └── variable_package/ │ │ ├── SomeModule.py │ │ └── __init__.py │ ├── run_all.py │ ├── sub_package/ │ │ └── kitty/ │ │ ├── __init__.py │ │ ├── bigkitty.py │ │ ├── smallkitty.py │ │ └── speak/ │ │ ├── __init__.py │ │ ├── hello.py │ │ ├── miau.py │ │ └── purr.py │ └── top_level_attributes_3/ │ └── some_package/ │ ├── __init__.py │ └── some_module.py ├── pgo/ │ ├── run_all.py │ └── unused_module/ │ ├── ImportedButMaybeNotUsed.py │ └── UnusedModuleMain.py ├── plugins/ │ ├── README.rst │ ├── code_signing/ │ │ └── CodeSigningMain.py │ ├── data_files/ │ │ ├── DataFilesMain.py │ │ ├── data_files_package/ │ │ │ ├── __init__.py │ │ │ ├── lala.txt │ │ │ └── sub_dir/ │ │ │ └── lulu.txt │ │ └── test_case.nuitka-package.config.yml │ ├── parameters/ │ │ ├── ParametersMain.py │ │ └── parameter-using-plugin.py │ └── run_all.py ├── programs/ │ ├── absolute_import/ │ │ ├── AbsoluteImportMain.py │ │ └── foobar/ │ │ ├── __init__.py │ │ ├── foobar.py │ │ ├── local.py │ │ └── util.py │ ├── case_imports1/ │ │ ├── CasedImportingMain.py │ │ ├── path1/ │ │ │ ├── Some_Module.py │ │ │ └── Some_Package/ │ │ │ └── __init__.py │ │ └── path2/ │ │ ├── some_module.py │ │ └── some_package/ │ │ └── __init__.py │ ├── case_imports2/ │ │ ├── CasedImportingMain.py │ │ ├── path1/ │ │ │ ├── some_module.py │ │ │ └── some_package/ │ │ │ └── __init__.py │ │ └── path2/ │ │ ├── Some_Module.py │ │ └── Some_Package/ │ │ └── __init__.py │ ├── case_imports3/ │ │ ├── CasedImportingMain.py │ │ ├── path1/ │ │ │ ├── Some_Module.py │ │ │ └── Some_Package/ │ │ │ └── __init__.py │ │ └── path2/ │ │ ├── Some_Module.py │ │ └── Some_Package/ │ │ └── __init__.py │ ├── cyclic_imports/ │ │ ├── CyclicImportsMain.py │ │ └── cyclic_importing_package/ │ │ ├── Child1.py │ │ ├── Child2.py │ │ └── __init__.py │ ├── dash_import/ │ │ ├── DashImportMain.py │ │ ├── dash-module.py │ │ └── plus+module.py │ ├── dash_main/ │ │ └── Dash-Main.py │ ├── deep/ │ │ ├── DeepProgramMain.py │ │ └── some_package/ │ │ ├── DeepBrother.py │ │ ├── DeepChild.py │ │ ├── __init__.py │ │ └── deep_package/ │ │ ├── DeepDeepChild.py │ │ └── __init__.py │ ├── dunderinit_imports/ │ │ ├── DunderInitImportsMain.py │ │ └── package/ │ │ ├── SubModule.py │ │ └── __init__.py │ ├── import_variants/ │ │ ├── ImportVariationsMain.py │ │ └── some_package/ │ │ ├── Child1.py │ │ ├── Child2.py │ │ ├── Child3.py │ │ └── __init__.py │ ├── main_raises/ │ │ ├── ErrorMain.py │ │ └── ErrorRaising.py │ ├── main_raises2/ │ │ ├── ErrorInFunctionMain.py │ │ └── ErrorRaising.py │ ├── module_attributes/ │ │ ├── ModuleAttributesMain.py │ │ └── package_level1/ │ │ ├── Nearby1.py │ │ ├── __init__.py │ │ └── package_level2/ │ │ ├── Nearby2.py │ │ ├── __init__.py │ │ └── package_level3/ │ │ ├── Nearby3.py │ │ └── __init__.py │ ├── module_exits/ │ │ ├── ErrorExitingModule.py │ │ └── Main.py │ ├── module_object_replacing/ │ │ ├── ModuleObjectReplacingMain.py │ │ └── SelfReplacingModule.py │ ├── multiprocessing_using/ │ │ ├── MultiprocessingUsingMain.py │ │ └── foo/ │ │ ├── __init__.py │ │ ├── __main__.py │ │ └── entry.py │ ├── named_imports/ │ │ ├── NamedImportsMain.py │ │ └── some_package/ │ │ ├── SomeModule.py │ │ ├── __init__.py │ │ └── sub_package/ │ │ └── SomeModule.py │ ├── package_code/ │ │ ├── PackageInitCodeMain.py │ │ └── some_package/ │ │ ├── SomeModule.py │ │ └── __init__.py │ ├── package_contains_main/ │ │ ├── PackageContainsMain.py │ │ ├── __init__.py │ │ └── local.py │ ├── package_init_import/ │ │ ├── PackageInitImportMain.py │ │ └── some_package/ │ │ ├── PackageLocal.py │ │ └── __init__.py │ ├── package_init_issue/ │ │ ├── PackageInitIssueMain.py │ │ └── some_package/ │ │ ├── __init__.py │ │ └── child_package/ │ │ ├── SomeModule.py │ │ └── __init__.py │ ├── package_missing_init/ │ │ ├── PackageMissingInitMain.py │ │ └── some_package/ │ │ ├── some_module.py │ │ └── sub_package/ │ │ └── some_sub_module.py │ ├── package_module_collision/ │ │ ├── PackageAndModuleNamedSameMain.py │ │ ├── Something/ │ │ │ └── __init__.py │ │ └── something.py │ ├── package_overload/ │ │ ├── Main.py │ │ └── foo/ │ │ ├── __init__.py │ │ ├── bar.py │ │ └── bar2.py │ ├── package_prevents_submodule/ │ │ ├── PackagePreventsSubmoduleMain.py │ │ └── some_package/ │ │ ├── __init__.py │ │ └── some_module.py │ ├── package_program/ │ │ └── PackageAsMain/ │ │ ├── __init__.py │ │ └── __main__.py │ ├── pkgutil_itermodules/ │ │ ├── PkgUtilIterModulesMain.py │ │ └── some_package/ │ │ ├── __init__.py │ │ ├── sub_package1/ │ │ │ ├── SomeModuleC.py │ │ │ ├── SomeModuleD.py │ │ │ └── __init__.py │ │ └── sub_package2/ │ │ ├── SomeModuleA.py │ │ ├── SomeModuleB.py │ │ └── __init__.py │ ├── pkgutil_usage/ │ │ ├── PkgUtilUsageMain.py │ │ └── package/ │ │ ├── DATA_FILE.txt │ │ ├── DATA_FILE2.txt │ │ ├── DATA_FILE3.txt │ │ └── __init__.py │ ├── plugin_import/ │ │ ├── PluginImportMain.py │ │ └── some_package/ │ │ ├── __init__.py │ │ ├── data/ │ │ │ └── .gitignore │ │ └── some_module.py │ ├── reimport_main_dynamic/ │ │ └── ImportItselfDynamicMain.py │ ├── reimport_main_static/ │ │ └── ImportItselfStaticMain.py │ ├── relative_import/ │ │ ├── RelativeImportMain.py │ │ └── dircache.py │ ├── resource_reader37/ │ │ ├── ResourceReaderMain.py │ │ └── some_package/ │ │ ├── DATA_FILE.txt │ │ └── __init__.py │ ├── run_all.py │ ├── stdlib_overload/ │ │ ├── StdlibOverloadMain.py │ │ ├── pyexpat.py │ │ └── some_package/ │ │ ├── __init__.py │ │ ├── normal_importing.py │ │ ├── pyexpat.py │ │ └── star_importing.py │ ├── syntax_errors/ │ │ ├── IndentationErroring.py │ │ ├── SyntaxErroring.py │ │ └── SyntaxErrorsMain.py │ ├── unicode_bom/ │ │ ├── UnicodeBomMain.py │ │ └── unicode_bom.py │ └── with space/ │ └── Space Main.py ├── reflected/ │ └── compile_itself.py ├── run-tests ├── standalone/ │ ├── BrotliUsing.py │ ├── CtypesUsing.py │ ├── DateutilsUsing.py │ ├── FlaskUsing.py │ ├── GiUsing.py │ ├── GlfwUsing.py │ ├── GtkUsing.py │ ├── HexEncodingTest_2.py │ ├── IdnaUsing.py │ ├── LxmlUsing.py │ ├── MatplotlibUsing.py │ ├── MetadataPackagesUsing.py │ ├── NumpyUsing.py │ ├── OpenGLUsing.py │ ├── PandasUsing.py │ ├── PasslibUsing.py │ ├── PendulumUsing.py │ ├── PkgResourcesRequiresUsing.py │ ├── PmwUsing.py │ ├── PyQt5Plugins.py │ ├── PyQt5SSLSupport.py │ ├── PyQt5Using.py │ ├── PyQt6Plugins.py │ ├── PyQt6Using.py │ ├── PySide2Using.py │ ├── PySide6Plugins.py │ ├── PySide6Using.py │ ├── RsaUsing.py │ ├── SetuptoolsUsing.py │ ├── ShlibUsing.py │ ├── SocketUsing.py │ ├── TkInterUsing.py │ ├── Urllib3Using.py │ ├── Win32ComUsing.py │ ├── run_all.py │ └── zip_importer/ │ └── ZipImporterMain.py ├── syntax/ │ ├── AsyncgenReturn36.py │ ├── AwaitInModule36.py │ ├── BreakWithoutLoop.py │ ├── ClassReturn.py │ ├── ClosureDel_2.py │ ├── ContinueWithoutLoop.py │ ├── DuplicateArgument.py │ ├── ExecWithNesting_2.py │ ├── FutureBraces.py │ ├── FutureUnknown.py │ ├── GeneratorExpressions38.py │ ├── GeneratorReturn_2.py │ ├── GlobalForParameter.py │ ├── Importing32.py │ ├── IndentationError.py │ ├── LateFutureImport.py │ ├── MisplacedFutureImport.py │ ├── ModuleReturn.py │ ├── NonAsciiWithoutEncoding_2.py │ ├── NonlocalForParameter32.py │ ├── NonlocalNotFound32.py │ ├── StarImportExtra.py │ ├── SyntaxError.py │ ├── TryExceptAllNotLast.py │ ├── TryFinallyContinue_37.py │ ├── UnpackNoTuple.py │ ├── UnpackTwoStars32.py │ ├── YieldFromInModule.py │ ├── YieldInAsync35.py │ ├── YieldInGenexp38.py │ ├── YieldInModule.py │ └── run_all.py ├── test-runners/ │ ├── run_all.py │ └── subject/ │ └── package/ │ ├── Something.py │ ├── __init__.py │ ├── sub_package1/ │ │ ├── SubSomething1.py │ │ ├── __init__.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── test_subsomething1.py │ ├── sub_package2/ │ │ ├── SubSomething2.py │ │ ├── __init__.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── test_subsomething2.py │ └── tests/ │ ├── __init__.py │ └── test_something.py └── type_inference/ ├── Test1.py ├── Test2.py ├── Test3.py └── Test4.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*.{py,c,cpp,h,rst,md,yml}] trim_trailing_whitespace = true insert_final_newline = true indent_style = space [*.{py,c,cpp,h}] indent_size = 4 [*.yml] indent_size = 2 ================================================ FILE: .gitattributes ================================================ * -text ================================================ FILE: .githooks/pre-commit ================================================ #!/bin/sh # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file # # An example hook script to verify what is about to be committed. # Called by "git commit" with no arguments. The hook should # exit with non-zero status after issuing an appropriate message if # it wants to stop the commit. # # To enable this hook, rename this file to "pre-commit". if git rev-parse --verify HEAD >/dev/null 2>&1; then against=HEAD else # Initial commit: diff against an empty tree object against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi # Redirect output to stderr. exec 1>&2 files=$(git diff --cached --name-only $against) if [ -z "$files" ]; then exit 0 fi # Autoformat the files. if [ "$COMMIT_UNCHECKED" != "1" ]; then exec ./bin/autoformat-nuitka-source --from-commit fi # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: .github/FUNDING.yml ================================================ custom: ['https://nuitka.net/pages/donations.html'] ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ Before submitting an Issue, please review the [Issue Guidelines](https://github.com/Nuitka/Nuitka/blob/develop/CONTRIBUTING.md#submitting-an-issue). - Please check whether the bug was already reported or fixed. - Please check out if the develop version of Nuitka works better for you. Download source, packages [from here](https://nuitka.net/doc/download.html) where you will also find instructions how to do it via pip or git. If you want to post a problem/bug, to help us understand and resolve your issue please check that you have provided at least the information below, and discard up to here: - Nuitka version, full Python version, flavor, OS, etc. as output by *this exact* command. > python -m nuitka --version If you are not providing the full output. The issue cannot be solved and will be considered `invalid`. The command outputs more than you think, and we are adding more all the time. We do not want to left guessing or trying things out to reproduce your issue. - How did you install Nuitka and Python Did you use pip, anaconda, deb, rpm, from source, git clone, then install into a virtualenv or not, this is very important usually and one thing, the above command does not tell us (yet). - The specific PyPI names and versions It should be taken from this output if there specific packages involved, e.g. `numpy`, you are expected to shorten this to the relevant ones. > python -m pip freeze - Many times when you get an error from Nuitka, your setup may be special Then even a `print("hello world")` program will not work, please try that and report that error instead. We do not need a report that says "Tensorflow does not work" when nothing actually works for you. You ought to also read the User Manual and check that your setup is actually supported already. - Also supply a Short, Self Contained, Correct, Example That demonstrates the issue i.e a small piece of code which reproduces the issue and can be run with out any other (or as few as possible) external dependencies. Issues without this may will likely be rejected without much consideration. Often this can be as simple as importing a package, if this is a packaging issue, try that first. Pointers to repositories with usage of `pipenv` are very welcome, archives with examples are too, e.g. if a certain package structure is needed. This must be only source code, binaries are not used ever by us. But beware, that e.g. we cannot click around and stuff. Still do an effort to make the usage obvious. Having a compile script in the repo is perfect. But this cannot be much code for non-commercial users, since that causes too much effort. We cannot just compile your code, run it and have it download a control and command center. - Provide in your issue the Nuitka options used Ideally use the `# nuitka-project:` options feature in the code, so options and example code go along. Alternatively state the command line. [Nuitka Options in the code](https://nuitka.net/doc/user-manual.html#nuitka-options-in-the-code) - Avoid unnecessary options Do not use `--onefile` if the issue also happens with `--standalone`. Minimize the use of options as far as you can, please. Do not disable outputs with `--quiet` and do not disable warnings. - Note if this is a regression If it used to work in an earlier version of Nuitka, please note what you know about that. Since git bisect is a thing for which we do a lot of error to make it usable, this will help dramatically to isolate the issue. - Consider getting commercial support [Nuitka commercial](https://nuitka.net/doc/commercial.html) offers subscriptions and priority support. This will accelerate your problem solution and helps to sustain Nuitka development. Also you then have a chance to provide source code of your project to us, which might simplify things, or pay for time to solve your issues in your environment. Some things are not welcome, please consider it. - Do *not* post screenshots These are not welcome unless absolutely necessary, e.g. because of Qt display problem, instead capture the output of programs, so things are searchable and copy&paste will work. I just plainly don't want to manually copy strings and hope they match. - Do *not* close the issue yourself, we will close things on stable releases We close issues only when they are released as a stable version, e.g. in a hotfix or a new release, before that it will be "Done" in planning and go through `factory` and `develop` tags to indicate they are solved there. Of course, if you find out your issue is invalid, please do close it, and we then attach the `invalid` tag. - Do *not* report against factory version Unless you were asked to test it there, it is frequently very broken, and there is only noise to be had. Telling me about it on Discord would be a better idea. - Do *not* let this template remain part of the issue, it's noise. ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ Thank your for contributing to Nuitka! !! Please check that you select the **develop branch** (details see below link) !! Before submitting a PR, please review the guidelines: [Contributing Guidelines](https://github.com/Nuitka/Nuitka/blob/develop/CONTRIBUTING.md) # What does this PR do? # Why was it initiated? Any relevant Issues? # PR Checklist - [ ] Correct base branch selected? Should be `develop` branch. - [ ] Enabled commit hook or executed `./bin/autoformat-nuitka-source`. - [ ] All tests still pass. Check the Developer Manual about `Running the Tests`. There are GitHub Actions tests that cover the most important things however, and you are welcome to rely on those, but they might not cover enough. - [ ] Ideally new features or fixed regressions ought to be covered via new tests. - [ ] Ideally new or changed features have documentation updates. ================================================ FILE: .github/workflows/testing.yml ================================================ name: Nuitka tests # makes little sense, spell-checker: disable on: pull_request: branches: - develop push: branches: - main - develop - factory - release/** - hotfix/** permissions: contents: read jobs: linux: runs-on: ubuntu-22.04 strategy: matrix: python_version: - '3.7' - '3.8' - '3.9' - '3.10' - '3.11' name: Ubuntu Python ${{ matrix.python_version }} steps: - name: 🛎️ Checkout uses: actions/checkout@v3 with: fetch-depth: 0 - name: 🐍 Use Python ${{ matrix.python_version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python_version }} - name: 🧳 Install Nuitka and dependencies run: | sudo apt-get update sudo apt-get install patchelf gdb ccache libfuse2 python -m pip install --no-python-version-warning --disable-pip-version-check -r requirements-devel.txt python -m pip install --no-python-version-warning --disable-pip-version-check . - name: Verbose scons output in compilation run: | python -m nuitka --module --show-scons --run --report=compilation-report-module.xml --experimental=debug-report-traceback tests/basics/EmptyModuleTest.py python -m nuitka --show-scons --run --report=compilation-report-exe.xml --experimental=debug-report-traceback tests/basics/EmptyModuleTest.py - name: Archive compilation reports for empty modules uses: actions/upload-artifact@v3 with: name: compilation-reports path: | *.xml # This can be used to ssh into GitHub actions if debugging is needed. # - uses: actions/checkout@v2 # - name: Setup upterm session # uses: lhotari/action-upterm@v1 # with: # ## limits ssh access and adds the ssh public keys of the listed GitHub users # limit-access-to-users: kayhayen - name: Run Nuitka test suite run: | python -m nuitka --version env | sort python ./tests/run-tests --no-other-python --skip-reflection-test --skip-all-cpython-tests --assume-yes-for-downloads - name: PyLint on Nuitka source code run: | python ./bin/check-nuitka-with-pylint if: matrix.python_version == '3.9' - name: RestLint on Nuitka source code run: | python ./bin/check-nuitka-with-restlint if: matrix.python_version == '3.9' - name: YamlLint on Nuitka source code run: | python ./bin/check-nuitka-with-yamllint if: matrix.python_version == '3.9' - name: Codespell on Nuitka source code run: | python ./bin/check-nuitka-with-codespell if: matrix.python_version == '3.9' - name: Auto-format check on Nuitka source code run: | # Install clang-format that matches what we use in VS code. wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - sudo apt-get install software-properties-common sudo add-apt-repository 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy main' sudo apt-get update sudo apt-get install clang-format-19 python ./bin/autoformat-nuitka-source --check-only if: matrix.python_version == '3.9' mac-python3: runs-on: macos-latest strategy: matrix: python_version: - '3.7' - '3.8' - '3.9' - '3.10' - '3.11' name: macOS Python ${{ matrix.python_version }} steps: - uses: actions/checkout@v3 - name: Use Python ${{ matrix.python_version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python_version }} - name: Verbose installation output for Python run: | set -x which python otool -L $(which python) otool -l $(which python) ls -lR $(dirname $(dirname $(which python))) - name: 🧳 Install Nuitka and dependencies run: | pip install --no-python-version-warning --disable-pip-version-check -r requirements-devel.txt pip install --no-python-version-warning --disable-pip-version-check . - name: Verbose scons output in compilation run: | python -m nuitka --module --show-scons --run --assume-yes-for-downloads tests/basics/EmptyModuleTest.py python -m nuitka --show-scons --run --assume-yes-for-downloads tests/basics/EmptyModuleTest.py - name: Run Nuitka test suite run: | python -m nuitka --version env | sort python ./tests/run-tests --no-other-python --skip-reflection-test --skip-all-cpython-tests windows: runs-on: windows-latest strategy: matrix: python_version: - '3.7' - '3.8' - '3.9' - '3.10' - '3.11' name: Windows Python ${{ matrix.python_version }} steps: - uses: actions/checkout@v3 - uses: ilammy/msvc-dev-cmd@v1 - name: Use Python ${{ matrix.python_version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python_version }} - name: 🧳 Install Nuitka and dependencies run: | pip install --no-python-version-warning --disable-pip-version-check -r requirements-devel.txt pip install --no-python-version-warning --disable-pip-version-check . - name: Verbose scons output in compilation run: | python -m nuitka --module --show-scons --run --assume-yes-for-downloads tests\basics\EmptyModuleTest.py python -m nuitka --show-scons --run tests\basics\EmptyModuleTest.py - name: Run Nuitka test suite run: | Get-ChildItem env: python -m nuitka --version python .\tests\run-tests --no-other-python --no-debug --skip-reflection-test --skip-all-cpython-tests --assume-yes-for-downloads ================================================ FILE: .gitignore ================================================ *~ *.DS_Store *.e4t *.e4q *.e4s *.pyc __pycache__/ *.pyo *.swp *.swo *.o *.os *.so *.pyd *.pyi *.exe *.exe.away *.cmd *.bin *.build *.onefile-build *.dist *.app *.key *.xml *.optimization.log *.inclusion.log *.strace *.dtruss *.nuitka-pgo .mypy_cache *.egg-info tests/reflected/nuitka/ tests/reflected/tests/ tests/reflected/nuitka.py tests/reflected/nuitka-runner.py tests/basics/BigConstants.py tests/generated/*.py !tests/generated/run_all.py tests/PyPI-pytest/venv_* *.dblite *.pdb releases/ html man/ htmlcov/ Mini.py python??.dll python??_d.dll build !nuitka/build dist MANIFEST README.pdf README.html Developer_Manual.pdf Developer_Manual.html Changelog.pdf Changelog.html doc/man-*.html doxygen-warnings.log venv_cpython/ venv_nuitka/ .pytest_cache doxygen_* doxygen-* .coverage* *.tmp *.dat .vscode/ipch .vscode/tags .vscode/.ropeproject Nuitka-* nuitka/tools/podman/containers/requirements-devel.txt ================================================ FILE: .gitmodules ================================================ [submodule "tests/CPython26"] path = tests/CPython26 url = https://github.com/Nuitka/Nuitka-CPython-tests.git branch = CPython26 [submodule "tests/CPython27"] path = tests/CPython27 url = https://github.com/Nuitka/Nuitka-CPython-tests.git branch = CPython27 [submodule "tests/CPython32"] path = tests/CPython32 url = https://github.com/Nuitka/Nuitka-CPython-tests.git branch = CPython32 [submodule "tests/CPython33"] path = tests/CPython33 url = https://github.com/Nuitka/Nuitka-CPython-tests.git branch = CPython33 [submodule "tests/CPython34"] path = tests/CPython34 url = https://github.com/Nuitka/Nuitka-CPython-tests.git branch = CPython34 [submodule "tests/CPython35"] path = tests/CPython35 url = https://github.com/Nuitka/Nuitka-CPython-tests.git branch = CPython35 [submodule "tests/CPython36"] path = tests/CPython36 url = https://github.com/Nuitka/Nuitka-CPython-tests.git branch = CPython36 [submodule "tests/CPython37"] path = tests/CPython37 url = https://github.com/Nuitka/Nuitka-CPython-tests.git branch = CPython37 [submodule "tests/CPython38"] path = tests/CPython38 url = https://github.com/Nuitka/Nuitka-CPython-tests.git branch = CPython38 [submodule "tests/CPython39"] path = tests/CPython39 url = https://github.com/Nuitka/Nuitka-CPython-tests.git branch = CPython39 [submodule "tests/CPython310"] path = tests/CPython310 url = https://github.com/Nuitka/Nuitka-CPython-tests.git branch = CPython310 [submodule "tests/CPython311"] path = tests/CPython311 url = https://github.com/Nuitka/Nuitka-CPython-tests.git branch = CPython311 ================================================ FILE: .sourcery.yaml ================================================ # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file ignore: - "tests" - "nuitka/build/inline_copy" refactor: python_version: '2.6' # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: .vscode/c_cpp_properties.json ================================================ { "env": { "myDefaultIncludePath": [ "${workspaceFolder}/nuitka/build/include", "${workspaceFolder}/nuitka/build/static_src", "${workspaceFolder}/nuitka/build/inline_copy/zstd", "${workspaceFolder}/nuitka/build/inline_copy/zlib", "${workspaceFolder}/nuitka/build/inline_copy/libbacktrace" ] }, "configurations": [ { "name": "Win32", "includePath": [ "${myDefaultIncludePath}", "C:\\Python311\\Include" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE", "__IDE_ONLY__", "PYTHON_VERSION=0x3b0" ], "windowsSdkVersion": "10.0.19041.0", "compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.31.31103/bin/Hostx64/x64/cl.exe", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "msvc-x64" }, { "name": "Win32-Py312", "includePath": [ "${myDefaultIncludePath}", "C:\\Python312\\Include" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE", "__IDE_ONLY__", "PYTHON_VERSION=0x3c0" ], "windowsSdkVersion": "10.0.19041.0", "compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.31.31103/bin/Hostx64/x64/cl.exe", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "msvc-x64" }, { "name": "Win32-Py310", "includePath": [ "${myDefaultIncludePath}", "C:\\Python310\\Include" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE", "__IDE_ONLY__", "PYTHON_VERSION=0x3a0" ], "windowsSdkVersion": "10.0.19041.0", "compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.31.31103/bin/Hostx64/x64/cl.exe", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "msvc-x64" }, { "name": "Win32-Py27", "includePath": [ "${myDefaultIncludePath}", "C:\\Python27\\Include" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE", "__IDE_ONLY__", "PYTHON_VERSION=0x270" ], "windowsSdkVersion": "10.0.19041.0", "compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.31.31103/bin/Hostx64/x64/cl.exe", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "msvc-x64" }, { "name": "Linux-Python3.9", "includePath": [ "/usr/include", "${myDefaultIncludePath}", "/usr/include/python3.9" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE", "__IDE_ONLY__", "PYTHON_VERSION=0x390" ], "compilerPath": "/usr/bin/gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}" }, { "name": "Linux-Python3.10", "includePath": [ "/usr/include", "${myDefaultIncludePath}", "/usr/include/python3.10" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE", "__IDE_ONLY__", "PYTHON_VERSION=0x3a0" ], "compilerPath": "/usr/bin/gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}" }, { "name": "Linux-Python3.11", "includePath": [ "/usr/include", "${myDefaultIncludePath}", "/usr/include/python3.11" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE", "__IDE_ONLY__", "PYTHON_VERSION=0x3B0" ], "compilerPath": "/usr/bin/gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}" }, { "name": "Linux-Python2.7", "includePath": [ "/usr/include", "${myDefaultIncludePath}", "/usr/include/python2.7" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE", "__IDE_ONLY__", "PYTHON_VERSION=0x270" ], "compilerPath": "/usr/bin/gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}" }, { "name": "Mac", "includePath": [ "${myDefaultIncludePath}", "/Library/Frameworks/Python.framework/Versions/3.11/include/python3.11" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE", "__IDE_ONLY__", "PYTHON_VERSION=0x3B0" ], "compilerPath": "/usr/bin/gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "${default}" } ], "version": 4 } ================================================ FILE: .vscode/extensions.json ================================================ { // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp // List of extensions which should be recommended for users of this workspace. "recommendations": [ "ms-python.python", "lextudio.restructuredtext", "foxundermoon.shell-format", "troelsdamgaard.reflow-paragraph", "ms-vscode.cpptools", "mervin.markdown-formatter", "stkb.rewrap", "trond-snekvik.simple-rst", "redhat.vscode-yaml", "dawidd6.debian-vscode", "streetsidesoftware.code-spell-checker", "samuelcolvin.jinjahtml", "tamasfe.even-better-toml" ], // List of extensions recommended by VS Code that should not be recommended for users of this workspace. "unwantedRecommendations": [ ] } ================================================ FILE: .vscode/settings.json ================================================ { "files.trimTrailingWhitespace": true, "files.trimFinalNewlines": true, "C_Cpp.dimInactiveRegions": false, "files.exclude": { "**/*.onefile-build": true, "**/*.build": true, "**/*.dist": true, "**/*.exe": true, "**/*.exe.away": true, "**/*.bin": true, "**/*.pyc": true, "**/__pycache__": true, "**/*.orig": true, "**/*.tmp": true, "tests/reflected/nuitka": true, "tests/distutils/venv_*": true, "build": true, }, "files.associations": { "*.tac": "python", "*.inc": "restructuredtext", "*.scons": "python", "*.sco": "python", "*.h": "c", "*.c": "c", "typeinfo": "c", "cstring": "c", "optional": "c", "istream": "c", "ostream": "c", "system_error": "c", "array": "c", "functional": "c", "tuple": "c", "type_traits": "c", "utility": "c", "memory": "c", "onefilesplashscreen.cpp": "cpp", "compare": "c", "string_view": "c", "initializer_list": "c", "ranges": "c", "chrono": "c", "ratio": "c", "__hash_table": "c", "__split_buffer": "c", "bitset": "c", "string": "c", "unordered_map": "c", "vector": "c", "xtr1common": "c", "__locale": "c", "atomic": "c", "__functional_base": "c", "__functional_base_03": "c", "__tuple": "c", "algorithm": "c", "limits": "c", "random": "c", "__bit_reference": "c", "__node_handle": "c", "deque": "c", "__memory": "c", "iterator": "c", "locale": "c" }, "python.analysis.autoSearchPaths": false, "python.analysis.extraPaths": [ "nuitka/build/inline_copy/lib/scons-3.1.2", "nuitka/build/inline_copy/clcache" ], "python.analysis.diagnosticSeverityOverrides": { "reportMissingImports": "none" }, "cSpell.words": [ "__abstractmethods__", "__aenter__", "__aexit__", "__cplusplus", "__newobj__", "__warningregistry__", "_NUITKA_WINMAIN_ENTRY_POINT", "_Py_DEC_REFTOTAL", "_Py_DecodeUTF8_surrogateescape", "_PyDict_NewPresized", "_wtoi", "_XOPEN_SOURCE", "abiflags", "abspath", "abstractmethod", "abstractproperty", "appdirs", "asyncgen", "backslashreplace", "basenames", "basestring", "binaryfunc", "bitor", "Buildbot", "bytearray", "bytecode", "bytecodes", "CAPI", "CBOOL", "ccache", "CFLOAT", "cframe", "clangcl", "clcache", "CLONG", "clonglong", "closefd", "co_argcount", "co_firstlineno", "co_freevars", "co_has_stardict", "co_has_starlist", "co_kwonlyargcount", "co_nconsts", "CO_NEWLOCALS", "CO_NOFREE", "co_posonlyargcount", "CO_VARKEYWORDS", "co_varnames", "codesign", "codespell", "compactify", "conda", "condition-evals-to-constant", "containerfile", "CORO_CLOSED", "CORO_CREATED", "CORO_RUNNING", "CORO_SUSPENDED", "cpython", "ctypes", "curexc_traceback", "curexc_type", "curexc_value", "Cython", "deepcopy", "Dejong", "descrgetfunc", "descrsetfunc", "devel", "devnull", "diffable", "distutils", "Doxygen", "dpkg", "dtrace", "dtruss", "dunder", "DYLD", "dylib", "elif", "embeddable", "EPEL", "finalizer", "FLUFL", "fromlist", "frozenset", "fstrings", "genericalias", "genexpr", "getpreferredencoding", "gettotalrefcount", "girepository", "Gitter", "hasattr", "hashable", "haskey", "Hayen", "HEDLEY", "hotfixes", "ibitand", "ibitor", "ibitxor", "idna", "imatmult", "importlib", "imult", "incbin", "inplace", "iolddiv", "ipython", "isabs", "isdir", "isfile", "isgen", "isgenerator", "isort", "iterdir", "iteritems", "iterkeys", "iternextfunc", "itervalues", "joinpath", "jsonschema", "Kivy", "kwargs", "kwds", "lasti", "ldconfig", "libc", "libpython", "lintian", "listdir", "lldb", "longlong", "LPWSTR", "lxml", "manylinux", "Matmult", "mdef", "metaclass", "metaclasses", "metapath", "METH_NOARGS", "METH_VARARGS", "MSVC", "msys", "Mult", "multidist", "namedtuples", "Namify", "NBOOL", "no_docstrings", "noelf", "nofollow", "noinclude", "nosite", "nowarn", "Nuitka", "Numba", "numberize", "numpy", "ob_sval", "olddiv", "onefile", "optipng", "organisation", "Organisational", "otool", "pacman", "patchelf", "pathlib", "pbuilder", "Pickler", "pipenv", "pkglib", "Podman", "POSIX", "Py_DECREF", "Py_INCREF", "PY_NOGIL", "Py_REFCNT", "Py_ssize_t", "Py_TPFLAGS", "Py_TPFLAGS_HAVE_WEAKREFS", "Py_TPFLAGS_HEAPTYPE", "Py_XDECREF", "Py_XINCREF", "PYCORE", "PyCoro_Type", "pyenv", "PyErr_WriteUnraisable", "pygsheets", "pylint", "pyproject", "pyqt", "pyside", "PYSTATE", "pystone", "PYTHONHASHSEED", "PYTHONHOME", "PYTHONIOENCODING", "PYTHONPATH", "pythonw", "Qualname", "redist", "reexecute", "repr", "reprfunc", "richcmpfunc", "roadmap", "rpartition", "RPATH", "rpaths", "RT_RCDATA", "Scons", "setattrofunc", "Setuptools", "sourcery", "ssizeargfunc", "startswith", "staticmethod", "stdlib", "strchr", "subclasscheck", "sysexit", "sysflag", "Termux", "ternaryfunc", "Themida", "Tkinter", "tp_alloc", "tp_basicsize", "tp_dealloc", "tp_descr_get", "tp_descr_set", "tp_dictoffset", "tp_getattro", "tp_getset", "tp_itemsize", "tp_iternext", "tp_richcompare", "tp_setattro", "tp_vectorcall_offset", "tp_weaklist", "tp_weaklistoffset", "traceback", "tracebacks", "traverseproc", "truediv", "tshape", "tstate", "ucrt", "uncompiled", "unoptimized", "unorderable", "unstripped", "Valgrind", "vectorcall", "vectorcallfunc", "viewitems", "viewkeys", "viewvalues", "virtualenv", "visitproc", "vmprof", "vshape", "wargv", "wcsicmp", "winlibs", "wmain", "zstandard", "zstd" ], "esbonio.server.enabled": true, "esbonio.sphinx.confDir": "", "cSpell.spellCheckOnlyWorkspaceFiles": true, "cSpell.ignorePaths": [ ".git", ".vscode", "Mini*.py", ], "yaml.schemas": { "misc/nuitka-package-config-schema.json": [ "*.nuitka-package.config.yml", "*.nuitka-package.config.yaml", ] }, "yaml.maxItemsComputed": 10000, "[python]": { "editor.defaultFormatter": "ms-python.black-formatter" } } ================================================ FILE: CODE_OF_CONDUCT.rst ================================================ ###################################### Contributor Covenant Code of Conduct ###################################### ************ Our Pledge ************ In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. *************** Our Standards *************** Examples of behavior that contributes to creating a positive environment include: - Using welcoming and inclusive language - Being respectful of differing viewpoints and experiences - Gracefully accepting constructive criticism - Focusing on what is best for the community - Showing empathy towards other community members Examples of unacceptable behavior by participants include: - The use of sexualized language or imagery and unwelcome sexual attention or advances - Trolling, insulting/derogatory comments, and personal or political attacks - Public or private harassment - Publishing other's private information, such as a physical or electronic address, without explicit permission - Other conduct which could reasonably be considered inappropriate in a professional setting ********************** Our Responsibilities ********************** Maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ******* Scope ******* This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ************* Enforcement ************* Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the Nuitka Organisation admins via email to "kay@nuitka.net". Use "COD complaint:" in your email subject. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The Code of Conduct Committee is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. ************* Attribution ************* This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html and the Linux kernel team changes as available under https://docs.kernel.org/_sources/process/code-of-conduct.rst.txt ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing to Nuitka ## First things Welcome on board. Nuitka is an ambitious project. We are friendly. Join it now. This document aims to give an overview of how to contribute to Nuitka. It tries to answer commonly asked questions regarding that, and to provide some insight on how to do it properly. - If you plan on submitting an issue Please follow this [template](https://github.com/Nuitka/Nuitka/blob/develop/.github/ISSUE_TEMPLATE.md). - If you want to open a pull request Make sure to read the information on further down this page but also have a look at our [pull request template](https://github.com/Nuitka/Nuitka/blob/develop/.github/PULL_REQUEST_TEMPLATE.md). ## Getting Started - Read the [Nuitka User Manual](https://nuitka.net/doc/user-manual.html) - Read the [Nuitka Developer Manual](https://nuitka.net/doc/developer-manual.html) - Checkout the [git repo of Nuitka](https://github.com/Nuitka/Nuitka) additional docs and sources - Join the [Discord Server](https://discord.gg/nZ9hr9tUck) ## Submitting a Pull Request Pull requests are great. Here's a quick guide: 1. Fork the repo on github. 2. Install the `pre-commit` git hook That is going to automatically format your code as described in the Developer Manual. For that you have to execute this: python misc/install-git-hooks.py 3. Make a new branch and base your new branch on `develop`. 4. Ideally add a test specific for your change to demonstrate it. Due to Nuitka testing being basically to compile the whole world, it's ok to not have one. But obviously if you fix something, it wasn't observed by that, it would be good to provide a reproducer. 5. Make the tests pass. 6. Push to your fork and submit a pull request against `nuitka:develop` 7. Wait for review Suggestions for improvements or alternative ideas may happen. Keep in mind that PR checklist items can be met after the pull request has been opened by adding more commits to the branch. Indicate work in progress with a `WIP:` prefix in your PR title. All the submitted pieces including potential data must be compatible with the Apache License 2, which already says that once you are sending modified source, e.g. via pull request, you automatically license it as that too. ## Submitting a Question If you want to ask a question about a specific Nuitka aspect, please be kind and first of all.. - Search for existing issues Consider [GitHub issues tagged as "question"](https://github.com/Nuitka/Nuitka/issues?q=label%3Aquestion) - If not asked yet, ask it there. ## Submitting Issues The issue template contains the guidance on how to properly support issues. If you ignore it, likely the issue will be closed as invalid. We cannot really make guesses. ================================================ FILE: Changelog.rst ================================================ ################## Nuitka Changelog ################## In this document, we track the per version changes and comments. This is now maintained separately at https://nuitka.net/changelog/Changelog.html please check it out from there. ================================================ FILE: Developer_Manual.rst ================================================ ######################### Nuitka Developer Manual ######################### The purpose of this Developer Manual is to present the current design of Nuitka, the project rules, and the motivations for choices made. It is intended to be a guide to the source code, and to give explanations that don't fit into the source code in comments form. It should be used as a reference for the process of planning and documenting decisions we made. Therefore we are e.g. presenting here the type inference plans before implementing them. And we update them as we proceed. It grows out of discussions and presentations made at conferences as well as private conversations or issue tracker. ************ Milestones ************ #. Feature parity with CPython, understand all the language construct and behave absolutely compatible. Feature parity has been reached for CPython 2.6 and 2.7. We do not target any older CPython release. For CPython 3.3 up to 3.8 it also has been reached. We do not target the older and practically unused CPython 3.0 to 3.2 releases. This milestone was reached. Dropping support for Python 2.6 and 3.3 is an option, should this prove to be any benefit. Currently it is not, as it extends the test coverage only. #. Create the most efficient native code from this. This means to be fast with the basic Python object handling. This milestone was reached, although of course, micro optimizations to this are happening all the time. #. Then do constant propagation, determine as many values and useful constraints as possible at compile time and create more efficient code. This milestone is considered almost reached. We continue to discover new things, but the infrastructure is there, and these are easy to add. #. Type inference, detect and special case the handling of strings, integers, lists in the program. This milestone is considered in progress. #. Add interfacing to C code, so Nuitka can turn a ``ctypes`` binding into an efficient binding as written with C. This milestone is planned only. #. Add hints module with a useful Python implementation that the compiler can use to learn about types from the programmer. This milestone is planned only. ***************** Version Numbers ***************** For Nuitka we use semantic versioning, initially with a leading zero still, once we pass release ``1.9``, the scheme will indicate the ``10`` through using ``2.0``. *************** Current State *************** Nuitka top level works like this: - ``nuitka.tree.Building`` outputs node tree - ``nuitka.optimization`` enhances it as best as it can - ``nuitka.finalization`` prepares the tree for code generation - ``nuitka.code_generation.CodeGeneration`` orchestrates the creation of code snippets - ``nuitka.code_generation.*Codes`` knows how specific code kinds are created - ``nuitka.MainControl`` keeps it all together This design is intended to last. Regarding types, the state is: - Types are always ``PyObject *``, and only a few C types, e.g. ``nuitka_bool`` and ``nuitka_void`` and more are coming. Even for objects, often it's know that things are e.g. really a ``PyTupleObject **``, but no C type is available for that yet. - There are a some specific use of types beyond "compile time constant", that are encoded in type and value shapes, which can be used to predict some operations, conditions, etc. if they raise, and result types they give. - In code generation, the supported C types are used, and sometimes we have specialized code generation, e.g. a binary operation that takes an ``int`` and a ``float`` and produces a ``float`` value. There will be fallbacks to less specific types. The expansion with more C types is currently in progress, and there will also be alternative C types, where e.g. ``PyObject *`` and ``C long`` are in an enum that indicates which value is valid, and where special code will be available that can avoid creating the ``PyObject **`` unless the later overflows. *************************************************** Setting up the Development Environment for Nuitka *************************************************** Currently there are very different kinds of files that we need support for. This is best addressed with an IDE. We cover here how to setup the most common one. Visual Studio Code ================== Download Visual Studio Code from here: https://code.visualstudio.com/download At this time, this is the recommended IDE for Linux and Windows. This is going to cover the plugins to install. Configuration is part of the ``.vscode`` in your Nuitka checkout. If you are not familiar with Eclipse, this is Free Software IDE,designed to be universally extended, and it truly is. There are plugins available for nearly everything. The extensions to be installed are part of the Visual Code recommendations in ``.vscode/extensions.json`` and you will be prompted about that and ought to install these. Eclipse / PyCharm ================= Don't use these anymore, we consider Visual Studio Code to be far superior for delivering a nice out of the box environment. ************************* Commit and Code Hygiene ************************* In Nuitka we have tools to auto format code, you can execute them manually, but it's probably best to execute them at commit time, to make sure when we share code, it's already well format, and to avoid noise doing cleanups. The kinds of changes also often cause unnecessary merge conflicts, while the auto format is designed to format code also in a way that it avoids merge conflicts in the normal case, e.g. by doing imports one item per line. In order to set up hooks, you need to execute these commands: .. code:: bash # Where python is the one you use with Nuitka, this then gets all # development requirements, can be full PATH. python -m pip install -r requirements-devel.txt python ./misc/install-git-hooks.py These commands will make sure that the ``autoformat-nuitka-source`` is run on every staged file content at the time you do the commit. For C files, it may complain unavailability of ``clang-format``, follow it's advice. You may call the above tool at all times, without arguments to format call Nuitka source code. Should you encounter problems with applying the changes to the checked out file, you can always execute it with ``COMMIT_UNCHECKED=1`` environment set. ********************* Coding Rules Python ********************* These rules should generally be adhered when working on Nuitka code. It's not library code and it's optimized for readability, and avoids all performance optimization for itself. Tool to format ============== There is a tool ``bin/autoformat-nuitka-source`` which is to apply automatic formatting to code as much as possible. It uses ``black`` (internally) for consistent code formatting. The imports are sorted with ``isort`` for proper order. The tool (mostly ``black`` and ``isort``) encodes all formatting rules, and makes the decisions for us. The idea being that we can focus on actual code and do not have to care as much about other things. It also deals with Windows new lines, trailing space, etc. and even sorts PyLint disable statements. Identifiers =========== Classes ------- Classes are camel case with leading upper case. Functions and methods are with leading verb in lower case, but also camel case. Variables and arguments are lower case with ``_`` as a separator. .. code:: python class SomeClass: def doSomething(some_parameter): some_var = ("foo", "bar") Base classes that are abstract have their name end with ``Base``, so that a meta class can use that convention, and readers immediately know, that it will not be instantiated like that. Functions --------- Function calls use keyword argument preferably. These are slower in CPython, but more readable: .. code:: python getSequenceCreationCode( sequence_kind=sequence_kind, element_identifiers=identifiers, context=context ) When the names don't add much value, sequential calls can be done: .. code:: python context.setLoopContinueTarget(handler_start_target) Here, ``setLoopContinueTarget`` will be so well known that the reader is expected to know the argument names and their meaning, but it would be still better to add them. But in this instance, the variable name already indicates that it is. Module/Package Names -------------------- Normal modules are named in camel case with leading upper case, because of their role as singleton classes. The difference between a module and a class is small enough and in the source code they are also used similarly. For the packages, no real code is allowed in their ``__init__.py`` and they must be lower case, like e.g. ``nuitka`` or ``codegen``. This is to distinguish them from the modules. Packages shall only be used to group things. In ``nuitka.code_generation`` the code generation packages are located, while the main interface is ``nuitka.code_generation.CodeGeneration`` and may then use most of the entries as local imports. There is no code in packages themselves. For programs, we use ``__main__`` package to carry the actual code. Names of modules should be plurals if they contain classes. Example is that a ``Nodes`` module that contains a ``Node`` class. Context Managers ---------------- Names for context manages start with ``with`` In order to easily recognize that something is to be used as a context manager, we follow a pattern of naming them ``withSomething``, to make that easily recognized. .. code:: python with withEnvironmentPathAdded(os.path.join(sys.prefix, "bin")): with withDirectoryChange(self.qt_datadir): ... This makes these easy to recognize even in their definition. Prefer list contractions over built-ins ======================================= This concerns ``map``, ``filter``, and ``apply``. Usage of these built-ins is highly discouraged within Nuitka source code. Using them is considered worth a warning by "PyLint" e.g. "Used built-in function 'map'". We should use list contractions instead, because they are more readable. List contractions are a generalization for all of them. We love readability and with Nuitka as a compiler, there won't be any performance difference at all. There are cases where a list contraction is faster because you can avoid to make a function call. And there may be cases, where map is faster, if a function must be called. These calls can be very expensive in CPython, and if you introduce a function, just for ``map``, then it might be slower. But of course, Nuitka is the project to free us from what is faster and to allow us to use what is more readable, so whatever is faster, we don't care. We make all options equally fast and let people choose. For Nuitka the choice is list contractions as these are more easily changed and readable. Look at this code examples from Python: .. code:: python class A: def getX(self): return 1 x = property(getX) class B(A): def getX(self): return 2 A().x == 1 # True B().x == 1 # True (!) This pretty much is what makes properties bad. One would hope ``B().x`` to be ``2``, but instead it's not changed. Because of the way properties take the functions and not members, and because they then are not part of the class, they cannot be overloaded without re-declaring them. Overloading is then not at all obvious anymore. Now imagine having a setter and only overloading the getter. How to update the property easily? So, that's not likable about them. And then we are also for clarity in these internal APIs too. Properties try and hide the fact that code needs to run and may do things. So let's not use them. For an external API you may exactly want to hide things, but internally that has no use, and in Nuitka, every API is internal API. One exception may be the ``hints`` module, which will gladly use such tricks for an easier write syntax. **************** Coding Rules C **************** For the static C parts, e.g. compiled types, helper codes, the ``clang-format`` from LLVM project is used, the tool ``autoformat-nuitka-source`` does this for us. We always have blocks for conditional statements to avoid typical mistakes made by adding a statement to a branch, forgetting to make it a block. ********************** The "git flow" model ********************** - The flow is used for releases and occasionally subsequent hot fixes. A few feature branches were used so far. It allows for quick delivery of fixes to both the stable and the development version, supported by a git plug-in, that can be installed via "apt-get install git-flow". - Stable (``main`` branch) The stable version, is expected to pass all the tests at all times and is fully supported. As soon as bugs are discovered, they are fixed as hot fixes, and then merged to develop by the "git flow" automatically. - Development (``develop`` branch) The future release, supposedly in almost ready for release state at nearly all times, but this is less strict. It is not officially supported, and may have problems and at times inconsistencies. Normally this branch is supposed to not be rebased. For severe problems it may be done though. - Factory (default feature branch) Code under construction. We publish commits there, that may not hold up in testing, and before it enters develop branch. Factory may have severe regressions frequently, and commits become **rebased all the time**, so do not base your patches on it, please prefer the ``develop`` branch for that, unless of course, it's about factory code itself. - Personal branches (jorj, orsiris, others as well) We are currently not using this, but it's an option. - Feature Branches We are not currently using these. They could be used for long lived changes that extend for multiple release cycles and are not ready yet. Currently we perform all changes in steps that can be included in releases or delay making those changes. ****************************** Nuitka "git/github" Workflow ****************************** - Forking and cloning You need to have git installed and GitHub account. Goto Nuitka repository and fork the repository. To clone it to your local machine execute the following your git bash: .. code:: bash git clone https://github.com/your-user-name/Nuitka.git cd Nuitka git remote add upstream https://github.com/Nuitka/Nuitka.git - Create a Branch .. code:: bash git checkout develop git pull --rebase upstream git checkout -b feature_branch If you are having merge conflicts while doing the previous step, then check out (DON'T FORGET TO SAVE YOUR CHANGES FIRST IF ANY): - In case you have an existing branch rebase it to develop .. code:: bash git fetch upstream git rebase upstream/develop Fix the merge conflicts if any and continue or skip commit if it is not your. Sometimes for important bug fixes, develop history gets rewritten. In that case, old and new commits will conflict during your rebase, and skipping is the best way to go. .. code:: bash git rebase --continue # not your commit: git rebase --skip If anything goes wrong while rebasing: .. code:: bash git rebase --abort - Making changes .. code:: bash git commit -a -m "Commit Message" git push -u origin # once, later always: git push ********************************** API Documentation and Guidelines ********************************** There is API documentation generated with ``doxygen``, available at `this location `__ . To ensure meaningful ``doxygen`` output, the following guidelines must be observed when creating or updating Python source: Use of Standard Python ``__doc__`` Strings ========================================== Every class and every method should be documented via the standard Python delimiters (``""" ... """``) in the usual way. Special ``doxygen`` Anatomy of ``__doc__`` ========================================== .. note:: We are replacing Doxygen with sphinx, this is all obsolete - Immediately after the leading ``"""``, and after 1 space on the same line, enter a brief description or title of the class or method. This must be 1 line and be followed by at least 1 empty line. - Depending on the item, choose from the following "sections" to describe what the item is and does. Each section name is coded on its own line, aligned with the leading ``"""`` and followed by a colon ":". Anything following the section, must start on a new line and be indented by 4 spaces relative to the section. Except for the first section (``Notes:``) after the title, sections need not be preceded by empty lines -- but it is good practice to still do that. - ``Notes:`` detailed description of the item, any length. May contain line breaks with each new line starting aligned with previous one. The text will automatically be joined across line breaks and be reformatted in the browser. If you describe details for a class, you can do so **without** using this section header and all formatting will still work fine. If you however omit the ``Notes:`` for methods, then the text will be interpreted **as code**, be shown in an ugly monospaced font, and no automatic line breaks will occur in the browser. - ``Args:`` positional arguments. Each argument then follows, starting on a new line and indented by 4 spaces. The argument name must be followed by a colon ``:`` or double hash ``--``, followed by a description of arbitrary length. The description can be separated by line breaks. - ``Kwargs:`` keyword arguments. Same rules as for args. - ``Returns:`` description of what will be returned if applicable (any length). - ``Yields:`` synonymous for ``Returns:``. - ``Raises:`` name any exceptions that may be raised. - ``Examples:`` specify any example code. .. code:: python def foo(p1, p2, kw1=None, kw2=None): """This is an example method. Notes: It does one or the other indispensable things based on some parameters and proudly returns a dictionary. Args: p1: parameter one p2: parameter two Kwargs: kw1: keyword one kw2: keyword two Returns: A dictionary calculated from the input. Raises: ValueError, IndexError Examples: >>> foo(1, 2, kw1=3, kw2=4) {'a': 4, 'b': 6} """ ********************* Checking the Source ********************* The static checking for errors is currently done with ``PyLint``. In the future, Nuitka itself will gain the ability to present its findings in a similar way, but this is not a priority, and we are not there yet. So, we currently use ``PyLint`` with options defined in a script. .. code:: bash ./bin/check-nuitka-with-pylint The above command is expected to give no warnings. It is also run on our CI and we will not merge branches that do not pass. ******************* Running the Tests ******************* This section describes how to run Nuitka tests. Running all Tests ================= The top level access to the tests is as simple as this: .. code:: bash ./tests/run-tests For fine grained control, it has the following options: .. code:: --skip-basic-tests The basic tests, execute these to check if Nuitka is healthy. Default is True. --skip-syntax-tests The syntax tests, execute these to check if Nuitka handles Syntax errors fine. Default is True. --skip-program-tests The programs tests, execute these to check if Nuitka handles programs, e.g. import recursions, etc. fine. Default is True. --skip-package-tests The packages tests, execute these to check if Nuitka handles packages, e.g. import recursions, etc. fine. Default is True. --skip-optimizations-tests The optimization tests, execute these to check if Nuitka does optimize certain constructs fully away. Default is True. --skip-standalone-tests The standalone tests, execute these to check if Nuitka standalone mode, e.g. not referring to outside, important 3rd library packages like PyQt fine. Default is True. --skip-reflection-test The reflection test compiles Nuitka with Nuitka, and then Nuitka with the compile Nuitka and compares the outputs. Default is True. --skip-cpython26-tests The standard CPython2.6 test suite. Execute this for all corner cases to be covered. With Python 2.7 this covers exception behavior quite well. Default is True. --skip-cpython27-tests The standard CPython2.7 test suite. Execute this for all corner cases to be covered. With Python 2.6 these are not run. Default is True. --skip-cpython32-tests The standard CPython3.2 test suite. Execute this for all corner cases to be covered. With Python 2.6 these are not run. Default is True. --skip-cpython33-tests The standard CPython3.3 test suite. Execute this for all corner cases to be covered. With Python 2.x these are not run. Default is True. --skip-cpython34-tests The standard CPython3.4 test suite. Execute this for all corner cases to be covered. With Python 2.x these are not run. Default is True. --skip-cpython35-tests The standard CPython3.5 test suite. Execute this for all corner cases to be covered. With Python 2.x these are not run. Default is True. --skip-cpython36-tests The standard CPython3.6 test suite. Execute this for all corner cases to be covered. With Python 2.x these are not run. Default is True. --skip-cpython37-tests The standard CPython3.7 test suite. Execute this for all corner cases to be covered. With Python 2.x these are not run. Default is True. --skip-cpython38-tests The standard CPython3.8 test suite. Execute this for all corner cases to be covered. With Python 2.x these are not run. Default is True. --skip-cpython39-tests The standard CPython3.9 test suite. Execute this for all corner cases to be covered. With Python 2.x these are not run. Default is True. --skip-cpython310-tests The standard CPython3.10 test suite. Execute this for all corner cases to be covered. With Python 2.x these are not run. Default is True. --skip-cpython311-tests The standard CPython3.11 test suite. Execute this for all corner cases to be covered. With Python 2.x these are not run. Default is True. --no-python2.6 Do not use Python 2.6 even if available on the system. Default is False. --no-python2.7 Do not use Python 2.7 even if available on the system. Default is False. --no-python3.3 Do not use Python 3.3 even if available on the system. Default is False. --no-python3.4 Do not use Python 3.4 even if available on the system. Default is False. --no-python3.5 Do not use Python 3.5 even if available on the system. Default is False. --no-python3.6 Do not use Python 3.6 even if available on the system. Default is False. --no-python3.7 Do not use Python 3.7 even if available on the system. Default is False. --no-python3.8 Do not use Python 3.8 even if available on the system. Default is False. --no-python3.9 Do not use Python 3.9 even if available on the system. Default is False. --no-python3.10 Do not use Python 3.10 even if available on the system. Default is False. --no-python3.11 Do not use Python 3.11 even if available on the system. Default is False. --coverage Make a coverage analysis, that does not really check. Default is False. You will only run the CPython test suites, if you have the submodules of the Nuitka git repository checked out. Otherwise, these will be skipped with a warning that they are not available. The policy is generally, that ``./test/run-tests`` running and passing all the tests on Linux and Windows shall be considered sufficient for a release, but of course, depending on changes going on, that might have to be expanded. Basic Tests =========== You can run the "basic" tests like this: .. code:: bash ./tests/basics/run_all.py search These tests normally give sufficient coverage to assume that a change is correct, if these "basic" tests pass. The most important constructs and built-ins are exercised. To control the Python version used for testing, you can set the ``PYTHON`` environment variable to e.g. ``python3.5`` (can also be full path), or simply execute the ``run_all.py`` script directly with the intended version, as it is portable across all supported Python versions, and defaults testing with the Python version is run with. Syntax Tests ============ Then there are "syntax" tests, i.e. language constructs that need to give a syntax error. It sometimes so happens that Nuitka must do this itself, because the ``ast.parse`` doesn't see the problem and raises no ``SyntaxError`` of its own. These cases are then covered by tests to make sure they work as expected. Using the ``global`` statement on a function argument is an example of this. These tests make sure that the errors of Nuitka and CPython are totally the same for this: .. code:: bash ./tests/syntax/run_all.py search Program Tests ============= Then there are small "programs" tests, that e.g. exercise many kinds of import tricks and are designed to reveal problems with inter-module behavior. These can be run like this: .. code:: bash ./tests/programs/run_all.py search Generated Tests =============== There are tests, which are generated from Jinja2 templates. They aim at e.g. combining at types with operations, in-place or not, or large constants. These can be run like this: .. code:: bash ./tests/generated/run_all.py search Compile Nuitka with Nuitka ========================== And there is the "compile itself" or "reflected" test. This test makes Nuitka compile itself and compare the resulting C++ when running compiled to non-compiled, which helps to find in-determinism. The test compiles every module of Nuitka into an extension module and all of Nuitka into a single binary. That test case also gives good coverage of the ``import`` mechanisms, because Nuitka uses a lot of packages and imports between them. .. code:: bash ./tests/reflected/compile_itself.py ********************* Internal/Plugin API ********************* The documentation from the source code for both the Python and the C parts are published as `Nuitka API `__ and arguably in a relatively bad shape as we started generating those with Doxygen only relatively late. .. code:: bash doxygen ./doc/Doxyfile xdg-open html Improvements have already been implemented for plugins: The plugin base class defined in ``PluginBase.py`` (which is used as a template for all plugins) is fully documented in Doxygen now. The same is true for the recently added standard plugins ``NumpyPlugin.py`` and ``TkinterPlugin.py``. These will be uploaded very soon. Going forward, this will also happen for the remaining standard plugins. Please find `here `__ a detailed description of how to write your own plugin. To learn about plugin option specification consult `this document `__. ********************************* Working with the CPython suites ********************************* Resetting CPython suites ======================== The CPython test suites are different branches of the same submodule. When you update your git checkout, they will frequently become detached. In this case, simply execute this command: .. code:: bash git submodule foreach 'git fetch && git checkout $(basename $(pwd)) && \ git reset --hard origin/$(basename $(pwd))' Added new CPython suites ======================== When adding a test suite, for a new version, proceed like this, of course while adapting of course the names. These are the commands used for adding CPython311 based on the CPython310 branch. .. code:: bash # Switch to a new branch. git checkout CPython310 git branch CPython311 git checkout CPython311 # Delete all but root commit git reset --hard `git log --root --oneline --reverse | head -1 | cut -d' ' -f1` # Switch test data to upstream ones. rm -rf test cp -r ~/repos/Nuitka-references/final/Python-3.11.0/Lib/test test git add test # Update commit message to mention proper Python version. git commit --amend -m "Initial commit of Python tests as in 3.11.0" # Push to github, setting upstream for branch. git push -u # Cherry pick the removal commits from previous branches. git log origin/CPython310 --reverse --oneline | grep ' Removed' | cut -d' ' -f1 | xargs git cherry-pick # When being prompted for merge conflicts with the deleted files: git status | sed -n 's/deleted by them://p' | xargs git rm --ignore-unmatch x ; git cherry-pick --continue # Push to github, this is useful. git push # Cherry pick the first commit of 'run_all.py', the copy it from the last state, and amend the commits. git log --reverse origin/CPython310 --oneline -- run_all.py | head -1 | cut -d' ' -f1 | xargs git cherry-pick git checkout origin/CPython310 -- run_all.py chmod +x run_all.py sed -i -e 's#python3.10#python3.11#' run_all.py git commit --amend --no-edit run_all.py # Same for 'update_doctest_generated.py' git log --reverse origin/CPython310 --oneline -- update_doctest_generated.py | head -1 | cut -d' ' -f1 | xargs git cherry-pick git checkout origin/CPython310 -- update_doctest_generated.py chmod +x update_doctest_generated.py sed -i -e 's#python3.10#python3.11#' update_doctest_generated.py git commit --amend --no-edit update_doctest_generated.py # Same for .gitignore git log --reverse origin/CPython310 --oneline -- .gitignore | head -1 | cut -d' ' -f1 | xargs git cherry-pick git checkout origin/CPython310 -- .gitignore git commit --amend --no-edit .gitignore # Now cherry-pick all commits of test support, these disable network, audio, GUI, random filenames and more # and are crucial for deterministic outputs and non-reliance on outside stuff. git log --reverse origin/CPython310 --oneline -- test/support/__init__.py | tail -n +2 | cut -d' ' -f1 | xargs git cherry-pick git push ********************* Design Descriptions ********************* These should be a lot more and contain graphics from presentations given. It will be filled in, but not now. Nuitka Logo =========== The logo was submitted by "dr. Equivalent". It's source is contained in ``doc/Logo`` where 3 variants of the logo in SVG are placed. - Symbol only (symbol) .. code:: rest .. image:: doc/images/Nuitka-Logo-Symbol.png :alt: Nuitka Logo - Text next to symbol (horizontal) .. code:: rest .. image:: doc/images/Nuitka-Logo-Horizontal.png :alt: Nuitka Logo - Text beneath symbol (vertical) .. code:: rest .. image:: doc/images/Nuitka-Logo-Vertical.png :alt: Nuitka Logo From these logos, PNG images, and "favicons", and are derived. The exact ImageMagick commands are in ``nuitka/tools/release/Documentation``, but are not executed each time, the commands are also replicated here: .. code:: bash convert -background none doc/Logo/Nuitka-Logo-Symbol.svg doc/images/Nuitka-Logo-Symbol.png convert -background none doc/Logo/Nuitka-Logo-Vertical.svg doc/images/Nuitka-Logo-Vertical.png convert -background none doc/Logo/Nuitka-Logo-Horizontal.svg doc/images/Nuitka-Logo-Horizontal.png Choice of the Target Language ============================= - Choosing the target language was important decision. factors were: - The portability of Nuitka is decided here - How difficult is it to generate the code? - Does the Python C-API have bindings? - Is that language known? - Does the language aid to find bugs? The *decision for C11* is ultimately one for portability, general knowledge of the language and for control over created code, e.g. being able to edit and try that quickly. The current status is to use pure C11. All code compiles as C11, and also in terms of workaround to missing compiler support as C++03. This is mostly needed, because MSVC does not support C. Naturally we are not using any C++ features, just the allowances of C++ features that made it into C11, which is e.g. allowing late definitions of variables. Use of Scons internally ======================= Nuitka does not involve Scons in its user interface at all; Scons is purely used internally. Nuitka itself, being pure Python, will run without any build process just fine. Nuitka simply prepares ``.build`` folders with lots of files and tasks scons to execute the final build, after which Nuitka again will take control and do more work as necessary. .. note:: When we speak of "standalone" mode, this is handled outside of Scons, and after it, creating the ".dist" folder. This is done in ``nuitka.MainControl`` module. For interfacing to Scons, there is the module ``nuitka.build.SconsInterface`` that will support calling ``scons`` - potentially from one of two inline copies (one for before / one for Python 3.5 or later). These are mainly used on Windows or when using source releases - and passing arguments to it. These arguments are passed as ``key=value``, and decoded in the scons file of Nuitka. The scons file is named ``SingleExe.scons`` for lack of better name. It's really wrong now, but we have yet to find a better name. It once expressed the intention to be used to create executables, but the same works for modules too, as in terms of building, and to Scons, things really are the same. The scons file supports operation in multiple modes for many things, and modules is just one of them. It runs outside of Nuitka process scope, even with a different Python version potentially, so all the information must be passed on the command line. What follows is the (lengthy) list of arguments that the scons file processes: - ``source_dir`` Where is the generated C source code. Scons will just compile everything it finds there. No list of files is passed, but instead this directory is being scanned. - ``nuitka_src`` Where do the include files and static C parts of Nuitka live. These provide e.g. the implementation of compiled function, generators, and other helper codes, this will point to where ``nuitka.build`` package lives normally. - ``module_mode`` Build a module instead of a program. - ``result_base`` This is not a full name, merely the basename for the result to be produced, but with path included, and the suffix comes from module or executable mode. - ``debug_mode`` Enable debug mode, which is a mode, where Nuitka tries to help identify errors in itself, and will generate less optimal code. This also asks for warnings, and makes the build fail if there are any. Scons will pass different compiler options in this case. - ``python_debug`` Compile and link against Python debug mode, which does assertions and extra checks, to identify errors, mostly related to reference counting. May make the build fail, if no debug build library of CPython is available. On Windows it is possible to install it for CPython3.5 or higher. - ``full_compat_mode`` Full compatibility, even where it's stupid, i.e. do not provide information, even if available, in order to assert maximum compatibility. Intended to control the level of compatibility to absurd. - ``experimental_mode`` Do things that are not yet accepted to be safe. - ``lto_mode`` Make use of link time optimization of gcc compiler if available and known good with the compiler in question. So far, this was not found to make major differences. - ``disable_console`` Windows subsystem mode: Disable console for windows builds. - ``unstripped_mode`` Unstripped mode: Do not remove debug symbols. - ``clang_mode`` Clang compiler mode, default on macOS X and FreeBSD, optional on Linux. - ``mingw_mode`` MinGW compiler mode, optional and useful on Windows only. - ``standalone_mode`` Building a standalone distribution for the binary. - ``show_scons`` Show scons mode, output information about Scons operation. This will e.g. also output the actual compiler used, output from compilation process, and generally debug information relating to be build process. - ``python_prefix`` Home of Python to be compiled against, used to locate headers and libraries. - ``target_arch`` Target architecture to build. Only meaningful on Windows. - ``python_version`` The major version of Python built against. - ``abiflags`` The flags needed for the Python ABI chosen. Might be necessary to find the folders for Python installations on some systems. - ``icon_path`` The icon to use for Windows programs if given. Locating Modules and Packages ============================= The search for modules used is driven by ``nuitka.importing.Importing`` module. - Quoting the ``nuitka.importing.Importing`` documentation: Locating modules and package source on disk. The actual import of a module would already execute code that changes things. Imagine a module that does ``os.system()``, it would be done during compilation. People often connect to databases, and these kind of things, at import time. Therefore CPython exhibits the interfaces in an ``imp`` module in standard library, which one can use those to know ahead of time, what file import would load. For us unfortunately there is nothing in CPython that is easily accessible and gives us this functionality for packages and search paths exactly like CPython does, so we implement here a multi step search process that is compatible. This approach is much safer of course and there is no loss. To determine if it's from the standard library, one can abuse the attribute ``__file__`` of the ``os`` module like it's done in ``isStandardLibraryPath`` of this module. End quoting the ``nuitka.importing.Importing`` documentation. - Role This module serves the recursion into modules and analysis if a module is a known one. It will give warnings for modules attempted to be located, but not found. These warnings are controlled by a while list inside the module. The decision making and caching are located in the ``nuitka.tree`` package, in modules ``nuitka.tree.Recursion`` and ``nuitka.tree.ImportCache``. Each module is only considered once (then cached), and we need to obey lots of user choices, e.g. to compile a standard library or not. Hooking for module ``import`` process ===================================== Currently, in generated code, for every ``import`` a normal ``__import__()`` built-in call is executed. The ``nuitka/build/static_src/MetaPathBasedLoader.c`` file provides the implementation of a ``sys.meta_path`` hook. This meta path based importer allows us to have the Nuitka provided module imported even when imported by non-compiled code. .. note:: Of course, it would make sense to compile time detect which module it is that is being imported and then to make it directly. At this time, we don't have this inter-module optimization yet, mid-term it should become easy to add. Supporting ``__class__`` of Python3 =================================== In Python3 the handling of ``__class__`` and ``super`` is different from Python2. It used to be a normal variable, and now the following things have changed. - The use of the ``super`` variable name triggers the addition of a closure variable ``__class__``, as can be witnessed by the following code: .. code:: python class X: def f1(self): print(locals()) def f2(self): print(locals()) super # Just using the name, not even calling it. x = X() x.f1() x.f2() Output is: .. code:: {'self': <__main__.X object at 0x7f1773762390>''} {'self': <__main__.X object at 0x7f1773762390>, '__class__': } - This value of ``__class__`` is also available in the child functions. - The parser marks up code objects usage of "super". It doesn't have to be a call, it can also be a local variable. If the ``super`` built-in is assigned to another name and that is used without arguments, it won't work unless ``__class__`` is taken as a closure variable. - As can be seen in the CPython3 code, the closure value is added after the class creation is performed. - It appears, that only functions locally defined to the class are affected and take the closure. This left Nuitka with the strange problem, of how to emulate that. The solution is this: - Under Python3, usage of ``__class__`` as a reference in a child function body is mandatory. It remains that way until all variable names have been resolved. - When recognizing calls to ``super`` without arguments, make the arguments into variable reference to ``__class__`` and potentially ``self`` (actually first argument name). - After all variables have been known, and no suspicious unresolved calls to anything named ``super`` are down, then unused references are optimized away by the normal unused closure variable. - Class dictionary definitions are added. These are special direct function calls, ready to propagate also "bases" and "metaclass" values, which need to be calculated outside. The function bodies used for classes will automatically store ``__class__`` as a shared local variable, if anything uses it. And if it's not assigned by user code, it doesn't show up in the "locals()" used for dictionary creation. Existing ``__class__`` local variable values are in fact provided as closure, and overridden with the built class , but they should be used for the closure giving, before the class is finished. So ``__class__`` will be local variable of the class body, until the class is built, then it will be the ``__class__`` itself. Frame Stack =========== In Python, every function, class, and module has a frame. It is created when the scope is entered, and there is a stack of these at run time, which becomes visible in tracebacks in case of exceptions. The choice of Nuitka is to make this an explicit element of the node tree, that are as such subject to optimization. In cases, where they are not needed, they may be removed. Consider the following code. .. code:: python def f(): if someNotRaisingCall(): return somePotentiallyRaisingCall() else: return None In this example, the frame is not needed for all the code, because the condition checked wouldn't possibly raise at all. The idea is the make the frame guard explicit and then to reduce its scope whenever possible. So we start out with code like this one: .. code:: python def f(): with frame_guard("f"): if someNotRaisingCall(): return somePotentiallyRaisingCall() else: return None This is to be optimized into: .. code:: python def f(): if someNotRaisingCall(): with frame_guard("f"): return somePotentiallyRaisingCall() else: return None Notice how the frame guard taking is limited and may be avoided, or in best cases, it might be removed completely. Also this will play a role when in-lining function. The frame stack entry will then be automatically preserved without extra care. .. note:: In the actual code, ``nuitka.nodes.FrameNodes.StatementsFrame`` is represents this as a set of statements to be guarded by a frame presence. Parameter Parsing ================= The parsing of parameters is very convoluted in Python, and doing it in a compatible way is not that easy. This is a description of the required process, for an easier overview. Input ----- The input is an argument ``tuple`` (the type is fixed), which contains the positional arguments, and potentially an argument ``dict`` (type is fixed as well, but could also be ``NULL``, indicating that there are no keyword arguments. Keyword dictionary ------------------ The keyword argument dictionary is checked first. Anything in there, that cannot be associated, either raise an error, or is added to a potentially given star dict argument. So there are two major cases. - No star dict argument: Iterate over dictionary, and assign or raise errors. This check covers extra arguments given. - With star dict argument: Iterate over dictionary, and assign or raise errors. Interesting case for optimization are no positional arguments, then no check is needed, and the keyword argument dictionary could be used as the star argument. Should it change, a copy is needed though. What's noteworthy here, is that in comparison to the keywords, we can hope that they are the same value as we use. The interning of strings increases chances for non-compiled code to do that, esp. for short names. We then can do a simple ``is`` comparison and only fall back to real string ``==`` comparisons, after all of these failed. That means more code, but also a lot faster code in the positive case. Argument tuple -------------- After this completed, the argument tuple is up for processing. The first thing it needs to do is to check if it's too many of them, and then to complain. For arguments in Python2, there is the possibility of them being nested, in which case they cannot be provided in the keyword dictionary, and merely should get picked from the argument tuple. Otherwise, the length of the argument tuple should be checked against its position and if possible, values should be taken from there. If it's already set (from the keyword dictionary), raise an error instead. SSA form for Nuitka =================== The SSA form is critical to how optimization works. The so called trace collections builds up traces. These are facts about how this works: - Assignments draw from a counter unique for the variable, which becomes the variable version. This happens during tree building phase. - References are associated with the version of the variable active. This can be a merge of branches. Trace collection does do that and provides nodes with the currently active trace for a variable. The data structures used for trace collection need to be relatively compact as the trace information can become easily much more data than the program itself. Every trace collection has these: - variable_actives Dictionary, where per "variable" the currently used version is. Used to track situations changes in branches. This is the main input for merge process. - variable_traces Dictionary, where "variable" and "version" form the key. The values are objects with or without an assignment, and a list of usages, which starts out empty. These objects have usages appended to them. In "onVariableSet", a new version is allocated, which gives a new object for the dictionary, with an empty usages list, because each write starts a new version. In "onVariableUsage" the version is detected from the current version. It may be not set yet, which means, it's a read of an undefined value (local variable, not a parameter name), or unknown in case of global variable. These objects may be told that their value has escaped. This should influence the value friend they attached to the initial assignment. Each usage may have a current value friend state that is different. When merging branches of conditional statements, the merge shall apply as follows: - Branches have their own collection Thee have potentially deviating sets of ``variable_actives``. These are children of an outer collections. - Case a) One branch only. For that branch a collection is performed. As usual new assignments generate a new version making it "active", references then related to these "active" versions. Then, when the branch is merged, for all "active" variables, it is considered, if that is a change related to before the branch. If it's not the same, a merge trace with the branch condition is created with the one active in the collection before that statement. - Case b) Two branches. When there are two branches, they both as are treated as above, except for the merge. When merging, a difference in active variables between the two branches creates the merge trace. .. note:: For conditional expressions, there are always only two branches. Even if you think you have more than one branch, you do not. It's always nested branches, already when it comes out of the ``ast`` parser. Trace structure, there are different kinds of traces. - Initial write of the version There may be an initial write for each version. It can only occur at the start of the scope, but not later, and there is only one. This might be known to be "initialized" (parameter variables of functions are like that) or "uninitialized", or "unknown". - Merge of other one or two other versions This combines two or more previous versions. In cases of loop exits or entries, there are multiple branches to combine potentially. These branches can have vastly different properties. - Becoming unknown. When control flow escapes, e.g. for a module variable, any write can occur to it, and it's value cannot be trusted to be unchanged. These are then traced as unknown. All traces have a base class ``ValueTraceBase`` which provides the interface to query facts about the state of a variable in that trace. It's e.g. of some interest, if a variable must have a value or must not. This allows to e.g. omit checks, know what exceptions might raise. Loop SSA ======== For loops we have the addition difficulty that we need would need to look ahead what types a variable has at loop exit, but that is a cyclic dependency. Our solution is to consider the variable types at loop entry. When these change, we drop all gained information from inside the loop. We may e.g. think that a variable is a ``int`` or ``float``, but later recognize that it can only be a float. Derivations from ``int`` must be discarded, and the loop analysis restarted. Then during the loop, we assign an incomplete loop trace shape to the variable, which e.g. says it was an ``int`` initially and additional type shapes, e.g. ``int or long`` are then derived. If at the end of the loop, a type produced no new types, we know we are finished and mark the trace as a complete loop trace. If it is not, and next time, we have the same initial types, we add the ones derived from this to the starting values, and see if this gives more types. Python Slots in Optimization ============================ Basic Slot Idea --------------- For almost all the operations in Python, a form of overloading is available. That is what makes it so powerful. So when you write an expression like this one: .. code:: python 1.0 + something This something will not just blindly work when it's a float, but go through a slot mechanism, which then can be overloaded. .. code:: python class SomeStrangeFloat: def __float__(self): return 3.14 something = SomeStrangeFloat() # ... 1.0 + float(something) // 4.140000000000001 Here it is the case, that this is used by user code, but more often this is used internally. Not all types have all slots, e.g. ``list`` does not have ``__float__`` and therefore will refuse an addition to a ``float`` value, based on that. Another slot is working here, that we didn't mention yet, and that is ``__add__`` which for some times will be these kinds of conversions or it will not do that kind of thing, e.g. something do hard checks, which is why this fails to work: .. code:: python [] + () As a deliberate choice, there is no ``__list__`` slot used. The Python designers are aiming at solving many things with slots, but they also accept limitations. There are many slots that are frequently used, most often behind your back (``__iter__``, ``__next__``, ``__lt__``, etc.). The list is large, and tends to grow with Python releases, but it is not endless. Representation in Nuitka ------------------------ So a slot in Nuitka typically has an owning node. We use ``__len__`` as an example here. In the ``computeExpression`` the ``len`` node named ``ExpressionBuiltinLen`` has to defer the decision what it computes to its argument. .. code:: python def computeExpression(self, trace_collection): return self.subnode_value.computeExpressionLen( len_node=self, trace_collection=trace_collection ) That decision then, in the absence of any type knowledge, must be done absolutely carefully and conservative, as could see anything executing here. That examples this code in ``ExpressionBase`` which every expression by default uses: .. code:: python def computeExpressionLen(self, len_node, trace_collection): shape = self.getValueShape() has_len = shape.hasShapeSlotLen() if has_len is False: return makeRaiseTypeErrorExceptionReplacementFromTemplateAndValue( template="object of type '%s' has no len()", operation="len", original_node=len_node, value_node=self, ) elif has_len is True: iter_length = self.getIterationLength() if iter_length is not None: from .ConstantRefNodes import makeConstantRefNode result = makeConstantRefNode( constant=int(iter_length), # make sure to downcast long source_ref=len_node.getSourceReference(), ) result = wrapExpressionWithNodeSideEffects(new_node=result, old_node=self) return ( result, "new_constant", "Predicted 'len' result from value shape.", ) self.onContentEscapes(trace_collection) # Any code could be run, note that. trace_collection.onControlFlowEscape(self) # Any exception may be raised. trace_collection.onExceptionRaiseExit(BaseException) return len_node, None, None Notice how by default, known ``__len__`` but unpredictable or even unknown if a ``__len__`` slot is there, the code indicates that its contents and the control flow escapes (could change things behind out back) and any exception could happen. Other expressions can know better, e.g. for compile time constants we can be a whole lot more certain: .. code:: python def computeExpressionLen(self, len_node, trace_collection): return trace_collection.getCompileTimeComputationResult( node=len_node, computation=lambda: len(self.getCompileTimeConstant()), description="""Compile time constant len value pre-computed.""", ) In this case, we are using a function that will produce a concrete value or the exception that the ``computation`` function raised. In this case, we can let the Python interpreter that runs Nuitka do all the hard work. This lives in ``CompileTimeConstantExpressionBase`` and is the base for all kinds of constant values, or even built-in references like the name ``len`` itself and would be used in case of doing ``len(len)`` which obviously gives an exception. Other overloads do not currently exist in Nuitka, but through the iteration length, most cases could be addressed, e.g. ``list`` nodes typical know their element counts. The C side ========== When a slot is not optimized away at compile time however, we need to generate actual code for it. We figure out what this could be by looking at the original CPython implementation. .. code:: C PyObject *builtin_len(PyObject *self, PyObject *v) { Py_ssize_t res; res = PyObject_Size(v); if (res < 0 && PyErr_Occurred()) return NULL; return PyInt_FromSsize_t(res); } We find a pointer to ``PyObject_Size`` which is a generic Python C/API function used in the ``builtin_len`` implementation: .. code:: C Py_ssize_t PyObject_Size(PyObject *o) { PySequenceMethods *m; if (o == NULL) { null_error(); return -1; } m = o->ob_type->tp_as_sequence; if (m && m->sq_length) return m->sq_length(o); return PyMapping_Size(o); } On the C level, every Python object (the ``PyObject *``) as a type named ``ob_type`` and most of its elements are slots. Sometimes they form a group, here ``tp_as_sequence`` and then it may or may not contain a function. This one is tried in preference. Then, if that fails, next up the mapping size is tried. .. code:: C Py_ssize_t PyMapping_Size(PyObject *o) { PyMappingMethods *m; if (o == NULL) { null_error(); return -1; } m = o->ob_type->tp_as_mapping; if (m && m->mp_length) return m->mp_length(o); type_error("object of type '%.200s' has no len()", o); return -1; } This is the same principle, except with ``tp_as_mapping`` and ``mp_length`` used. So from this, we can tell how ``len`` gets at what could be a Python class ``__len__`` or other built-in types. In principle, every slot needs to be dealt with in Nuitka, and it is assumed that currently all slots are supported on at least a very defensive level, to avoid unnoticed escapes of control flow. Built-in call optimization ========================== For calls to built-in names, there is typically a function in Python that delegates to the type constructor (e.g. when we talk about ``int`` that just creates an object passing the arguments of the call) or its own special implementation as we saw with the ``len``. For each built-in called, we have a specialized node, that presents to optimization the actions of the built-in. What are the impact, what are the results. We have seen the resulting example for ``len`` above, but how do we get there. In Python, built-in names are used only if there is no module level variable of the name, and of course no local variable of that name. Therefore, optimization of a built-in name is only done if it turns out the actually assigned in other code, and then when the call comes, arguments are checked and a relatively static node is created. Code Generation towards C ========================= Currently, Nuitka uses Pure C and no C++ patterns at all. The use of C11 requires on some platforms to compile the C11 using a C++ compiler, which works relatively well, but also limits the amount of C11 that can be used. Exceptions ---------- To handle and work with exceptions, every construct that can raise has either a ``bool`` or ``int`` return code or ``PyObject *`` with ``NULL`` return value. This is very much in line with that the Python C-API does. Every helper function that contains code that might raise needs these variables. After a failed call, our variant of ``PyErr_Fetch`` called ``FETCH_ERROR_OCCURRED_STATE`` must be used to catch the defined error, unless some quick exception cases apply. The quick exception means, ``NULL`` return from C-API without a set exception means e.g. ``StopIteration``. As an optimization, functions that raise exceptions, but are known not to do so, for whatever reason, could only be asserted to not do so. Statement Temporary Variables ----------------------------- For statements and larger constructs the context object track temporary values, that represent references. For some, these should be released at the end of the statement, or they represent a leak. The larger scope temporary variables, are tracked in the function or module context, where they are supposed to have explicit ``del`` to release their references. Local Variables Storage ----------------------- Closure variables taken are to be released when the function object is later destroyed. For in-lined calls, variables are just passed, and it does not become an issue to release anything. For function exit, owned variables, local or shared to other functions, must be released. This cannot be a ``del`` operation, as it also involves setting a value, which would be wrong for shared variables (and wasteful to local variables, as that would be its last usage). Therefore we need a special operation that simply releases the reference to the cell or object variable. Exit Targets ------------ Each error or other exit releases statement temporary values and then executes a ``goto`` to the exit target. These targets need to be setup. The ``try``/``except`` will e.g. catch error exits. Other exits are ``continue``, ``break``, and ``return`` exits. They all work alike. Generally, the exits stack of with constructs that need to register themselves for some exit types. A loop e.g. registers the ``continue`` exit, and a contained ``try``/``finally`` too, so it can execute the final code should it be needed. Frames ------ Frames are containers for variable declarations and cleanups. As such, frames provide error exits and success exits, which remove the frame from the frame stack, and then proceed to the parent exit. With the use of non ``PyObject **`` C types, but frame exception exits, the need to convert those types becomes apparent. Exceptions should still resolve the C version. When using different C types at frame exception exits, there is a need to trace the active type, so it can be used in the correct form. Abortive Statements ------------------- The way ``try``/``finally`` is handled, copies of the ``finally`` block are made, and optimized independently for each abort method. The ones there are of course, ``return``, ``continue``, and ``break``, but also implicit and explicit ``raise`` of an exception. Code trailing an abortive statement can be discarded, and the control flow will follow these "exits". Constant Preparation ==================== Early versions of Nuitka, created all constants for the whole program for ready access to generated code, before the program launches. It did so in a single file, but that approach didn't scale well. Problems were - Even unused code contributed to start-up time, this can become a lot for large programs, especially in standalone mode. - The massive amount of constant creation codes gave backend C compilers a much harder time than necessary to analyse it all at once. The current approach is as follows. Code generation detects constants used in only one module, and declared ``static`` there, if the module is the only user, or ``extern`` if it is not. Some values are forced to be global, as they are used pre-main or in helpers. These ``extern`` values are globally created before anything is used. The ``static`` values are created when the module is loaded, i.e. something did import it. We trace used constants per module, and for nested ones, we also associate them. The global constants code is special in that it can only use ``static`` for nested values it exclusively uses, and has to export values that others use. Language Conversions to make things simpler =========================================== There are some cases, where the Python language has things that can in fact be expressed in a simpler or more general way, and where we choose to do that at either tree building or optimization time. The ``assert`` statement ------------------------ The ``assert`` statement is a special statement in Python, allowed by the syntax. It has two forms, with and without a second argument. The later is probably less known, as is the fact that raise statements can have multiple arguments too. The handling in Nuitka is: .. code:: python assert value # Absolutely the same as: if not value: raise AssertionError .. code:: python assert value, raise_arg # Absolutely the same as: if not value: raise AssertionError(raise_arg) This makes assertions absolutely the same as a raise exception in a conditional statement. This transformation is performed at tree building already, so Nuitka never knows about ``assert`` as an element and standard optimizations apply. If e.g. the truth value of the assertion can be predicted, the conditional statement will have the branch statically executed or removed. The "comparison chain" expressions ---------------------------------- In Nuitka we have the concept of an outline, and therefore we can make the following re-formulation instead: .. code:: python a < b() > c < d def _comparison_chain(): # So called "outline" function tmp_a = a tmp_b = b() tmp = tmp_a < tmp_b if not tmp: return tmp del tmp_a tmp_c = c tmp = tmp_b > tmp_c if not tmp: return tmp del tmp_b return tmp_c < d _comparison_chain() This transformation is performed at tree building already. The temporary variables keep the value for the use of the same expression. Only the last expression needs no temporary variable to keep it. What we got from this, is making the checks of the comparison chain explicit and comparisons in Nuitka to be internally always about two operands only. The ``execfile`` built-in ------------------------- Handling is: .. code:: python execfile(filename) # Basically the same as: exec(compile(open(filename).read()), filename, "exec") .. note:: This allows optimizations to discover the file opening nature easily and apply file embedding or whatever we will have there one day. This transformation is performed when the ``execfile`` built-in is detected as such during optimization. Generator expressions with ``yield`` ------------------------------------ These are converted at tree building time into a generator function body that yields from the iterator given, which is the put into a for loop to iterate, created a lambda function of and then called with the first iterator. That eliminates the generator expression for this case. It's a bizarre construct and with this trick needs no special code generation. This is a complex example, demonstrating multiple cases of yield in unexpected cases: .. code:: python x = ((yield i) for i in (1, 2) if not (yield)) # Basically the same as: def x(): for i in (1, 2): if not (yield): yield (yield i) Function Decorators ------------------- When one learns about decorators, you see that: .. code:: python @decorator def function(): pass # Is basically the same as: def function(): pass function = decorator(function) The only difference is the assignment to function. In the ``@decorator`` case, if the decorator fails with an exception, the name ``function`` is not assigned yet, but kept in a temporary variable. Therefore in Nuitka this assignment is more similar to that of a lambda expression, where the assignment to the name is only at the end, which also has the extra benefit of not treating real function and lambda functions any different. This removes the need for optimization and code generation to support decorators at all. And it should make the two variants optimize equally well. Functions nested arguments -------------------------- Nested arguments are a Python2 only feature supported by Nuitka. Consider this example: .. code:: python def function(a, (b, c)): return a, b, c We solve this, by kind of wrapping the function with another function that does the unpacking and gives the errors that come from this: .. code:: python def function(a, _1): def _tmp(a, b, c): return a, b, c a, b = _1 return _tmp(a, b, c) The ``.1`` is the variable name used by CPython internally, and actually works if you use keyword arguments via star dictionary. So this is very compatible and actually the right kind of re-formulation, but it removes the need from the code that does parameter parsing to deal with these. Obviously, there is no frame for ``_tmp``, just one for ``function`` and we do not use local variables, but temporary functions. In-place Assignments -------------------- In-place assignments are re-formulated to an expression using temporary variables. These are not as much a reformulation of ``+=`` to ``+``, but instead one which makes it explicit that the assign target may change its value. .. code:: python a += b .. code:: python _tmp = a.__iadd__(b) if a is not _tmp: a = _tmp Using ``__iadd__`` here to express that for the ``+``, the in-place variant ``iadd`` is used instead. The ``is`` check may be optimized away depending on type and value knowledge later on. Complex Assignments ------------------- Complex assignments are defined as those with multiple targets to assign from a single source and are re-formulated to such using a temporary variable and multiple simple assignments instead. .. code:: python a = b = c .. code:: python _tmp = c a = _tmp b = _tmp del _tmp This is possible, because in Python, if one assignment fails, it can just be interrupted, so in fact, they are sequential, and all that is required is to not calculate ``c`` twice, which the temporary variable takes care of. Were ``b`` a more complex expression, e.g. ``b.some_attribute`` that might raise an exception, ``a`` would still be assigned. Unpacking Assignments --------------------- Unpacking assignments are re-formulated to use temporary variables as well. .. code:: python a, b.attr, c[ind] = d = e, f, g = h() Becomes this: .. code:: python _tmp = h() _iter1 = iter(_tmp) _tmp1 = unpack(_iter1, 3) _tmp2 = unpack(_iter1, 3) _tmp3 = unpack(_iter1, 3) unpack_check(_iter1) a = _tmp1 b.attr = _tmp2 c[ind] = _tmp3 d = _tmp _iter2 = iter(_tmp) _tmp4 = unpack(_iter2, 3) _tmp5 = unpack(_iter2, 3) _tmp6 = unpack(_iter2, 3) unpack_check(_iter1) e = _tmp4 f = _tmp5 g = _tmp6 That way, the unpacking is decomposed into multiple simple statements. It will be the job of optimizations to try and remove unnecessary unpacking, in case e.g. the source is a known tuple or list creation. .. note:: The ``unpack`` is a special node which is a form of ``next`` that will raise a ``ValueError`` when it cannot get the next value, rather than a ``StopIteration``. The message text contains the number of values to unpack, therefore the integer argument. .. note:: The ``unpack_check`` is a special node that raises a ``ValueError`` exception if the iterator is not finished, i.e. there are more values to unpack. Again the number of values to unpack is provided to construct the error message. With Statements --------------- The ``with`` statements are re-formulated to use temporary variables as well. The taking and calling of ``__enter__`` and ``__exit__`` with arguments, is presented with standard operations instead. The promise to call ``__exit__`` is fulfilled by ``try``/``except`` clause instead. .. code:: python with some_context as x: something(x) .. code:: python tmp_source = some_context # Actually it needs to be "special look-up" for Python2.7, so attribute # look-up won't be exactly what is there. tmp_exit = tmp_source.__exit__ # This one must be held for the whole with statement, it may be assigned # or not, in our example it is. If an exception occurs when calling # ``__enter__``, the ``__exit__`` should not be called. tmp_enter_result = tmp_source.__enter__() # Indicator variable to know if "tmp_exit" has been called. tmp_indicator = False try: # Now the assignment is to be done, if there is any name for the # manager given, this may become multiple assignment statements and # even unpacking ones. x = tmp_enter_result # Then the code of the "with" block. something(x) except Exception: # Note: This part of the code must not set line numbers, which we # indicate with special source code references, which we call "internal". # Otherwise the line of the frame would get corrupted. tmp_indicator = True if not tmp_exit(*sys.exc_info()): raise finally: if not tmp_indicator: # Call the exit if no exception occurred with all arguments # as "None". tmp_exit(None, None, None) .. note:: We don't refer really to ``sys.exc_info()`` at all, instead, we have fast references to the current exception type, value and trace, taken directly from the caught exception object on the C level. If we had the ability to optimize ``sys.exc_info()`` to do that, we could use the same transformation, but right now we don't have it. For Loops --------- The ``for`` loops use normal assignments and handle the iterator that is implicit in the code explicitly. .. code:: python for x, y in iterable: if something(x): break else: otherwise() This is roughly equivalent to the following code: .. code:: python _iter = iter(iterable) _no_break_indicator = False while 1: try: _tmp_value = next(_iter) except StopIteration: # Set the indicator that the else branch may be executed. _no_break_indicator = True # Optimization should be able to tell that the else branch is run # only once. break # Normal assignment re-formulation applies to this assignment of course. x, y = _tmp_value del _tmp_value if something(x): break if _no_break_indicator: otherwise() .. note:: The ``_iter`` temporary variable is of course also in a ``try/finally`` construct, to make sure it releases after its used. The ``x, y`` assignment is of course subject to unpacking re-formulation. The ``try``/``except`` is detected to allow to use a variant of ``next`` that does not raise an exception, but to be fast check about the ``NULL`` return from ``next`` built-in. So no actual exception handling is happening in this case. While Loops ----------- Quoting the ``nuitka.tree.ReformulationWhileLoopStatements`` documentation: Reformulation of while loop statements. Loops in Nuitka have no condition attached anymore, so while loops are re-formulated like this: .. code:: python while condition: something() .. code:: python while 1: if not condition: break something() This is to totally remove the specialization of loops, with the condition moved to the loop body in an initial conditional statement, which contains a ``break`` statement. That achieves, that only ``break`` statements exit the loop, and allow for optimization to remove always true loop conditions, without concerning code generation about it, and to detect such a situation, consider e.g. endless loops. .. note:: Loop analysis (not yet done) can then work on a reduced problem (which ``break`` statements are executed under what conditions) and is then automatically very general. The fact that the loop body may not be entered at all, is still optimized, but also in the general sense. Explicit breaks at the loop start and loop conditions are the same. End quoting the ``nuitka.tree.ReformulationWhileLoopStatements`` documentation: Exception Handlers ------------------ Exception handlers in Python may assign the caught exception value to a variable in the handler definition. And the different handlers are represented as conditional checks on the result of comparison operations. .. code:: python try: block() except A as e: handlerA(e) except B as e: handlerB(e) else: handlerElse() .. code:: python try: block() except: # These are special nodes that access the exception, and don't really # use the "sys" module. tmp_exc_type = sys.exc_info()[0] tmp_exc_value = sys.exc_info()[1] # exception_matches is a comparison operation, also a special node. if exception_matches(tmp_exc_type, (A,)): e = tmp_exc_value handlerA(e) elif exception_matches(tmp_exc_type, (B,)): e = tmp_exc_value handlerB(e) else: handlerElse() For Python3, the assigned ``e`` variables get deleted at the end of the handler block. Should that value be already deleted, that ``del`` does not raise, therefore it's tolerant. This has to be done in any case, so for Python3 it is even more complex. .. code:: python try: block() except: # These are special nodes that access the exception, and don't really # use the "sys" module. tmp_exc_type = sys.exc_info()[0] tmp_exc_value = sys.exc_info()[1] # exception_matches is a comparison operation, also a special node. if exception_matches(tmp_exc_type, (A,)): try: e = tmp_exc_value handlerA(e) finally: del e elif exception_matches(tmp_exc_type, (B,)): try: e = tmp_exc_value handlerB(e) finally: del e else: handlerElse() Should there be no ``else:`` branch, a default re-raise statement is used instead. And of course, the values of the current exception type and value, both use special references, that access the C++ and don't go via ``sys.exc_info`` at all, nodes called ``CaughtExceptionTypeRef`` and ``CaughtExceptionValueRef``. This means, that the different handlers and their catching run time behavior are all explicit and reduced the branches. Statement ``try``/``except`` with ``else`` ------------------------------------------ Much like ``else`` branches of loops, an indicator variable is used to indicate the entry into any of the exception handlers. Therefore, the ``else`` becomes a real conditional statement in the node tree, checking the indicator variable and guarding the execution of the ``else`` branch. Class Creation (Python2) ------------------------ Classes in Python2 have a body that only serves to build the class dictionary and is a normal function otherwise. This is expressed with the following re-formulation: .. code:: python # in module "SomeModule" # ... class SomeClass(SomeBase, AnotherBase): """ This is the class documentation. """ some_member = 3 .. code:: python def _makeSomeClass(): # The module name becomes a normal local variable too. __module__ = "SomeModule" # The doc string becomes a normal local variable. __doc__ = """ This is the class documentation. """ some_member = 3 return locals() # force locals to be a writable dictionary, will be optimized away, but # that property will stick. This is only to express, that locals(), where # used will be writable to. exec("") SomeClass = make_class("SomeClass", (SomeBase, AnotherBase), _makeSomeClass()) That is roughly the same, except that ``_makeSomeClass`` is *not* visible to its child functions when it comes to closure taking, which we cannot express in Python language at all. Therefore, class bodies are just special function bodies that create a dictionary for use in class creation. They don't really appear after the tree building stage anymore. The type inference will of course have to become able to understand ``make_class`` quite well, so it can recognize the created class again. Class Creation (Python3) ------------------------ In Python3, classes are a complicated way to write a function call, that can interact with its body. The body starts with a dictionary provided by the metaclass, so that is different, because it can ``__prepare__`` a non-empty locals for it, which is hidden away in "prepare_class_dict" below. What's noteworthy, is that this dictionary, could e.g. be an ``OrderDict``. I am not sure, what ``__prepare__`` is allowed to return. .. code:: python3 # in module "SomeModule" # ... class SomeClass(SomeBase, AnotherBase, metaclass = SomeMetaClass): """ This is the class documentation. """ some_member = 3 .. code:: python # Non-keyword arguments, need to be evaluated first. tmp_bases = (SomeBase, AnotherBase) # Keyword arguments go next, __metaclass__ is just one of them. In principle # we need to forward the others as well, but this is ignored for the sake of # brevity. tmp_metaclass = select_metaclass(tmp_bases, SomeMetaClass) tmp_prepared = tmp_metaclass.__prepare__("SomeClass", tmp_bases) # The function that creates the class dictionary. Receives temporary variables # to work with. def _makeSomeClass(): # This has effect, currently I don't know how to express that in Python3 # syntax, but we will have a node that does that. locals().replace(tmp_prepared) # The module name becomes a normal local variable too. __module__ = "SomeModule" # The doc string becomes a normal local variable. __doc__ = """ This is the class documentation. """ some_member = 3 # Create the class, share the potential closure variable "__class__" # with others. __class__ = tmp_metaclass("SomeClass", tmp_bases, locals()) return __class__ # Build and assign the class. SomeClass = _makeSomeClass() Generator Expressions --------------------- There are re-formulated as functions. Generally they are turned into calls of function bodies with (potentially nested) for loops: .. code:: python gen = (x * 2 for x in range(8) if cond()) .. code:: python def _gen_helper(__iterator): for x in __iterator: if cond(): yield x * 2 gen = _gen_helper(range(8)) List Contractions ----------------- The list contractions of Python2 are different from those of Python3, in that they don't actually do any closure variable taking, and that no function object ever exists. .. code:: python list_value = [x * 2 for x in range(8) if cond()] .. code:: python def _listcontr_helper(__iterator): result = [] for x in __iterator: if cond(): result.append(x * 2) return result list_value = _listcontr_helper(range(8)) The difference is that with Python3, the function "_listcontr_helper" is really there and named ```` (or ```` as of Python3.7 or higher), whereas with Python2 the function is only an outline, so it can readily access the containing name space. Set Contractions ---------------- The set contractions of Python2.7 are like list contractions in Python3, in that they produce an actual helper function: .. code:: python set_value = {x * 2 for x in range(8) if cond()} .. code:: python def _setcontr_helper(__iterator): result = set() for x in __iterator: if cond(): result.add(x * 2) return result set_value = _setcontr_helper(range(8)) Dictionary Contractions ----------------------- The dictionary contractions of are like list contractions in Python3, in that they produce an actual helper function: .. code:: python dict_value = {x: x * 2 for x in range(8) if cond()} .. code:: python def _dictcontr_helper(__iterator): result = {} for x in __iterator: if cond(): result[x] = x * 2 return result set_value = _dictcontr_helper(range(8)) Boolean expressions ``and`` and ``or`` -------------------------------------- The short circuit operators ``or`` and ``and`` tend to be only less general that the ``if``/``else`` expressions, but have dedicated nodes. We used to have a re-formulation towards those, but we now do these via dedicated nodes too. These new nodes, present the evaluation of the left value, checking for its truth value, and depending on it, to pick it, or use the right value. Simple Calls ------------ As seen below, even complex calls are simple calls. In simple calls of Python there is still some hidden semantic going on, that we expose. .. code:: python func(arg1, arg2, named1=arg3, named2=arg4) On the C-API level there is a tuple and dictionary built. This one is exposed: .. code:: python func(*(arg1, arg2), **{"named1": arg3, "named2": arg4}) A called function will access this tuple and the dictionary to parse the arguments, once that is also re-formulated (argument parsing), it can then lead to simple in-lining. This way calls only have 2 arguments with constant semantics, that fits perfectly with the C-API where it is the same, so it is actually easier for code generation. Although the above looks like a complex call, it actually is not. No checks are needed for the types of the star arguments and it's directly translated to ``PyObject_Call``. Complex Calls ------------- The call operator in Python allows to provide arguments in 4 forms. - Positional (or normal) arguments - Named (or keyword) arguments - Star list arguments - Star dictionary arguments The evaluation order is precisely that. An example would be: .. code:: python something(pos1, pos2, name1=named1, name2=named2, *star_list, **star_dict) The task here is that first all the arguments are evaluated, left to right, and then they are merged into only two, that is positional and named arguments only. for this, the star list argument and the star dictionary arguments, are merged with the positional and named arguments. What's peculiar, is that if both the star list and dictionary arguments are present, the merging is first done for star dictionary, and only after that for the star list argument. This makes a difference, because in case of an error, the star argument raises first. .. code:: python something(*1, **2) This raises "TypeError: something() argument after ** must be a mapping, not int" as opposed to a possibly more expected "TypeError: something() argument after * must be a sequence, not int." That doesn't matter much though, because the value is to be evaluated first anyway, and the check is only performed afterwards. If the star list argument calculation gives an error, this one is raised before checking the star dictionary argument. So, what we do, is we convert complex calls by the way of special functions, which handle the dirty work for us. The optimization is then tasked to do the difficult stuff. Our example becomes this: .. code:: python def _complex_call(called, pos, kw, star_list_arg, star_dict_arg): # Raises errors in case of duplicate arguments or tmp_star_dict not # being a mapping. tmp_merged_dict = merge_star_dict_arguments( called, tmp_named, mapping_check(called, tmp_star_dict) ) # Raises an error if tmp_star_list is not a sequence. tmp_pos_merged = merge_pos_arguments(called, tmp_pos, tmp_star_list) # On the C-API level, this is what it looks like. return called(*tmp_pos_merged, **tmp_merged_dict) returned = _complex_call( called=something, pos=(pos1, pos2), named={"name1": named1, "name2": named2}, star_list_arg=star_list, star_dict_arg=star_dict, ) The call to ``_complex_call`` is be a direct function call with no parameter parsing overhead. And the call in its end, is a special call operation, which relates to the ``PyObject_Call`` C-API. Assignment Expressions ---------------------- In Python 3.8 or higher, you assign inside expressions. .. code:: python if (x := cond()): do_something() this is the same as: .. code:: python # Doesn't exist with that name, and it is not really taking closure variables, # it just shares the execution context. def _outline_func(): nonlocal x x = cond() return x if (_outline_func()): do_something When we use this outline function, we are allowed statements, even assignments, in expressions. For optimization, they of course pose a challenge to be removed ever, only happens when it becomes only a return statement, but they do not cause much difficulties for code generation, since they are transparent. Match Statements ---------------- In Python 3.10 or higher, you can write so called ``match`` statements like this: .. code:: python match something(): case [x] if x: z = 2 case _ as y if y == x and y: z = 1 case 0: z = 0 This is the same as .. code:: python tmp_match_subject = something() # Indicator variable, once true, all matching stops. tmp_handled = False # First branch x = tmp_match_subject if sequence_check(x) if x: z = 2 tmp_handled = True if tmp_handled is False: y = tmp_match_subject if x == y and y: z = 1 tmp_handled = True if tmp_handled is False: z = 0 Print Statements ---------------- The ``print`` statement exists only in Python2. It implicitly converts its arguments to strings before printing them. In order to make this accessible and compile time optimized, this is made visible in the node tree. .. code:: python print arg1, "1", 1 This is in Nuitka converted so that the code generation for ``print`` doesn't do any conversions itself anymore and relies on the string nature of its input. .. code:: python print str(arg1), "1", str(1) Only string objects are spared from the ``str`` built-in wrapper, because that would only cause noise in optimization stage. Later optimization can then find it unnecessary for certain arguments. Additionally, each ``print`` may have a target, and multiple arguments, which we break down as well for dumber code generation. The target is evaluated first and should be a file, kept referenced throughout the whole print statement. .. code:: python print >> target_file, str(arg1), "1", str(1) This is being reformulated to: .. code:: python try: tmp_target = target_file print >>tmp_target, str(arg1), print >>tmp_target, "1", print >>tmp_target, str(1), print >>tmp_target finally: del tmp_target This allows code generation to not deal with arbitrary amount of arguments to ``print``. It also separates the newline indicator from the rest of things, which makes sense too, having it as a special node, as it's behavior with regards to soft-space is different of course. And finally, for ``print`` without a target, we still assume that a target was given, which would be ``sys.stdout`` in a rather hard-coded way (no variable look-ups involved). Reformulations during Optimization ================================== Builtin ``zip`` for Python2 --------------------------- .. code:: python def _zip(a, b, c): # Potentially more arguments. # First assign, to preserve the order of execution, the arguments might be # complex expressions with side effects. tmp_arg1 = a tmp_arg2 = b tmp_arg3 = c # could be more ... # Creation of iterators goes first. try: tmp_iter_1 = iter(tmp_arg1) except TypeError: raise TypeError("zip argument #1 must support iteration") try: tmp_iter_2 = iter(tmp_arg2) except TypeError: raise TypeError("zip argument #2 must support iteration") try: tmp_iter_3 = iter(tmp_arg3) except TypeError: raise TypeError("zip argument #3 must support iteration") # could be more ... tmp_result = [] try: while 1: tmp_result.append( ( next(tmp_iter_1), next(tmp_iter_2), next(tmp_iter_3), # more arguments here ... ) ) except StopIteration: pass return tmp_result Builtin ``zip`` for Python3 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: python for x, y, z in zip(a, b, c): ... .. code:: python def _zip_gen_object(a, b, c, ...): ... # See Python2 ... # could be more ... while 1: yield ( next(tmp_iter_1), next(tmp_iter_2), next(tmp_iter_3), ... ) except StopIteration: break for x, y, z in _zip_gen_object(a, b, c): ... Builtin ``map`` for Python2 --------------------------- .. code:: python def _map(): # TODO: Not done yet. pass Builtin ``min`` --------------- .. code:: python # TODO: keyfunc (Python2/3), defaults (Python3) def _min(a, b, c): # Potentially more arguments. tmp_arg1 = a tmp_arg2 = b tmp_arg3 = c # more arguments here ... result = tmp_arg1 if keyfunc is None: # can be decided during re-formulation tmp_key_result = keyfunc(result) tmp_key_candidate = keyfunc(tmp_arg2) if tmp_key_candidate < tmp_key_result: result = tmp_arg2 tmp_key_result = tmp_key_candidate tmp_key_candidate = keyfunc(tmp_arg3) if tmp_key_candidate < tmp_key_result: result = tmp_arg3 tmp_key_result = tmp_key_candidate # more arguments here ... else: if tmp_arg2 < result: result = tmp_arg2 if tmp_arg3 < result: result = tmp_arg3 # more arguments here ... return result Builtin ``max`` --------------- See ``min`` just with ``>`` instead of ``<``. Call to ``dir`` without arguments --------------------------------- This expression is reformulated to ``locals().keys()`` for Python2, and ``list(locals.keys())`` for Python3. Calls to functions with known signatures ---------------------------------------- As a necessary step for inlining function calls, we need to change calls to variable references to function references. .. code:: python def f(arg1, arg2): return some_op(arg1, arg2) # ... other code x = f(a, b + c) In the optimization it is turned into .. code:: python # ... other code x = lambda arg1, arg2: some_op(arg1, arg2)(a, b + c) .. note:: The ``lambda`` stands here for a reference to the function, rather than a variable reference, this is the normal forward propagation of values, and does not imply duplicating or moving any code at all. At this point, we still have not resolved the actual call arguments to the variable names, still a Python level function is created, and called, and arguments are parsed to a tuple, and from a tuple. For simplicity sake, we have left out keyword arguments out of the equation for now, but they are even more costly. So now, what we want to do, is to re-formulate the call into what we call an outline body, which is a inline function, and that does the parameter parsing already and contains the function code too. In this inlining, there still is a function, but it's technically not a Python function anymore, just something that is an expression whose value is determined by control flow and the function call. .. code:: python # ... other code def _f(): tmp_arg1 = arg1 tmp_arg2 = b + c return tmp_arg1 + tmp_arg2 x = _f() With this, a function is considered inlined, because it becomes part of the abstract execution, and the actual code is duplicated. The point is, that matching the signature of the function to the actual arguments given, is pretty straight forward in many cases, but there are two forms of complications that can happen. One is default values, because they need to assigned or not, and the other is keyword arguments, because they allow to reorder arguments. Let's consider an example with default values first. .. code:: python def f(arg1, arg2=some_default()): return some_op(arg1, arg2) # ... other code x = f(a, b + c) Since the point, at which defaults are taken, we must execute them at that point and make them available. .. code:: python tmp_defaults = (some_default,) # that was f.__defaults__ # ... other code def _f(): tmp_arg1 = arg1 tmp_arg2 = tmp_defaults[0] return tmp_arg1 + tmp_arg2 x = _f() Now, one where keyword arguments are ordered the other way. .. code:: python def f(arg1, arg2): return some_op(arg1, arg2) # ... other code x = f(arg2=b + c, arg1=a) # "b+c" is evaluated before "a" The solution is an extra level of temporary variables. We remember the argument order by names and then assign parameters from it: .. code:: python # ... other code def _f(): tmp_given_value1 = b + c tmp_given_value2 = a tmp_arg1 = tmp_given_value2 tmp_arg2 = tmp_given_value1 return tmp_arg1 + tmp_arg2 x = _f() Obviously, optimization of Nuitka can decide, that e.g. should ``a`` or ``b+c`` not have side effects, to optimize these with standard variable tracing away. Nodes that serve special purposes ================================= Try statements -------------- In Python, there is ``try``/``except`` and ``try``/``finally``. In Nuitka there is only a ``try``, which then has blocks to handle exceptions, ``continue``, or ``break``, or ``return``. There is no ``else`` to this node type. This is more low level and universal. Code for the different handlers can be different. User provided ``finally`` blocks become copied into the different handlers. Releases -------- When a function exits, the local variables are to be released. The same applies to temporary variables used in re-formulations. These releases cause a reference to the object to the released, but no value change. They are typically the last use of the object in the function. The are similar to ``del``, but make no value change. For shared variables this effect is most visible. Side Effects ------------ When an exception is bound to occur, and this can be determined at compile time, Nuitka will not generate the code the leads to the exception, but directly just raise it. But not in all cases, this is the full thing. Consider this code: .. code:: python f(a(), 1 / 0) The second argument will create a ``ZeroDivisionError`` exception, but before that ``a()`` must be executed, but the call to ``f`` will never happen and no code is needed for that, but the name look-up must still succeed. This then leads to code that is internally like this: .. code:: python f(a(), raise_ZeroDivisionError()) which is then modeled as: .. code:: python side_effect(a(), f, raise_ZeroDivisionError()) where we can consider ``side_effect`` to be a function that returns the last expression. Of course, if this is not part of another expression, but close to statement level, side effects, can be converted to multiple statements simply. Another use case, is that the value of an expression can be predicted, but that the language still requires things to happen, consider this: .. code:: python a = len((f(), g())) We can tell that ``a`` will be 2, but the call to ``f`` and ``g`` must still be performed, so it becomes: .. code:: python a = side_effects(f(), g(), 2) Modelling side effects explicitly has the advantage of recognizing them easily and allowing to drop the call to the tuple building and checking its length, only to release it. Caught Exception Type/Value References -------------------------------------- When catching an exception, these are not directly put to ``sys.exc_info()``, but remain as mere C variables. From there, they can be accessed with these nodes, or if published then from the thread state. Hard Module Imports ------------------- These are module look-ups that don't depend on any local variable for the module to be looked up, but with hard-coded names. These may be the result of optimization gaining such level of certainty. Currently they are used to represent ``sys.stdout`` usage for ``print`` statements, but other usages will follow. Locals Dict Update Statement ---------------------------- For the ``exec`` re-formulation, we apply an explicit sync back to locals as an explicit node. It helps us to tell the affected local variable traces that they might be affected. It represents the bit of ``exec`` in Python2, that treats ``None`` as the locals argument as an indication to copy back. Optimizing Attribute Lookups into Method Calls for Built-ins types ================================================================== The attribute lookup node ``ExpressionAttributeLookup`` represents looking up an attribute name, that is known to be a string. That's already a bit more special, than say what ``ExpressionBuiltinGetattr`` does for ``getattr``, where it could be any object being looked up. From the Python syntax however, these are what gets created, as it's not allowed in any other way. So, this is where this starts. Then, when we are creating an attribute node with a *fixed* name, we dispatch it to generated node classes, e.g. ``ExpressionAttributeLookupFixedAppend``. This will be the same, except that the attribute name is hardcoded. There are generated, such that they can have code that is special for ``.append`` lookups. In their case, it makes sense to ask the source, if they are a ``list`` object exactly. It doesn't make sense to do this check for names that the ``list`` does not contain. So at that stage, we are saving both a bit of memory and time. Should this question succeed, i.e. the expression the attribute values is looked up upon, is known to be a ``list`` exactly, we persist this knowledge in the also generated nodes that represent ``list.append`` and just that. It is called ``ExpressionAttributeLookupListAppend`` and only represents the knowledge gained so far. We do not consider if ``ExpressionAttributeLookupFixedAppend`` is called, or not, passed as an argument, assigned somewhere, it doesn't matter yet, but for ``ExpressionAttributeLookupListAppend`` we know a hell of a lot more. We know its type, we know attributes for it, say ``__name__``, as it is a compile time constant, therefore much optimization can follow for them, and code generation can specialize them too (not yet done). Should these nodes then, and say this happens later after some inlining happens be seen as called, we can then turn them into method call nodes, checking the arguments and such, this is then ``ExpressionListOperationAppend`` and at this point, will raising errors with wrong argument counts. And then we have this ``ExpressionListOperationAppend`` which will influence the tracing of ``list`` contents, i.e. it will be able to tell the ``list`` in question is no more empty after this ``append``, and it will be able to at least predict the last element value, truth value of the list, etc. ****************************** Plan to add "ctypes" support ****************************** Add interfacing to C code, so Nuitka can turn a ``ctypes`` binding into an efficient binding as if it were written manually with Python C-API or better. Goals/Allowances to the task ============================ #. Goal: Must not directly use any pre-existing C/C++ language file headers, only generate declarations in generated C code ourselves. We would rather write or use tools that turn an existing a C header to some ``ctypes`` declarations if it needs to be, but not mix and use declarations from existing header code. .. note:: The "cffi" interface maybe won't have the issue, but it's not something we need to write or test the code for. #. Allowance: May use ``ctypes`` module at compile time to ask things about ``ctypes`` and its types. #. Goal: Should make use of ``ctypes``, to e.g. not hard code in Nuitka what ``ctypes.c_int()`` gives on the current platform, unless there is a specific benefit. #. Allowance: Not all ``ctypes`` usages must be supported immediately. #. Goal: Try and be as general as possible. For the compiler, ``ctypes`` support should be hidden behind a generic interface of some sort. Supporting ``math`` module should be the same thing. Type Inference - The Discussion =============================== Main initial goal is to forward value knowledge. When you have ``a = b``, that means that a and b now "alias". And if you know the value of ``b`` you can assume to know the value of ``a``. This is called "aliasing". When assigning ``a`` to something new, that won't change ``b`` at all. But when an attribute is set, a method called of it, that might impact the actual value, referenced by both. We need to understand mutable vs. immutable though, as some things are not affected by aliasing in any way. .. code:: python a = 3 b = a b += 4 # a is not changed a = [3] b = a b += [4] # a is changed indeed If we cannot tell, we must assume that ``a`` might be changed. It's either ``b`` or what ``a`` was before. If the type is not mutable, we can assume the aliasing to be broken up, and if it is, we can assume both to be the same value still. When that value is a compile time constant, we will want to push it forward, and we do that with "(Constant) Value Propagation", which is implemented already. We avoid too large constants, and we properly trace value assignments, but not yet aliases. In order to fully benefit from type knowledge, the new type system must be able to be fully friends with existing built-in types, but for classes to also work with it, it should not be tied to them. The behavior of a type ``long``, ``str``, etc. ought to be implemented as far as possible with the built-in ``long``, ``str`` at compiled time as well. .. note:: This "use the real thing" concept extends beyond builtin types, e.g. ``ctypes.c_int()`` should also be used, but we must be aware of platform dependencies. The maximum size of ``ctypes.c_int`` values would be an example of that. Of course that may not be possible for everything. This approach has well proven itself with built-in functions already, where we use real built-ins where possible to make computations. We have the problem though that built-ins may have problems to execute everything with reasonable compile time cost. Another example, consider the following code: .. code:: python len("a" * 1000000000000) To predict this code, calculating it at compile time using constant operations, while feasible, puts an unacceptable burden on the compilation. Esp. we wouldn't want to produce such a huge constant and stream it, the C++ code would become too huge. So, we need to stop the ``*`` operator from being used at compile time and cope with reduced knowledge, already here: .. code:: python "a" * 10000000000000 Instead, we would probably say that for this expression: - The result is a ``str`` or a C level ``PyStringObject *``. - We know its length exactly, it's ``10000000000000``. - Can predict every of its elements when sub-scripted, sliced, etc., if need be, with a function we may create. Similar is true for this horrible (in Python2) thing: .. code:: python range(10000000000000) So it's a rather general problem, this time we know: - The result is a ``list`` or C level ``PyListObject *``. - We know its length exactly, ``10000000000000``. - Can predict every of its elements when index, sliced, etc., if need be, with a function. Again, we wouldn't want to create the list. Therefore Nuitka avoids executing these calculation, when they result in constants larger than a threshold of e.g. 256 elements. This concept has to be also applied to large integers and more CPU and memory traps. Now lets look at a more complete use case: .. code:: python for x in range(10000000000000): doSomething() Looking at this example, one traditional way to look at it, would be to turn ``range`` into ``xrange``, and to note that ``x`` is unused. That would already perform better. But really better is to notice that ``range()`` generated values are not used at all, but only the length of the expression matters. And even if ``x`` were used, only the ability to predict the value from a function would be interesting, so we would use that computation function instead of having an iteration source. Being able to predict from a function could mean to have Python code to do it, as well as C code to do it. Then code for the loop can be generated without any CPython library usage at all. .. note:: Of course, it would only make sense where such calculations are "O(1)" complexity, i.e. do not require recursion like "n!" does. The other thing is that CPython appears to at - run time - take length hints from objects for some operations, and there it would help too, to track length of objects, and provide it, to outside code. Back to the original example: .. code:: python len("a" * 1000000000000) The theme here, is that when we can't compute all intermediate expressions, and we sure can't do it in the general case. But we can still, predict some of properties of an expression result, more or less. Here we have ``len`` to look at an argument that we know the size of. Great. We need to ask if there are any side effects, and if there are, we need to maintain them of course. This is already done by existing optimization if an operation generates an exception. .. note:: The optimization of ``len`` has been implemented and works for all kinds of container creation and ranges. Applying this to "ctypes" ========================= The *not so specific* problem to be solved to understand ``ctypes`` declarations is maybe as follows: .. code:: python import ctypes This leads to Nuitka in its tree to have an assignment from a ``__import__`` expression to the variable ``ctypes``. It can be predicted by default to be a module object, and even better, it can be known as ``ctypes`` from standard library with more or less certainty. See the section about "Importing". So that part is "easy", and it's what will happen. During optimization, when the module ``__import__`` expression is examined, it should say: - ``ctypes`` is a module - ``ctypes`` is from standard library (if it is, might not be true) - ``ctypes`` then has code behind it, called ``ModuleFriend`` that knows things about it attributes, that should be asked. The later is the generic interface, and the optimization should connect the two, of course via package and module full names. It will need a ``ModuleFriendRegistry``, from which it can be pulled. It would be nice if we can avoid ``ctypes`` to be loaded into Nuitka unless necessary, so these need to be more like a plug-in, loaded only if necessary, i.e. the user code actually uses ``ctypes``. Coming back to the original expression, it also contains an assignment expression, because it re-formulated to be more like this: .. code:: python ctypes = __import__("ctypes") The assigned to object, simply gets the type inferred propagated as part of an SSA form. Ideally, we could be sure that nothing in the program changes the variable, and therefore have only one version of that variable. For module variables, when the execution leaves the module to unknown code, or unclear code, it might change the variable. Therefore, likely we will often only assume that it could still be ``ctypes``, but also something else. Depending on how well we control module variable assignment, we can decide this more of less quickly. With "compiled modules" types, the expectation is that it's merely a quick C ``==`` comparison check. The module friend should offer code to allow a check if it applies, for uncertain cases. Then when we come to uses of it: .. code:: python ctypes.c_int() At this point, using SSA, we are more of less sure, that ``ctypes`` is at that point the module, and that we know what it's ``c_int`` attribute is, at compile time, and what it's call result is. We will use the module friend to help with that. It will attach knowledge about the result of that expression during the SSA collection process. This is more like a value forward propagation than anything else. In fact, constant propagation should only be the special case of it, and one design goal of Nuitka was always to cover these two cases with the same code. Excursion to Functions ====================== In order to decide what this means to functions and their call boundaries, if we propagate forward, how to handle this: .. code:: python def my_append(a, b): a.append(b) return a We annotate that ``a`` is first a "unknown but defined parameter object", then later on something that definitely has an ``append`` attribute, when returned, as otherwise an exception occurs. The type of ``a`` changes to that after ``a.append`` look-up succeeds. It might be many kinds of an object, but e.g. it could have a higher probability of being a ``PyListObject``. And we would know it cannot be a ``PyStringObject``, as that one has no ``append`` method, and would have raised an exception therefore. .. note:: If classes, i.e. other types in the program, have an ``append`` attribute, it should play a role too, there needs to be a way to plug-in to this decisions. .. note:: On the other hand, types without ``append`` attribute can be eliminated. Therefore, functions through SSA provide an automatic analysis on their return state, or return value types, or a quick way to predict return value properties, based on input value knowledge. So this could work: .. code:: python b = my_append([], 3) assert b == [3] # Could be decided now Goal: The structure we use makes it easy to tell what ``my_append`` may be. So, there should be a means to ask it about call results with given type/value information. We need to be able to tell, if evaluating ``my_append`` makes sense with given parameters or not, if it does impact the return value. We should e.g. be able to make ``my_append`` tell, one or more of these: - Returns the first parameter value as return value (unless it raises an exception). - The return value has the same type as ``a`` (unless it raises an exception). - The return value has an ``append`` attribute. - The return value might be a ``list`` object. - The return value may not be a ``str`` object. - The function will raise if first argument has no ``append`` attribute. The exactness of statements may vary. But some things may be more interesting. If e.g. the aliasing of a parameter value to the return value is known exactly, then information about it need to all be given up, but some can survive. It would be nice, if ``my_append`` had sufficient information, so we could specialize with ``list`` and ``int`` from the parameters, and then e.g. know at least some things that it does in that case. Such specialization would have to be decided if it makes sense. In the alternative, it could be done for each variant anyway, as there won't be that many of them. Doing this "forward" analysis appears to be best suited for functions and therefore long term. We will try it that way. Excursion to Loops ================== .. code:: python a = 1 while 1: # think loop: here b = a + 1 a = b if cond(): break print(a) The handling of loops (both ``for`` and ``while`` are re-formulated to this kind of loops with ``break`` statements) has its own problem. The loop start and may have an assumption from before it started, that ``a`` is constant, but that is only true for the first iteration. So, we can't pass knowledge from outside loop forward directly into the for loop body. So the collection for loops needs to be two pass for loops. First, to collect assignments, and merge these into the start state, before entering the loop body. The need to make two passes is special to loops. For a start, it is done like this. At loop entry, all pre-existing, but written traces, are turned into loop merges. Knowledge is not completely removed about everything assigned or changed in the loop, but then it's not trusted anymore. From that basis, the ``break`` exits are analysed, and merged, building up the post loop state, and ``continue`` exits of the loop replacing the unknown part of the loop entry state. The loop end is considered a ``continue`` for this purpose. Excursion to Conditions ======================= .. code:: python if cond: x = 1 else: x = 2 b = x < 3 The above code contains a condition, and these have the problem, that when exiting the conditional block, a merge must be done, of the ``x`` versions. It could be either one. The merge may trace the condition under which a choice is taken. That way, we could decide pairs of traces under the same condition. These merges of SSA variable "versions", represent alternative values. They pose difficulties, and might have to be reduced to commonality. In the above example, the ``<`` operator will have to check for each version, and then to decide that both indeed give the same result. The trace collection tracks variable changes in conditional branches, and then merges the existing state at conditional statement exits. .. note:: A branch is considered "exiting" if it is not abortive. Should it end in a ``raise``, ``break``, ``continue``, or ``return``, there is no need to merge that branch, as execution of that branch is terminated. Should both branches be abortive, that makes things really simple, as there is no need to even continue. Should only one branch exist, but be abortive, then no merge is needed, and the collection can assume after the conditional statement, that the branch was not taken, and continue. When exiting both the branches, these branches must both be merged, with their new information. In the above case: - The "yes" branch knows variable ``x`` is an ``int`` of constant value ``1`` - The "no" branch knows variable ``x`` is an ``int`` of constant value ``2`` That might be collapsed to: - The variable ``x`` is an integer of value in ``(1,2)`` Given this, we then should be able to pre-compute the value of this: .. code:: python b = x < 3 The comparison operator can therefore decide and tell: - The variable ``b`` is a boolean of constant value ``True``. Were it unable to decide, it would still be able to say: - The variable ``b`` is a boolean. For conditional statements optimization, it's also noteworthy, that the condition is known to pass or not pass the truth check, inside branches, and in the case of non-exiting single branches, after the statement it's not true. We may want to take advantage of it. Consider e.g. .. code:: python if type(a) is list: a.append(x) else: a += (x,) In this case, the knowledge that ``a`` is a list, could be used to generate better code and with the definite knowledge that ``a`` is of type list. With that knowledge the ``append`` attribute call will become the ``list`` built-in type operation. Excursion to ``return`` statements ================================== The ``return`` statement (like ``break``, ``continue``, ``raise``) is "aborting" to control flow. It is always the last statement of inspected block. When there statements to follow it, optimization will remove it as "dead code". If all branches of a conditional statement are "aborting", the statement is decided "aborting" too. If a loop doesn't abort with a break, it should be considered "aborting" too. Excursion to ``yield`` expressions ================================== The ``yield`` expression can be treated like a normal function call, and as such invalidates some known constraints just as much as they do. It executes outside code for an unknown amount of time, and then returns, with little about the outside world known anymore, if it's accessible from there. Mixed Types =========== Consider the following inside a function or module: .. code:: python if cond is not None: a = [x for x in something() if cond(x)] else: a = () A programmer will often not make a difference between ``list`` and ``tuple``. In fact, using a ``tuple`` is a good way to express that something won't be changed later, as these are mutable. .. note:: Better programming style, would be to use this: .. code:: python if cond is not None: a = tuple(x for x in something() if cond(x)) else: a = () People don't do it, because they dislike the performance hit encountered by the generator expression being used to initialize the tuple. But it would be more consistent, and so Nuitka is using it, and of course one day Nuitka ought to be able to make no difference in performance for it. To Nuitka though this means, that if ``cond`` is not predictable, after the conditional statement we may either have a ``tuple`` or a ``list`` type object in ``a``. In order to represent that without resorting to "I know nothing about it", we need a kind of ``min``/``max`` operating mechanism that is capable of say what is common with multiple alternative values. .. note:: At this time, we don't really have that mechanism to find the commonality between values. Back to "ctypes" ================ .. code:: python v = ctypes.c_int() Coming back to this example, we needed to propagate ``ctypes``, then we can propagate "something" from ``ctypes.int`` and then known what this gives with a call and no arguments, so the walk of the nodes, and diverse operations should be addressed by a module friend. In case a module friend doesn't know what to do, it needs to say so by default. This should be enforced by a base class and give a warning or note. Now to the interface ==================== The following is the intended interface: - Iteration with node methods ``computeStatement`` and ``computeExpression``. These traverse modules and functions (i.e. scopes) and visit everything in the order that Python executes it. The visiting object is ``TraceCollection`` and pass forward. Some node types, e.g. ``StatementConditional`` new create branch trace collections and handle the SSA merging at exit. - Replacing nodes during the visit. Both ``computeStatement`` and ``computeExpression`` are tasked to return potential replacements of themselves, together with "tags" (meaningless now), and a "message", used for verbose tracing. The replacement node of ``+`` operator, may e.g. be the pre-computed constant result, wrapped in side effects of the node, or the expression raised, again wrapped in side effects. - Assignments and references affect SSA. The SSA tree is initialized every time a scope is visited. Then during traversal, traces are built up. Every assignment and merge starts a new trace for that matter. References to a given variable version are traced that way. - Value escapes are traced too. When an operation hands over a value to outside code, it indicates so to the trace collection. This is for it to know, when e.g. a constant value, might be mutated meanwhile. - Nodes can be queried about their properties. There is a type shape and a value shape that each node can be asked about. The type shape offers methods that allow to check if certain operations are at all supported or not. These can always return ``True`` (yes), ``False`` (no), and ``None`` (cannot decide). In the case of the later, optimizations may not be able do much about it. Lets call these values "tri-state". There is also the value shape of a node. This can go deeper, and be more specific to a given node. The default implementation will be very pessimistic. Specific node types and shapes may then declare, that they e.g. have no side effects, will not raise for certain operations, have a known truth value, have a known iteration length, can predict their iteration values, etc. - Nodes are linked to certain states. During the collect, a variable reference, is linked to a certain trace state, and that can be used by parent operations. .. code:: python a = 1 b = a + a In this example, the references to ``a``, can look-up the ``1`` in the trace, and base value shape response to ``+`` on it. For compile time evaluation, it may also ask ``isCompileTimeConstant()`` and if both nodes will respond ``True``, then "getCompileTimeConstant()" will return ``1``, which will be be used in computation. Then ``extractSideEffects()`` for the ``a`` reference will return ``()`` and therefore, the result ``2`` will not be wrapped. An alternative approach would be ``hasTypeSlotAdd()`` on the both nodes, and they both do, to see if the selection mechanism used by CPython can be used to find which types ``+`` should be used. - Class for module import expression ``ExpressionImportModule``. This one just knows that something is imported, but not how or what it is assigned to. It will be able in a recursive compile, to provide the module as an assignment source, or the module variables or submodules as an attribute source when referenced from a variable trace or in an expression. - Base class for module friend ``ModuleFriendBase``. This is intended to provide something to overload, which e.g. can handle ``math`` in a better way. - Module ``ModuleFriendRegistry`` Provides a register function with ``name`` and instances of ``ValueFriendModuleBase`` to be registered. Recursed to modules should integrate with that too. The registry could well be done with a metaclass approach. - The module friends should each live in a module of their own. With a naming policy to be determined. These modules should add themselves via above mechanism to ``ModuleFriendRegistry`` and all shall be imported and register. Importing of e.g. ``ctypes`` should be delayed to when the friend is actually used. A meta class should aid this task. The delay will avoid unnecessary blot of the compiler at run time, if no such module is used. For "qt" and other complex stuff, this will be a must. - The walk should initially be single pass, and not maintain history. Instead optimization that needs to look at multiple things, e.g. "unused assignment", will look at the whole SSA collection afterwards. Discussing with examples ======================== The following examples: .. code:: python # Assignment, the source decides the type of the assigned expression a = b # Operator "attribute look-up", the looked up expression "ctypes" decides # via its trace. ctypes.c_int # Call operator, the called expressions decides with help of arguments, # which have been walked, before the call itself. called_expression_of_any_complexity() # import gives a module any case, and the "ModuleRegistry" may say more. import ctypes # From import need not give module, "x" decides what it is. from x import y # Operations are decided by arguments, and CPython operator rules between # argument states. a + b The optimization is mostly performed by walking of the tree and performing trace collection. When it encounters assignments and references to them, it considers current state of traces and uses it for ``computeExpression``. .. note:: Assignments to attributes, indexes, slices, etc. will also need to follow the flow of ``append``, so it cannot escape attention that a list may be modified. Usages of ``append`` that we cannot be sure about, must be traced to exist, and disallow the list to be considered known value again. Code Generation Impact ====================== Right now, code generation assumes that everything is a ``PyObject *``, i.e. a Python object, and does not take knowledge of ``int`` or other types into consideration at all, and it should remain like that for some time to come. Instead, ``ctypes`` value friend will be asked give ``Identifiers``, like other codes do too. And these need to be able to convert themselves to objects to work with the other things. But Code Generation should no longer require that operations must be performed on that level. Imagine e.g. the following calls: .. code:: python c_call(other_c_call()) Value returned by "other_c_call()" of say ``c_int`` type, should be possible to be fed directly into another call. That should be easy by having a ``asIntC()`` in the identifier classes, which the ``ctypes`` Identifiers handle without conversions. Code Generation should one day also become able to tell that all uses of a variable have only ``c_int`` value, and use ``int`` instead of ``PyObjectLocalVariable`` more or less directly. We could consider ``PyIntLocalVariable`` of similar complexity as ``int`` after the C++ compiler performed its in-lining. Such decisions would be prepared by finalization, which then would track the history of values throughout a function or part of it. Initial Implementation ====================== The basic interface will be added to *all* expressions and a node may override it, potentially using trace collection state, as attached during ``computeExpression``. Goal 1 (Reached) ---------------- Initially most things will only be able to give up on about anything. And it will be little more than a tool to do simple look-ups in a general form. It will then be the first goal to turn the following code into better performing one: .. code:: python a = 3 b = 7 c = a / b print(c) to: .. code:: python a = 3 b = 7 c = 3 / 7 print(c) and then: .. code:: python a = 3 b = 7 c = 0 print(c) and then: .. code:: python a = 3 b = 7 c = 0 print(0) This depends on SSA form to be able to tell us the values of ``a``, ``b``, and ``c`` to be written to by constants, which can be forward propagated at no cost. Goal 2 (Reached) ---------------- The assignments to ``a``, ``b``, and ``c`` shall all become prey to "unused" assignment analysis in the next step. They are all only assigned to, and the assignment source has no effect, so they can be simply dropped. .. code:: python print(0) In the SSA form, these are then assignments without references. These assignments, can be removed if the assignment source has no side effect. Or at least they could be made "anonymous", i.e. use a temporary variable instead of the named one. That would have to take into account though, that the old version still needs a release. The most general form would first merely remove assignments that have no impact, and leave the value as a side effect, so we arrive at this first: .. code:: python 3 7 0 print(0) When applying the removal of expression only statements without effect, this gives us: .. code:: python print(0) which is the perfect result. Doing it in one step would only be an optimization at the cost of generalization. In order to be able to manipulate nodes related to a variable trace, we need to attach the nodes that did it. Consider this: .. code:: python if cond(): x = 1 elif other(): x = 3 # Not using "x". print(0) In the above case, the merge of the value traces, should say that ``x`` may be undefined, or one of ``1`` or ``3``, but since ``x`` is not used, apply the "dead value" trick to each branch. The removal of the "merge" of the 3 ``x`` versions, should exhibit that the other versions are also only assigned to, and can be removed. These merges of course appear as usages of the ``x`` versions. Goal 3 ------ Then third goal is to understand all of this: .. code:: python def f(): a = [] print(a) for i in range(1000): print(a) a.append(i) return len(a) .. note:: There are many operations in this, and all of them should be properly handled, or at least ignored in safe way. The first goal code gave us that the ``list`` has an annotation from the assignment of ``[]`` and that it will be copied to ``a`` until the for loop in encountered. Then it must be removed, because the ``for`` loop somehow says so. The ``a`` may change its value, due to the unknown attribute look-up of it already, not even the call. The for loop must be able to say "may change value" due to that, of course also due to the call of that attribute too. The code should therefore become equivalent to: .. code:: python def f(): a = [] print([]) for i in range(1000): print(a) a.append(i) return len(a) But no other changes must occur, especially not to the ``return`` statement, it must not assume ``a`` to be constant "[]" but an unknown ``a`` instead. With that, we would handle this code correctly and have some form constant value propagation in place, handle loops at least correctly, and while it is not much, it is important demonstration of the concept. Goal 4 ------ The fourth goal is to understand the following: .. code:: python def f(cond): y = 3 if cond: x = 1 else: x = 2 return x < y In this we have a branch, and we will be required to keep track of both the branches separately, and then to merge with the original knowledge. After the conditional statement we will know that "x" is an "int" with possible values in ``(1,2)``, which can be used to predict that the return value is always ``True``. The fourth goal will therefore be that the "ValueFriendConstantList" knows that append changes ``a`` value, but it remains a list, and that the size increases by one. It should provide an other value friend "ValueFriendList" for "a" due to that. In order to do that, such code must be considered: .. code:: python a = [] a.append(1) a.append(2) print(len(a)) It will be good, if ``len`` still knows that ``a`` is a list object, but not the constant list anymore. From here, work should be done to demonstrate the correctness of it with the basic tests applied to discover undetected issues. Fifth and optional goal: Extra bonus points for being able to track and predict ``append`` to update the constant list in a known way. Using ``list.append`` that should be done and lead to a constant result of ``len`` being used. The sixth and challenging goal will be to make the code generation be impacted by the value friends types. It should have a knowledge that ``PyList_Append`` does the job of append and use ``PyList_Size`` for ``len``. The "ValueFriends" should aid the code generation too. Last and right now optional goal will be to make ``range`` have a value friend, that can interact with iteration of the for loop, and ``append`` of the ``list`` value friend, so it knows it's possible to iterate 5000 times, and that "a" has then after the "loop" this size, so ``len(a)`` could be predicted. For during the loop, about a the range of its length should be known to be less than 5000. That would make the code of goal 2 completely analyzed at compile time. Limitations for now =================== - Aim only for limited examples. For ``ctypes`` that means to compile time evaluate: .. code:: python print(ctypes.c_int(17) + ctypes.c_long(19)) Later then call to "libc" or something else universally available, e.g. "strlen()" or "strcmp()" from full blown declarations of the callable. - We won't have the ability to test that optimization are actually performed, we will check the generated code by hand. With time, we will add XML based checks with "xpath" queries, expressed as hints, but that is some work that will be based on this work here. The "hints" fits into the "ValueFriends" concept nicely or so the hope is. - No inter-function optimization functions yet Of course, once in place, it will make the ``ctypes`` annotation even more usable. Using ``ctypes`` objects inside functions, while creating them on the module level, is therefore not immediately going to work. - No loops yet Loops break value propagation. For the ``ctypes`` use case, this won't be much of a difficulty. Due to the strangeness of the task, it should be tackled later on at a higher priority. - Not too much. Try and get simple things to work now. We shall see, what kinds of constraints really make the most sense. Understanding ``list`` subscript/slice values e.g. is not strictly useful for much code and should not block us. .. note:: This design is not likely to be the final one. *********************************** How to make Features Experimental *********************************** Every experimental feature needs a name. We have a rule to pick a name with lower case and ``_`` as separators. An example of with would be the name ``jinja_generated_add`` that has been used in the past. Command Line ============ Experimental features are enabled with the command line argument .. code:: bash nuitka --experimental=jinja_generated_add ... In C code ========= In Scons, all experimental features automatically are converted into C defines, and can be used like this: .. code:: C #ifdef _NUITKA_EXPERIMENTAL_JINJA_GENERATED_ADD #include "HelpersOperationGeneratedBinaryAdd.c" #else #include "HelpersOperationBinaryAdd.c" #endif The C pre-processor is the only thing that makes an experimental feature usable. In Python ========= You can query experimental features using ``Options.isExperimental()`` with e.g. code like this: .. code:: python if Options.isExperimental("use_feature"): experimental_code() else: standard_code() When to use it ============== Often we need to keep feature in parallel because they are not finished, or need to be tested after merge and should not break. Then we can do code changes that will not make a difference except when the experimental flag is given on the command line to Nuitka. The testing of Nuitka is very heavy weight when e.g. all Python code is compiled, and very often, it is interesting to compare behavior with and without a change. When to remove it ================= When a feature becomes default, we might choose to keep the old variant around, but normally we do not. Then we remove the ``if`` and ``#if`` checks and drop the old code. At this time, large scale testing will have demonstrated the viability of the code. ******************************* Adding dependencies to Nuitka ******************************* First of all, there is an important distinction to make, run time or development time. The first kind of dependency is used when Nuitka is executing. Adding a Run Time Dependency ============================ This is the kind of dependency that is the most scrutinized. As we want Nuitka to run on latest greatest Python as well as relatively old ones, we have to be very careful with these ones. There is also a distinction of optional dependencies. Right now e.g. the ``lxml`` package is relatively optional, and Nuitka can work without it being installed, because e.g. on some platforms it will not be easy to do so. That bar has lifted somewhat, but it means e.g. that XML based optimization tests are not run with all Python versions. The list of run time dependencies is in ``requirements.txt`` and it is for those the case, that they are not really required to be installed by the user, consider this snippet: .. code:: python # Folders to use for cache files. appdirs # Scons is the backend building tool to turn C files to binaries. scons For both these dependencies, there is either an inline copy (Scons) that we handle to use in case, if Scons is not available (in fact we have a version that works with Python 2.6 and 2.7 still), and also the same for appdirs and every dependency. But since inline copies are against the rules on some platforms that still do not contain the package, we often even have our own wrapper which provides a minimal fallback or exposes a sane interface for the subset of functionality that we use. .. note:: Therefore, please if you consider adding one of these, get in touch with ``@Nuitka-pushers`` first and get a green light. Adding a Development Dependency =============================== A typical example of a development dependency is ``black`` which is used by our autoformat tool, and then in turn by the git pre-commit hook. It is used to format source code, and doesn't have a role at run time of the actual compiler code of Nuitka. Much less strict rules apply to these in comparison to runtime dependencies. Generally please take care that the tool must be well maintained an available on newer Pythons. Then we can use it, no problem normally. But if it's really big, say all of SciPy, we might want to justify it a bit better. The list of development dependencies is in ``requirements-devel.txt`` and it is for example like this: .. code:: python # Autoformat needs this rstfmt == 0.0.10 ; python_version >= '3.7' We always add the version, so that when tests run on as old versions as Python 2.6, the installation would fail with that version, so we need to make a version requirement. Sometimes we use older versions for Python2 than for Python3, ``Jinaj2`` being a notable candidate, but generally we ought to avoid that. For many tools only being available for currently 3.7 or higher is good enough, esp. if they are run as development tools, like ``autoformat-nuitka-source`` is. ********** Idea Bin ********** This an area where to drop random ideas on our minds, to later sort it out, and out it into action, which could be code changes, plan changes, issues created, etc. - Make "SELECT_METACLASS" meta class selection transparent. Looking at the "SELECT_METACLASS" it should become an anonymous helper function. In that way, the optimization process can remove choices at compile time, and e.g. in-line the effect of a meta class, if it is known. This of course makes most sense, if we have the optimizations in place that will allow this to actually happen. - Keeping track of iterations The trace collection trace should become the place, where variables or values track their use state. The iterator should keep track of the "next()" calls made to it, so it can tell which value to given in that case. That would solve the "iteration of constants" as a side effect and it would allow to tell that they can be removed. That would mean to go back in the tree and modify it long after. .. code:: python a = iter((2, 3)) b = next(a) c = next(a) del a It would be sweet if we could recognize that as: .. code:: python a = iter((2, 3)) b = side_effect(next(a), 2) c = side_effect(next(a), 3) del a That trivially becomes: .. code:: python a = iter((2, 3)) next(a) b = 2 next(a) c = 3 del a When the ``del a`` is examined at the end of scope, or due to another assignment to the same variable, ending the trace, we would have to consider of the ``next`` uses, and retrofit the information that they had no effect. .. code:: python a = iter((2, 3)) b = 2 b = 3 del a - Aliasing Each time an assignment is made, an alias is created. A value may have different names. .. code:: python a = iter(range(9)) b = a c = next(b) d = next(a) If we fail to detect the aliasing nature, we will calculate ``d`` wrongly. We may incref and decref values to trace it. Aliasing is automatically traced already in SSA form. The ``b`` is assigned to version of ``a``. So, that should allow to replace it with this: .. code:: python a = iter(range(9)) c = next(a) d = next(a) Which then will be properly handled. - Tail recursion optimization. Functions that return the results of calls, can be optimized. The Stackless Python does it already. - Integrate with "upx" compression. Calling "upx" on the created binaries, would be easy. - In-lining constant "exec" and "eval". It should be possible to re-formulate at least cases without "locals" or "globals" given. .. code:: python def f(): a = 1 b = 2 exec("""a+=b;c=1""") return a, c Should become this here: .. code:: python def f(): a = 1 b = 2 a += b # c = 1 # MaybeLocalVariables for everything except known local ones. return a, c If this holds up, inlining ``exec`` should be relatively easy. - Original and overloaded built-ins This is about making things visible in the node tree. In Nuitka things that are not visible in the node tree tend to be wrong. We already pushed around information to the node tree a lot. Later versions, Nuitka will become able to determine it has to be the original built-in at compile time, then a condition that checks will be optimized away, together with the slow path. Or the other path, if it won't be. Then it will be optimized away, or if doubt exists, it will be correct. That is the goal. Right now, the change would mean to effectively disable all built-in call optimization, which is why we don't immediately do it. Making the compatible version, will also require a full listing of all built-ins, which is typing work merely, but not needed now. And a way to stop built-in optimization from optimizing built-in calls that it used in a wrap. Probably just some flag to indicate it when it visits it to skip it. That's for later. But should we have that both, I figure, we could not raise a ``RuntimeError`` error, but just do the correct thing, in all cases. An earlier step may raise ``RuntimeError`` error, when built-in module values are written to, that we don't support. ****************** Prongs of Action ****************** In this chapter, we keep track of prongs of action currently ongoing. This can get detailed and shows things we strive for. Builtin optimization ==================== Definitely want to get built-in names under full control, so that variable references to module variables do not have a twofold role. Currently they reference the module variable and also the potential built-in as a fallback. In terms of generated code size and complexity for modules with many variables and uses of them that is horrible. But ``some_var`` (normally) cannot be a built-in and therefore needs no code to check for that each time. This is also critical to getting to whole program optimization. Being certain what is what there on module level, will enable more definitely knowledge about data flows and module interfaces. Class Creation Overhead Reduction ================================= This is more of a meta goal. Some work for the metaclass has already been done, but that is Python2 only currently. Being able to to decide built-ins and to distinguish between global only variables, and built-ins more clearly will help this a lot. In the end, empty classes should be able to be statically converted to calls to ``type`` with static dictionaries. The inlining of class creation function is also needed for this, but on Python3 cannot happen yet. Memory Usage at Compile Time ============================ We will need to store more and more information in the future. Getting the tree to be tight shaped is therefore an effort, where we will be spending time too. The mix-ins prevent slots usage, so lets try and get rid of those. The "children having" should become more simple and faster code. I am even thinking of even generating code in the meta class, so it's both optimal and doesn't need that mix-in any more. This is going to be ugly then. Coverage Testing ================ And then there is coverage, it should be taken and merged from all Python versions and OSes, but I never managed to merge between Windows and Linux for unknown reasons. Python3 Performance =================== The Python3 lock for thread state is making it slower by a lot. I have only experimental code that just ignores the lock, but it likely only works on Linux, and I wonder why there is that lock in the first place. Ignoring the locks cannot be good. But what updates that thread state pointer ever without a thread change, and is this what ABI flags are about in this context, are there some that allow us to ignore the locks. An important bit would be to use a thread state once acquired for as much as possible, currently exception helpers do not accept it as an argument, but that ought to become an option, that way saving and restoring an exception will be much faster, not to mention checking and dropping non interesting, or rewriting exceptions. Caching of Python level compilation =================================== While the C compilation result is already cached with `ccache` and friends now, we need to also cover our bases and save the resulting node tree of potential expensive optimization on the module level. ************************* Updates for this Manual ************************* This document is written in REST. That is an ASCII format which is readable to human, but easily used to generate PDF or HTML documents. You will find the current source under: https://github.com/Nuitka/Nuitka/blob/develop/Developer_Manual.rst And the current PDF under: https://nuitka.net/doc/Developer_Manual.pdf ================================================ FILE: LICENSE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright © 2010-2019 Kay Hayen Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: MANIFEST.in ================================================ # Spell checking makes no sense, spell-checker: disable include LICENSE.txt include MANIFEST.in include README.rst include Changelog.rst include Developer_Manual.rst include doc/nuitka.1 include doc/nuitka-run.1 include bin/compare_with_cpython include bin/compare_with_xml include bin/check-nuitka-with-pylint include bin/autoformat-nuitka-source include bin/measure-construct-performance # Runners, mainly for source distribution. include bin/nuitka include bin/nuitka-run include misc/*.bat include tests/run-tests include nuitka/plugins/standard/*.yml # Logo with source include doc/Logo/Nuitka-Logo-Symbol.svg include doc/Logo/Nuitka-Logo-Vertical.svg include doc/Logo/Nuitka-Logo-Horizontal.svg include doc/images/Nuitka-Logo-Symbol.png include doc/images/Nuitka-Logo-Vertical.png include doc/images/Nuitka-Logo-Horizontal.png recursive-include lib *.py # Core tests are included along with Nuitka itself. recursive-include tests/basics *.py recursive-include tests/syntax *.py recursive-include tests/packages *.py recursive-include tests/programs *.py include tests/programs/pkgutil_usage/package/DATA_FILE*.txt include tests/programs/resource_reader37/some_package/DATA_FILE*.txt recursive-include tests/optimizations *.py recursive-include tests/standalone *.py recursive-include tests/onefile *.py recursive-include tests/reflected *.py recursive-include tests/plugins *.py recursive-include tests/plugins *.yml include tests/plugins/data_files/data_files_package/*.txt include tests/plugins/data_files/data_files_package/sub_dir/*.txt # C templates for code generation. recursive-include nuitka/code_generation/templates_c *.j2 # Report templates recursive-include nuitka/reports *.j2 ================================================ FILE: README.rst ================================================ #################### Nuitka User Manual #################### This document is the recommended first read when you start using **Nuitka**. On this page, you will learn more about **Nuitka** fundamentals, such as license type, use cases, requirements, and credits. .. contents:: Table of Contents :depth: 1 :local: :class: page-toc Nuitka is **the** Python compiler. It is written in Python. It is a seamless replacement or extension to the Python interpreter and compiles **every** construct that Python 2 (2.6, 2.7) and Python 3 (3.4 - 3.11) have, when itself run with that Python version. It then executes uncompiled code and compiled code together in an extremely compatible manner. You can use all Python library modules and all extension modules freely. Nuitka translates the Python modules into a C level program that then uses ``libpython`` and static C files of its own to execute in the same way as CPython does. All optimization is aimed at avoiding overhead, where it's unnecessary. None is aimed at removing compatibility, although slight improvements will occasionally be done, where not every bug of standard Python is emulated, e.g. more complete error messages are given, but there is a full compatibility mode to disable even that. ************** Requirements ************** To ensure smooth operation of **Nuitka**, make sure to follow system requirements, that include the following components: .. contents:: :depth: 1 :local: C Compiler ========== You need a C compiler with support for C11 or alternatively a C++ compiler for C++03 [#]_. Currently, this means, you need to use one of these compilers: - The MinGW64 C11 compiler, on Windows, must be based on gcc 11.2 or higher. It will be *automatically* downloaded if no usable C compiler is found, which is the recommended way of installing it, as Nuitka will also upgrade it for you. - Visual Studio 2022 or higher on Windows [#]_. English language pack for best results (Nuitka filters away garbage outputs, but only for English language). It will be used by default if installed. - On all other platforms, the ``gcc`` compiler of at least version 5.1, and below that the ``g++`` compiler of at least version 4.4 as an alternative. - The ``clang`` compiler on macOS X and most FreeBSD architectures. - On Windows, the ``clang-cl`` compiler on Windows can be used if provided by the Visual Studio installer. .. [#] Support for this C11 is given with gcc 5.x or higher or any clang version. The older MSVC compilers don't do it yet. But as a workaround, with Python 3.10 or older, the C++03 language standard is significantly overlapping with C11, it is then used instead. .. [#] Download for free from https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx (the community editions work just fine). The latest version is recommended, but not required. On the other hand, there is no need to except to support pre-Windows 10 versions, and they might work for you, but support of these configurations is only available to commercial users. Python ====== **Python 2** (2.6, 2.7) and **Python 3** (3.4 — 3.11) are supported. If at any moment, there is a stable Python release that is not in this list, rest assured it is being worked on and will be added. .. important:: For Python 3.4 and *only* that version, we need other Python version as a *compile time* dependency. Nuitka itself is fully compatible with all listed versions, but Scons as an internally used tool is not. For these versions, you *need* a Python2 or Python 3.5 or higher installed as well, but only during the compile time. That is for use with Scons (which orchestrates the C compilation), which does not support the same Python versions as Nuitka. In addition, on Windows, Python2 cannot be used because ``clcache`` does not work with it, there a Python 3.5 or higher needs to be installed. Nuitka finds these needed Python versions (e.g. on Windows via registry) and you shouldn't notice it as long as they are installed. Increasingly, other functionality is available when another Python has a certain package installed. For example, onefile compression will work for a Python 2.x when another Python is found that has the ``zstandard`` package installed. .. admonition:: Moving binaries to other machines The created binaries can be made executable independent of the Python installation, with ``--standalone`` and ``--onefile`` options. .. admonition:: Binary filename suffix The created binaries have an ``.exe`` suffix on Windows. On other platforms they have no suffix for standalone mode, or ``.bin`` suffix, that you are free to remove or change, or specify with the ``-o`` option. The suffix for acceleration mode is added just to be sure that the original script name and the binary name do not ever collide, so we can safely overwrite the binary without destroying the original source file. .. admonition:: It **has to** be CPython, Anaconda Python, or Homebrew You need the standard Python implementation, called "CPython", to execute Nuitka because it is closely tied to implementation details of it. .. admonition:: It **cannot be** from the Windows app store It is known that Windows app store Python definitely does not work, it's checked against. .. admonition:: It **cannot be** pyenv on macOS It is known that macOS "pyenv" does **not** work. Use Homebrew instead for self compiled Python installations. But note that standalone mode will be worse on these platforms and not be as backward compatible with older macOS versions. Operating System ================ Supported Operating Systems: Linux, FreeBSD, NetBSD, macOS, and Windows (32 bits/64 bits/ARM). Others will work as well. The portability is expected to be generally good, but the e.g. Nuitka's internal Scons usage may have to be adapted or need flags passed. Make sure to match Python and C compiler architecture, or else you will get cryptic error messages. Architecture ============ Supported Architectures are x86, x86_64 (amd64), and arm, likely many, many more. Other architectures are expected to also work, out of the box, as Nuitka is generally not using any hardware specifics. These are just the ones tested and known to be good. Feedback is welcome. Generally, the architectures that Debian supports can be considered good and tested, too. ******* Usage ******* Command Line ============ The recommended way of executing Nuitka is `` -m nuitka`` to be absolutely certain which Python interpreter you are using, so it is easier to match with what Nuitka has. The next best way of executing Nuitka bare that is from a source checkout or archive, with no environment variable changes, most noteworthy, you do not have to mess with ``PYTHONPATH`` at all for Nuitka. You just execute the ``nuitka`` and ``nuitka-run`` scripts directly without any changes to the environment. You may want to add the ``bin`` directory to your ``PATH`` for your convenience, but that step is optional. Moreover, if you want to execute with the right interpreter, in that case, be sure to execute `` bin/nuitka`` and be good. .. admonition:: Pick the right Interpreter If you encounter a ``SyntaxError`` you absolutely most certainly have picked the wrong interpreter for the program you are compiling. Nuitka has a ``--help`` option to output what it can do: .. code:: bash nuitka --help The ``nuitka-run`` command is the same as ``nuitka``, but with a different default. It tries to compile *and* directly execute a Python script: .. code:: bash nuitka-run --help This option that is different is ``--run``, and passing on arguments after the first non-option to the created binary, so it is somewhat more similar to what plain ``python`` will do. Installation ============ For most systems, there will be packages on the `download page `__ of Nuitka. But you can also install it from source code as described above, but also like any other Python program it can be installed via the normal ``python setup.py install`` routine. Notice for integration with GitHub workflows there is this `Nuitka-Action `__ that you should use that makes it really easy to integrate. You ought to start with a local compilation though, but this will be easiest for cross platform compilation with Nuitka. License ======= Nuitka is licensed under the Apache License, Version 2.0; you may not use it except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ************************************* Tutorial Setup and build on Windows ************************************* This is basic steps if you have nothing installed, of course if you have any of the parts, just skip it. Setup ===== Install Python -------------- - Download and install Python from https://www.python.org/downloads/windows - Select one of ``Windows x86-64 web-based installer`` (64 bits Python, recommended) or ``x86 executable`` (32 bits Python) installer. - Verify it's working using command ``python --version``. Install Nuitka -------------- - ``python -m pip install nuitka`` - Verify using command ``python -m nuitka --version`` Write some code and test ======================== Create a folder for the Python code ----------------------------------- - ``mkdir`` HelloWorld - make a python file named **hello.py** .. code:: python def talk(message): return "Talk " + message def main(): print(talk("Hello World")) if __name__ == "__main__": main() Test your program ----------------- Do as you normally would. Running Nuitka on code that works incorrectly is not easier to debug. .. code:: bash python hello.py ---- Build it using -------------- .. code:: bash python -m nuitka hello.py .. note:: This will prompt you to download a C caching tool (to speed up repeated compilation of generated C code) and a MinGW64 based C compiler, unless you have a suitable MSVC installed. Say ``yes`` to both those questions. Run it ------ Execute the ``hello.exe`` created near ``hello.py``. Distribute ---------- To distribute, build with ``--standalone`` option, which will not output a single executable, but a whole folder. Copy the resulting ``hello.dist`` folder to the other machine and run it. You may also try ``--onefile`` which does create a single file, but make sure that the mere standalone is working, before turning to it, as it will make the debugging only harder, e.g. in case of missing data files. *********** Use Cases *********** Use Case 1 — Program compilation with all modules embedded ========================================================== If you want to compile a whole program recursively, and not only the single file that is the main program, do it like this: .. code:: bash python -m nuitka --follow-imports program.py .. note:: There are more fine-grained controls than ``--follow-imports`` available. Consider the output of ``nuitka --help``. Including fewer modules into the compilation, but instead using normal Python for it, will make it faster to compile. In case you have a source directory with dynamically loaded files, i.e. one which cannot be found by recursing after normal import statements via the ``PYTHONPATH`` (which would be the recommended way), you can always require that a given directory shall also be included in the executable: .. code:: bash python -m nuitka --follow-imports --include-plugin-directory=plugin_dir program.py .. note:: If you don't do any dynamic imports, simply setting your ``PYTHONPATH`` at compilation time is what you should do. Use ``--include-plugin-directory`` only if you make ``__import__()`` calls that Nuitka cannot predict, and that come from a directory, for everything from your Python installation, use ``--include-module`` or ``--include-package``. .. note:: The resulting filename will be ``program.exe`` on Windows, ``program.bin`` on other platforms, but ``--output-filename`` allows changing that. .. note:: The resulting binary still depends on CPython and used C extension modules being installed. If you want to be able to copy it to another machine, use ``--standalone`` and copy the created ``program.dist`` directory and execute the ``program.exe`` (Windows) or ``program`` (other platforms) put inside. Use Case 2 — Extension Module compilation ========================================= If you want to compile a single extension module, all you have to do is this: .. code:: bash python -m nuitka --module some_module.py The resulting file ``some_module.so`` can then be used instead of ``some_module.py``. .. important:: The filename of the produced extension module must not be changed as Python insists on a module name derived function as an entry point, in this case ``PyInit_some_module`` and renaming the file will not change that. Match the filename of the source code to what the binary name should be. .. note:: If both the extension module and the source code of it are in the same directory, the extension module is loaded. Changes to the source code only have effect once you recompile. .. note:: The option ``--follow-import-to`` works as well, but the included modules will only become importable *after* you imported the ``some_module`` name. If these kinds of imports are invisible to Nuitka, e.g. dynamically created, you can use ``--include-module`` or ``--include-package`` in that case, but for static imports it should not be needed. .. note:: An extension module can never include other extension modules. You will have to create a wheel for this to be doable. .. note:: The resulting extension module can only be loaded into a CPython of the same version and doesn't include other extension modules. Use Case 3 — Package compilation ================================ If you need to compile a whole package and embed all modules, that is also feasible, use Nuitka like this: .. code:: bash python -m nuitka --module some_package --include-package=some_package .. note:: The inclusion of the package contents needs to be provided manually; otherwise, the package is mostly empty. You can be more specific if you like, and only include part of it, or exclude part of it, e.g. with ``--nofollow-import-to='*.tests'`` you would not include the unused test part of your code. .. note:: Data files located inside the package will not be embedded by this process, you need to copy them yourself with this approach. Alternatively, you can use the `file embedding of Nuitka commercial `__. Use Case 4 — Program Distribution ================================= For distribution to other systems, there is the standalone mode, which produces a folder for which you can specify ``--standalone``. .. code:: bash python -m nuitka --standalone program.py Following all imports is default in this mode. You can selectively exclude modules by specifically saying ``--nofollow-import-to``, but then an ``ImportError`` will be raised when import of it is attempted at program run time. This may cause different behavior, but it may also improve your compile time if done wisely. For data files to be included, use the option ``--include-data-files==`` where the source is a file system path, but the target has to be specified relative. For the standalone mode, you can also copy them manually, but this can do extra checks, and for the onefile mode, there is no manual copying possible. To copy some or all file in a directory, use the option ``--include-data-files=/etc/*.txt=etc/`` where you get to specify shell patterns for the files, and a subdirectory where to put them, indicated by the trailing slash. .. important:: Nuitka does not consider data files code, do not include DLLs, or Python files as data files, and expect them to work, they will not, unless you really know what you are doing. In the following, non-code data files are all files, not matching on of these criterions. +------------+----------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+ | Suffix | Rationale | Solution | +============+========================================================================================+========================================================================================================+ | ``.py`` | Nuitka trims even the stdlib modules to be included. If it doesn't see Python code, | Use ``--include-module`` on them instead | | | there is no dependencies analyzed, and as a result it will just not work. | | +------------+----------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+ | ``.pyc`` | Same as ``.py``. | Use ``--include-module`` on them from their source code instead. | +------------+----------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+ | ``.pyo`` | Same as ``.pyc``. | Use ``--include-module`` on them from their source code instead. | +------------+----------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+ | ``.pyw`` | Same as ``.py``. | For including multiple programs, use multiple ``--main`` arguments instead. | +------------+----------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+ | ``.pyi`` | These are ignored, because they are code-like and not needed at run time. For the | Raise an issue if 3rd part software needs it. | | | ``lazy`` package that actually would depend on them, we made a compile time solution | | | | that removes the need. | | +------------+----------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+ | ``.pyx`` | These are ignored, because they are Cython source code not used at run time | | +------------+----------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+ | ``.dll`` | These are ignored, since they **usually** are not data files. For the cases where 3rd | Create Nuitka Package configuration for those, with ``dll`` section for the package that uses them. | | | party packages do actually used them as data, e.g. ``.NET`` packages, we solve that in | For rare cases, data-files section with special configuration might be the correct thing to do. | | | package configuration for it. | | +------------+----------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+ | ``.dylib`` | These are ignored, since they macOS extension modules or DLLs. | Need to add configuration with ``dll`` section or ``depends`` that are missing | +------------+----------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+ | ``.so`` | These are ignored, since they Linux, BSD, etc. extension modules or DLLs. | Need to add configuration with ``dll`` section or ``depends`` that are missing | +------------+----------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+ | ``.exe`` | The are binaries to Windows. | You can add Nuitka Package configuration to include those as DLLs and mark them as ``executable: yes`` | +------------+----------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+ | ``.bin`` | The are binaries to non-Windows, otherwise same as ``.exe``. | | +------------+----------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+ Also folders are ignored, these are ``site-packages``, ``dist-packages`` and ``vendor-packages`` which would otherwise include a full virtualenv, which is never a good thing to happen. And the ``__pycache__`` folder is also always ignored. On non-MacOS the file ``.DS_Store`` is ignored too, and ``py.typed`` folders have only meaning to IDEs, and are ignored like ``.pyi`` files . To copy a whole folder with all non-code files, you can use ``--include-data-dir=/path/to/images=images`` which will place those in the destination, and if you want to use the ``--noinclude-data-files`` option to remove them. Code files are as detailed above DLLs, executables, Python files, etc. and will be ignored. For those you can use the ``--include-data-files=/binaries/*.exe=binary/`` form to force them, but that is not recommended and known to cause issues at run-time. For package data, there is a better way, namely using ``--include-package-data``, which detects all non-code data files of packages automatically and copies them over. It even accepts patterns in a shell style. It spares you the need to find the package directory yourself and should be preferred whenever available. Functionally it's very similar to ``--include-data-dir`` but it has the benefit to locate the correct folder for you. With data files, you are largely on your own. Nuitka keeps track of ones that are needed by popular packages, but it might be incomplete. Raise issues if you encounter something in these. Even better, raise PRs with enhancements to the Nuitka package configuration. With want 3rd party software to just work out of the box. When that is working, you can use the onefile mode if you so desire. .. code:: bash python -m nuitka --onefile program.py This will create a single binary, that extracts itself on the target, before running the program. But notice, that accessing files relative to your program is impacted, make sure to read the section `Onefile: Finding files`_ as well. .. code:: bash # Create a binary that unpacks into a temporary folder python -m nuitka --onefile program.py .. note:: There are more platform-specific options, e.g. related to icons, splash screen, and version information, consider the ``--help`` output for the details of these and check the section Tweaks_. For the unpacking, by default a unique user temporary path one is used, and then deleted, however this default ``--onefile-tempdir-spec="{TEMP}/onefile_{PID}_{TIME}"`` can be overridden with a path specification that is using then using a cached path, avoiding repeated unpacking, e.g. with ``--onefile-tempdir-spec="{CACHE_DIR}/{COMPANY}/{PRODUCT}/{VERSION}"`` which uses version information, and user-specific cache directory. .. note:: Using cached paths will be relevant, e.g. when Windows Firewall comes into play because otherwise, the binary will be a different one to it each time it is run. Currently, these expanded tokens are available: +----------------+-----------------------------------------------------------+---------------------------------------+ | Token | What this Expands to | Example | +================+===========================================================+=======================================+ | {TEMP} | User temporary file directory | C:\\Users\\...\\AppData\\Locals\\Temp | +----------------+-----------------------------------------------------------+---------------------------------------+ | {PID} | Process ID | 2772 | +----------------+-----------------------------------------------------------+---------------------------------------+ | {TIME} | Time in seconds since the epoch. | 1299852985 | +----------------+-----------------------------------------------------------+---------------------------------------+ | {PROGRAM} | Full program run-time filename of executable. | C:\\SomeWhere\\YourOnefile.exe | +----------------+-----------------------------------------------------------+---------------------------------------+ | {PROGRAM_BASE} | No-suffix of run-time filename of executable. | C:\\SomeWhere\\YourOnefile | +----------------+-----------------------------------------------------------+---------------------------------------+ | {CACHE_DIR} | Cache directory for the user. | C:\\Users\\SomeBody\\AppData\\Local | +----------------+-----------------------------------------------------------+---------------------------------------+ | {COMPANY} | Value given as ``--company-name`` | YourCompanyName | +----------------+-----------------------------------------------------------+---------------------------------------+ | {PRODUCT} | Value given as ``--product-name`` | YourProductName | +----------------+-----------------------------------------------------------+---------------------------------------+ | {VERSION} | Combination of ``--file-version`` & ``--product-version`` | 3.0.0.0-1.0.0.0 | +----------------+-----------------------------------------------------------+---------------------------------------+ | {HOME} | Home directory for the user. | /home/somebody | +----------------+-----------------------------------------------------------+---------------------------------------+ | {NONE} | When provided for file outputs, ``None`` is used | see notice below | +----------------+-----------------------------------------------------------+---------------------------------------+ | {NULL} | When provided for file outputs, ``os.devnull`` is used | see notice below | +----------------+-----------------------------------------------------------+---------------------------------------+ .. important:: It is your responsibility to make the path provided unique, on Windows a running program will be locked, and while using a fixed folder name is possible, it can cause locking issues in that case, where the program gets restarted. Usually, you need to use ``{TIME}`` or at least ``{PID}`` to make a path unique, and this is mainly intended for use cases, where e.g. you want things to reside in a place you choose or abide your naming conventions. .. important:: For disabling output and stderr with ``--force-stdout-spec`` and ``--force-stderr-spec`` the values ``{NONE}`` and ``{NULL}`` achieve it, but with different effect. With ``{NONE}``, the corresponding handle becomes ``None``. As a result, e.g. ``sys.stdout`` will be ``None``, which is different from ``{NULL}`` where it will be backed by a file pointing to ``os.devnull``, i.e. you can write to it. With ``{NONE}``, you may e.g. get ``RuntimeError: lost sys.stdout`` in case it does get used; with ``{NULL}`` that never happens. However, some libraries handle this as input for their logging mechanism, and on Windows this is how you are compatible with ``pythonw.exe`` which is behaving like ``{NONE}``. Use Case 5 — Setuptools Wheels ============================== If you have a ``setup.py``, ``setup.cfg`` or ``pyproject.toml`` driven creation of wheels for your software in place, putting Nuitka to use is extremely easy. Let's start with the most common ``setuptools`` approach, you can, having Nuitka installed of course, simply execute the target ``bdist_nuitka`` rather than the ``bdist_wheel``. It takes all the options and allows you to specify some more, that are specific to Nuitka. .. code:: python # For setup.py if you don't use other build systems: setup( # Data files are to be handled by setuptools and not Nuitka package_data={"some_package": ["some_file.txt"]}, ..., # This is to pass Nuitka options. command_options={ 'nuitka': { # boolean option, e.g. if you cared for C compilation commands '--show-scons': True, # options without value, e.g. enforce using Clang '--clang': None, # options with single values, e.g. enable a plugin of Nuitka '--enable-plugin': "pyside2", # options with several values, e.g. avoiding including modules '--nofollow-import-to' : ["*.tests", "*.distutils"], }, }, ) # For setup.py with other build systems: # The tuple nature of the arguments is required by the dark nature of # "setuptools" and plugins to it, that insist on full compatibility, # e.g. "setuptools_rust" setup( # Data files are to be handled by setuptools and not Nuitka package_data={"some_package": ["some_file.txt"]}, ..., # This is to pass Nuitka options. ..., command_options={ 'nuitka': { # boolean option, e.g. if you cared for C compilation commands '--show-scons': ("setup.py", True), # options without value, e.g. enforce using Clang '--clang': ("setup.py", None), # options with single values, e.g. enable a plugin of Nuitka '--enable-plugin': ("setup.py", "pyside2"), # options with several values, e.g. avoiding including modules '--nofollow-import-to' : ("setup.py", ["*.tests", "*.distutils"]), } }, ) If for some reason, you cannot or do not want to change the target, you can add this to your ``setup.py``. .. code:: python # For setup.py setup( ..., build_with_nuitka=True ) .. note:: To temporarily disable the compilation, you could the remove above line, or edit the value to ``False`` by or take its value from an environment variable if you so choose, e.g. ``bool(os.getenv("USE_NUITKA", "True"))``. This is up to you. Or you could put it in your ``setup.cfg`` .. code:: toml [metadata] build_with_nuitka = true And last, but not least, Nuitka also supports the new ``build`` meta, so when you have a ``pyproject.toml`` already, simple replace or add this value: .. code:: toml [build-system] requires = ["setuptools>=42", "wheel", "nuitka", "toml"] build-backend = "nuitka.distutils.Build" # Data files are to be handled by setuptools and not Nuitka [tool.setuptools.package-data] some_package = ['data_file.txt'] [tool.nuitka] # These are not recommended, but they make it obvious to have effect. # boolean option, e.g. if you cared for C compilation commands, leading # dashes are omitted show-scons = true # options with single values, e.g. enable a plugin of Nuitka enable-plugin = "pyside2" # options with several values, e.g. avoiding including modules, accepts # list argument. nofollow-import-to = ["*.tests", "*.distutils"] .. note:: For the ``nuitka`` requirement above absolute paths like ``C:\Users\...\Nuitka`` will also work on Linux, use an absolute path with *two* leading slashes, e.g. ``//home/.../Nuitka``. .. note:: Whatever approach you take, data files in these wheels are not handled by Nuitka at all, but by setuptools. You can, however, use the data file embedding of Nuitka commercial. In that case, you actually would embed the files inside the extension module itself, and not as a file in the wheel. Use Case 6 — Multidist ====================== If you have multiple programs, that each should be executable, in the past you had to compile multiple times, and deploy all of these. With standalone mode, this, of course, meant that you were fairly wasteful, as sharing the folders could be done, but wasn't really supported by Nuitka. Enter ``Multidist``. There is an option ``--main`` that replaces or adds to the positional argument given. And it can be given multiple times. When given multiple times, Nuitka will create a binary that contains the code of all the programs given, but sharing modules used in them. They therefore do not have to be distributed multiple times. Let's call the basename of the main path, and entry point. The names of these must, of course, be different. Then the created binary can execute either entry point, and will react to what ``sys.argv[0]`` appears to it. So if executed in the right way (with something like ``subprocess`` or OS API you can control this name), or by renaming or copying the binary, or symlinking to it, you can then achieve the miracle. This allows to combine very different programs into one. .. note:: This feature is still experimental. Use with care and report your findings should you encounter anything that is undesirable behavior This mode works with standalone, onefile, and mere acceleration. It does not work with module mode. Use Case 7 — Building with GitHub Workflows =========================================== For integration with GitHub workflows there is this `Nuitka-Action `__ that you should use that makes it really easy to integrate. You ought to start with a local compilation though, but this will be easiest for cross platform compilation with Nuitka. This is an example workflow that builds on all 3 OSes .. code:: yaml jobs: build: strategy: matrix: os: [macos-latest, ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - name: Check-out repository uses: actions/checkout@v3 - name: Setup Python uses: actions/setup-python@v4 with: python-version: '3.10' cache: 'pip' cache-dependency-path: | **/requirements*.txt - name: Install your Dependencies run: | pip install -r requirements.txt -r requirements-dev.txt - name: Build Executable with Nuitka uses: Nuitka/Nuitka-Action@main with: nuitka-version: main script-name: your_main_program.py # many more Nuitka options available, see action doc, but it's best # to use nuitka-project: options in your code, so e.g. you can make # a difference for macOS and create an app bundle there. onefile: true - name: Upload Artifacts uses: actions/upload-artifact@v3 with: name: ${{ runner.os }} Build path: | # match what's created for the 3 OSes build/*.exe build/*.bin build/*.app/**/* If you app is a GUI, e.g. ``your_main_program.py`` should contain these comments as explained in `Nuitka Options in the code`_ since on macOS this should then be a bundle. .. code:: python # Compilation mode, standalone everywhere, except on macOS there app bundle # nuitka-project-if: {OS} in ("Windows", "Linux", "FreeBSD"): # nuitka-project: --onefile # nuitka-project-if: {OS} == "Darwin": # nuitka-project: --standalone # nuitka-project: --macos-create-app-bundle # # Debugging options, controlled via environment variable at compile time. # nuitka-project-if: os.getenv("DEBUG_COMPILATION", "no") == "yes" # nuitka-project: --enable-console # nuitka-project-else: # nuitka-project: --disable-console ******** Tweaks ******** Icons ===== For good looks, you may specify icons. On Windows, you can provide an icon file, a template executable, or a PNG file. All of these will work and may even be combined: .. code:: bash # These create binaries with icons on Windows python -m nuitka --onefile --windows-icon-from-ico=your-icon.png program.py python -m nuitka --onefile --windows-icon-from-ico=your-icon.ico program.py python -m nuitka --onefile --windows-icon-template-exe=your-icon.ico program.py # These create application bundles with icons on macOS python -m nuitka --macos-create-app-bundle --macos-app-icon=your-icon.png program.py python -m nuitka --macos-create-app-bundle --macos-app-icon=your-icon.icns program.py .. note:: With Nuitka, you do not have to create platform-specific icons, but instead it will convert e.g. PNG, but also other formats on the fly during the build. MacOS Entitlements ================== Entitlements for an macOS application bundle can be added with the option, ``--macos-app-protected-resource``, all values are listed on `this page from Apple `__ An example value would be ``--macos-app-protected-resource=NSMicrophoneUsageDescription:Microphone access`` for requesting access to a Microphone. After the colon, the descriptive text is to be given. .. note:: Beware that in the likely case of using spaces in the description part, you need to quote it for your shell to get through to Nuitka and not be interpreted as Nuitka arguments. Console Window ============== On Windows, the console is opened by programs unless you say so. Nuitka defaults to this, effectively being only good for terminal programs, or programs where the output is requested to be seen. There is a difference in ``pythonw.exe`` and ``python.exe`` along those lines. This is replicated in Nuitka with the option ``--disable-console``. Nuitka recommends you to consider this in case you are using ``PySide6`` e.g. and other GUI packages, e.g. ``wx``, but it leaves the decision up to you. In case, you know your program is console application, just using ``--enable-console`` which will get rid of these kinds of outputs from Nuitka. .. note:: The ``pythonw.exe`` is never good to be used with Nuitka, as you cannot see its output. Splash screen ============= Splash screens are useful when program startup is slow. Onefile startup itself is not slow, but your program may be, and you cannot really know how fast the computer used will be, so it might be a good idea to have them. Luckily, with Nuitka, they are easy to add for Windows. For the splash screen, you need to specify it as a PNG file, and then make sure to disable the splash screen when your program is ready, e.g. has completed the imports, prepared the window, connected to the database, and wants the splash screen to go away. Here we are using the project syntax to combine the code with the creation, compile this: .. code:: python # nuitka-project: --onefile # nuitka-project: --onefile-windows-splash-screen-image={MAIN_DIRECTORY}/Splash-Screen.png # Whatever this is, obviously print("Delaying startup by 10s...") import time, tempfile, os time.sleep(10) # Use this code to signal the splash screen removal. if "NUITKA_ONEFILE_PARENT" in os.environ: splash_filename = os.path.join( tempfile.gettempdir(), "onefile_%d_splash_feedback.tmp" % int(os.environ["NUITKA_ONEFILE_PARENT"]), ) if os.path.exists(splash_filename): os.unlink(splash_filename) print("Done... splash should be gone.") ... # Rest of your program goes here. Reports ======= For analysis of your program and Nuitka packaging, there is the `Compilation Report`_ available. You can also make custom reports by providing your template, with a few of them built-in to Nuitka. These reports carry all the detail information, e.g. when a module was attempted to be imported, but not found, you can see where that happens. For bug reporting, it is very much recommended to provide the report. Version Information =================== You can attach copyright and trademark information, company name, product name, and so on to your compilation. This is then used in version information for the created binary on Windows, or application bundle on macOS. If you find something that is lacking, please let us know. ****************** Typical Problems ****************** Deployment Mode =============== By default, Nuitka compiles without ``--deployment`` which leaves a set of safe guards and helpers on, that are aimed at debugging wrong uses of Nuitka. This is a new feature, and implements a bunch of protections and helpers, that are documented here. Fork bombs (self-execution) --------------------------- So after compilation, ``sys.executable`` is the compiled binary. In case of packages like ``multiprocessing``, ``joblib``, or ``loky`` what these typically do is to expect to run from a full ``python`` with ``sys.executable`` and then to be able to use its options like ``-c command`` or ``-m module_name`` and then be able to launch other code temporarily or permanently as a service daemon. With Nuitka however, this executes your program again, and puts these arguments, in ``sys.argv`` where you maybe ignore them, and then you fork yourself again to launch the helper daemons. Sometimes this ends up spawning CPU count processes that spawn CPU count processes that... this is called a fork bomb, and with almost all systems, that freezes them easily to death. That is why e.g. this happens with default Nuitka: .. code:: ./hello.dist/hello.bin -l fooL -m fooM -n fooN -o fooO -p Error, the program tried to call itself with '-m' argument. Disable with '--no-deployment-flag=self-execution'. Your program may well have its own command line parsing, and not use an unsupported package that does attempt to re-execute. In this case, you need at *compile time* to use ``--no-deployment-flag=self-execution`` which disables this specific guard. Misleading Messages ------------------- Some packages output what they think is helpful information about what the reason of a failed import might mean. With compiled programs there are very often just plain wrong. We try and repair those in non-deployment mode. Here is an example, where we change a message that asks to pip install (which is not the issue) to point the user to the include command that makes an ``imageio`` plugin work. .. code:: yaml - module-name: 'imageio.core.imopen' anti-bloat: - replacements_plain: '`pip install imageio[{config.install_name}]` to install it': '`--include-module={config.module_name}` with Nuitka to include it' 'err_type = ImportError': 'err_type = RuntimeError' when: 'not deployment' And much more ------------- The deployment mode is relatively new and has constantly more features added, e.g. something for ``FileNotFoundError`` should be coming soon. Disabling All ------------- All these helpers can of course be disabled at once with ``--deployment`` but keep in mind that for debugging, you may want to re-enable it. You might want to use Nuitka Project options and an environment variable to make this conditional. Should you disable them all? We believe, disabling should only happen selectively, but with PyPI upgrades, your code changes, all of these issues can sneak back in. The space saving of deployment mode is currently negligible, so attempt to not do it, but review what exists, and if you know that it cannot affect you, or if it does, you will not need it. Some of the future ones, will clearly be geared at beginner level usage. Windows Virus scanners ====================== Binaries compiled on Windows with default settings of Nuitka and no further actions taken might be recognized by some AV vendors as malware. This is avoidable, but only in Nuitka commercial there is actual support and instructions for how to do it, seeing this as a typical commercial only need. https://nuitka.net/doc/commercial.html Linux Standalone ================ For Linux standalone it is pretty difficult to build a binary that works on other Linux versions. This is mainly because on Linux, much software is built specifically targeted to concrete DLLs. Things like glibc used, are then encoded into the binary built, and it will not run with an older glibc, just to give one critical example. The solution is to build on the oldest OS that you want to see supported. Picking that and setting it up can be tedious, so can be login, and keeping it secure, as it's something you put your source code on. To aid that, Nuitka commercial has container based builds, that you can use. This uses dedicated optimized Python builds, targets CentOS 7 and supports even newest Pythons and very old OSes that way using recent C compiler chains all turn key solution. The effort needs to be compensated to support Nuitka development for Linux, there you need to purchase it https://nuitka.net/doc/commercial.html but even a sponsor license will be cheaper than doing it yourself. Program crashes system (fork bombs) =================================== A fork bomb is a program that starts itself over and over. This can easily happen, since ``sys.executable`` for compiled programs is not a Python interpreter, and packages that try to do multiprocessing in a better way, often relaunch themselves through this, and Nuitka needs and does have handling for these with known packages. However, you may encounter a situation where the detection of this fails. See deployment option above that is needed to disable this protection. When this fork bomb happens easily all memory, all CPU of the system that is available to the user is being used, and even the most powerful build system will go down in flames sometimes needing a hard reboot. For fork bombs, we can use ``--experimental=debug-self-forking`` and see what it does, and we have a trick, that prevents fork bombs from having any actual success in their bombing. Put this at the start of your program. .. code:: python import os, sys if "NUITKA_LAUNCH_TOKEN" not in os.environ: sys.exit("Error, need launch token or else fork bomb suspected.") else: del os.environ["NUITKA_LAUNCH_TOKEN"] Actually Nuitka is trying to get ahold of them without the deployment option already, finding "-c" and "-m" options, but it may not be perfect or not work well with a package (anymore). Memory issues and compiler bugs =============================== In some cases, the C compilers will crash saying they cannot allocate memory or that some input was truncated, or similar error messages, clearly from it. These are example error messages, that are a sure sign of too low memory, there is no end to them. .. code:: # gcc fatal error: error writing to -: Invalid argument Killed signal terminated program # MSVC fatal error C1002: compiler is out of heap space in pass 2 fatal error C1001: Internal compiler error There are several options you can explore here. Ask Nuitka to use less memory ----------------------------- There is a dedicated option ``--low-memory`` which influences decisions of Nuitka, such that it avoids high usage of memory during compilation at the cost of increased compile time. Avoid 32 bit C compiler/assembler memory limits ----------------------------------------------- Do not use a 32 bit compiler, but a 64 bit one. If you are using Python with 32 bits on Windows, you most definitely ought to use MSVC as the C compiler, and not MinGW64. The MSVC is a cross-compiler, and can use more memory than gcc on that platform. If you are not on Windows, that is not an option, of course. Also, using the 64 bit Python will work. Use a minimal virtualenv ------------------------ When you compile from a living installation, that may well have many optional dependencies of your software installed. Some software will then have imports on these, and Nuitka will compile them as well. Not only may these be just the troublemakers, they also require more memory, so get rid of that. Of course, you do have to check that your program has all the needed dependencies before you attempt to compile, or else the compiled program will equally not run. Use LTO compilation or not -------------------------- With ``--lto=yes`` or ``--lto=no`` you can switch the C compilation to only produce bytecode, and not assembler code and machine code directly, but make a whole program optimization at the end. This will change the memory usage pretty dramatically, and if your error is coming from the assembler, using LTO will most definitely avoid that. Switch the C compiler to clang ------------------------------ People have reported that programs that fail to compile with gcc due to its bugs or memory usage work fine with clang on Linux. On Windows, this could still be an option, but it needs to be implemented first for the automatic downloaded gcc, that would contain it. Since MSVC is known to be more memory effective anyway, you should go there, and if you want to use Clang, there is support for the one contained in MSVC. Add a larger swap file to your embedded Linux --------------------------------------------- On systems with not enough RAM, you need to use swap space. Running out of it is possibly a cause, and adding more swap space, or one at all, might solve the issue, but beware that it will make things extremely slow when the compilers swap back and forth, so consider the next tip first or on top of it. Limit the amount of compilation jobs ------------------------------------ With the ``--jobs`` option of Nuitka, it will not start many C compiler instances at once, each competing for the scarce resource of RAM. By picking a value of one, only one C compiler instance will be running, and on an 8 core system, that reduces the amount of memory by factor 8, so that's a natural choice right there. Dynamic ``sys.path`` ==================== If your script modifies ``sys.path``, e.g. inserts directories with source code relative to it, Nuitka will not be able to see those. However, if you set the ``PYTHONPATH`` to the resulting value, it will be able to compile it and find the used modules from these paths as well. Manual Python File Loading ========================== A very frequent pattern with private code is that it scans plugin directories of some kind, and e.g. uses ``os.listdir``, then considers Python filenames, and then opens a file and does ``exec`` on them. This approach works for Python code, but for compiled code, you should use this much cleaner approach, that works for pure Python code and is a lot less vulnerable. .. code:: python # Using a package name, to locate the plugins. This is also a sane # way to organize them into a directory. scan_path = scan_package.__path__ for item in pkgutil.iter_modules(scan_path): importlib.import_module(scan_package.__name__ + "." + item.name) # You may want to do it recursively, but we don't do this here in # this example. If you'd like to, handle that in this kind of branch. if item.ispkg: ... Missing data files in standalone ================================ If your program fails to find data file, it can cause all kinds of different behavior, e.g. a package might complain it is not the right version because a ``VERSION`` file check defaulted to an unknown. The absence of icon files or help texts, may raise strange errors. Often the error paths for files not being present are even buggy and will reveal programming errors like unbound local variables. Please look carefully at these exceptions, keeping in mind that this can be the cause. If your program works without standalone, chances are data files might be the cause. The most common error indicating file absence is of course an uncaught ``FileNotFoundError`` with a filename. You should figure out what package is missing files and then use ``--include-package-data`` (preferably), or ``--include-data-dir``/``--include-data-files`` to include them. Missing DLLs/EXEs in standalone =============================== Nuitka has plugins that deal with copying DLLs. For NumPy, SciPy, Tkinter, etc. These need special treatment to be able to run on other systems. Manually copying them is not enough and will give strange errors. Sometimes newer version of packages, esp. NumPy can be unsupported. In this case, you will have to raise an issue, and use the older one. If you want to manually add a DLL or an EXE because it is your project only, you will have to use user Yaml files describing where they can be found. This is described in detail with examples in the `Nuitka Package Configuration `__ page. Dependency creep in standalone ============================== Some packages are a single import, but to Nuitka mean that more than a thousand packages (literally) are to be included. The prime example of Pandas, which does want to plug and use just about everything you can imagine. Multiple frameworks for syntax highlighting everything imaginable take time. Nuitka will have to learn effective caching to deal with this in the future. Presently, you will have to deal with huge compilation times for these. A major weapon in fighting dependency creep should be applied, namely the ``anti-bloat`` plugin, which offers interesting abilities, that can be put to use and block unneeded imports, giving an error for where they occur. Use it e.g. like this ``--noinclude-pytest-mode=nofollow --noinclude-setuptools-mode=nofollow`` and e.g. also ``--noinclude-custom-mode=setuptools:error`` to get the compiler to error out for a specific package. Make sure to check its help output. It can take for each module of your choice, e.g. forcing also that e.g. ``PyQt5`` is considered uninstalled for standalone mode. It's also driven by a configuration file, ``anti-bloat.yml`` that you can contribute to, removing typical bloat from packages. Please don't hesitate to enhance it and make PRs towards Nuitka with it. Standalone: Finding files ========================= The standard code that normally works, also works, you should refer to ``os.path.dirname(__file__)`` or use all the packages like ``pkgutil``, ``pkg_resources``, ``importlib.resources`` to locate data files near the standalone binary. .. important:: What you should **not** do, is use the current directory ``os.getcwd``, or assume that this is the script directory, e.g. with paths like ``data/``. If you did that, it was never good code. Links, to a program, launching from another directory, etc. will all fail in bad ways. Do not make assumptions about the directory your program is started from. In case you mean to refer to the location of the ``.dist`` folder for files that are to reside near the binary, there is ``__compiled__.containing_dir`` that also abstracts all differences with ``--macos-create-app-bundle`` and the ``.app`` folder a having more nested structure. .. code:: python # This will find a file *near* your app or dist folder try: open(os.path.join(__compiled__.containing_dir, "user-provided-file.txt")) except NameError: open(os.path.join(os.path.dirname(sys.argv[0]), "user-provided-file.txt")) Onefile: Finding files ====================== There is a difference between ``sys.argv[0]`` and ``__file__`` of the main module for the onefile mode, that is caused by using a bootstrap to a temporary location. The first one will be the original executable path, whereas the second one will be the temporary or permanent path the bootstrap executable unpacks to. Data files will be in the later location, your original environment files will be in the former location. Given 2 files, one which you expect to be near your executable, and one which you expect to be inside the onefile binary, access them like this. .. code:: python # This will find a file *near* your onefile.exe open(os.path.join(os.path.dirname(sys.argv[0]), "user-provided-file.txt")) # This will find a file *inside* your onefile.exe open(os.path.join(os.path.dirname(__file__), "user-provided-file.txt")) # This will find a file *near* your onefile binary and work for standalone too try: open(os.path.join(__compiled__.containing_dir, "user-provided-file.txt")) except NameError: open(os.path.join(os.path.dirname(sys.argv[0]), "user-provided-file.txt")) Windows Programs without console give no errors =============================================== For debugging purposes, remove ``--disable-console`` or use the options ``--force-stdout-spec`` and ``--force-stderr-spec`` with paths as documented for ``--onefile-tempdir-spec`` above. These can be relative to the program or absolute, so you can see the outputs given. Deep copying uncompiled functions ================================= Sometimes people use this kind of code, which for packages on PyPI, we deal with by doing source code patches on the fly. If this is in your own code, here is what you can do: .. code:: python def binder(func, name): result = types.FunctionType(func.__code__, func.__globals__, name=func.__name__, argdefs=func.__defaults__, closure=func.__closure__) result = functools.update_wrapper(result, func) result.__kwdefaults__ = func.__kwdefaults__ result.__name__ = name return result Compiled functions cannot be used to create uncompiled ones from, so the above code will not work. However, there is a dedicated ``clone`` method, that is specific to them, so use this instead. .. code:: python def binder(func, name): try: result = func.clone() except AttributeError: result = types.FunctionType(func.__code__, func.__globals__, name=func.__name__, argdefs=func.__defaults__, closure=func.__closure__) result = functools.update_wrapper(result, func) result.__kwdefaults__ = func.__kwdefaults__ result.__name__ = name return result Modules: Extension modules are not executable directly ====================================================== A package can be compiled with Nuitka, no problem, but when it comes to executing it, ``python -m compiled_module`` is not going to work and give the error ``No code object available for AssertsTest`` because the compiled module is not source code, and Python will not just load it. The closest would be ``python -c "import compile_module"`` and you might have to call the main function yourself. To support this, the CPython ``runpy`` and/or ``ExtensionFileLoader`` would need improving such that Nuitka could supply its compiled module object for Python to use. ****** Tips ****** Nuitka Options in the code ========================== One clean way of providing options to Nuitka, that you will always use for your program, is to put them into the main file you compile. There is even support for conditional options, and options using pre-defined variables, this is an example: .. code:: python # Compilation mode, support OS-specific options # nuitka-project-if: {OS} in ("Windows", "Linux", "Darwin", "FreeBSD"): # nuitka-project: --onefile # nuitka-project-else: # nuitka-project: --standalone # The PySide2 plugin covers qt-plugins # nuitka-project: --enable-plugin=pyside2 # nuitka-project: --include-qt-plugins=qml The comments must be at the start of lines, and indentation inside of them is to be used, to end a conditional block, much like in Python. There are currently no other keywords than the used ones demonstrated above. You can put arbitrary Python expressions there, and if you wanted to e.g. access a version information of a package, you could simply use ``__import__("module_name").__version__`` if that would be required to e.g. enable or disable certain Nuitka settings. The only thing Nuitka does that makes this not Python expressions, is expanding ``{variable}`` for a pre-defined set of variables: Table with supported variables: +------------------+--------------------------------+------------------------------------------+ | Variable | What this Expands to | Example | +==================+================================+==========================================+ | {OS} | Name of the OS used | Linux, Windows, Darwin, FreeBSD, OpenBSD | +------------------+--------------------------------+------------------------------------------+ | {Version} | Version of Nuitka | e.g. (1, 6, 0) | +------------------+--------------------------------+------------------------------------------+ | {Commercial} | Version of Nuitka Commercial | e.g. (2, 1, 0) | +------------------+--------------------------------+------------------------------------------+ | {Arch} | Architecture used | x86_64, arm64, etc. | +------------------+--------------------------------+------------------------------------------+ | {MAIN_DIRECTORY} | Directory of the compiled file | some_dir/maybe_relative | +------------------+--------------------------------+------------------------------------------+ | {Flavor} | Variant of Python | e.g. Debian Python, Anaconda Python | +------------------+--------------------------------+------------------------------------------+ The use of ``{MAIN_DIRECTORY}`` is recommended when you want to specify a filename relative to the main script, e.g. for use in data file options or user package configuration yaml files, .. code:: python # nuitka-project: --include-data-files={MAIN_DIRECTORY}/my_icon.png=my_icon.png # nuitka-project: --user-package-configuration-file={MAIN_DIRECTORY}/user.nuitka-package.config.yml Python command line flags ========================= For passing things like ``-O`` or ``-S`` to Python, to your compiled program, there is a command line option name ``--python-flag=`` which makes Nuitka emulate these options. The most important ones are supported, more can certainly be added. Caching compilation results =========================== The C compiler, when invoked with the same input files, will take a long time and much CPU to compile over and over. Make sure you are having ``ccache`` installed and configured when using gcc (even on Windows). It will make repeated compilations much faster, even if things are not yet not perfect, i.e. changes to the program can cause many C files to change, requiring a new compilation instead of using the cached result. On Windows, with gcc Nuitka supports using ``ccache.exe`` which it will offer to download from an official source and it automatically. This is the recommended way of using it on Windows, as other versions can e.g. hang. Nuitka will pick up ``ccache`` if it's found in system ``PATH``, and it will also be possible to provide if by setting ``NUITKA_CCACHE_BINARY`` to the full path of the binary, this is for use in CI systems where things might be non-standard. For the MSVC compilers and ClangCL setups, using the ``clcache`` is automatic and included in Nuitka. On macOS and Intel, there is an automatic download of a ``ccache`` binary from our site, for arm64 arches, it's recommended to use this setup, which installs Homebrew and ccache in there. Nuitka picks that one up automatically if it on that kind of machine. You need and should not use Homebrew with Nuitka otherwise, it's not the best for standalone deployments, but we can take ``ccache`` from there. .. code:: bash export HOMEBREW_INSTALL_FROM_API=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" eval $(/opt/homebrew/bin/brew shellenv) brew install ccache Control where Caches live ========================= The storage for cache results of all kinds, downloads, cached compilation results from C and Nuitka, is done in a platform dependent directory as determined by the ``appdirs`` package. However, you can override it with setting the environment variable ``NUITKA_CACHE_DIR`` to a base directory. This is for use in environments where the home directory is not persisted, but other paths are. There is also per cache control of these caches, here is a table of environment variables that you can set before starting the compilation, to make Nuitka store some of these caches in an entirely separate space. +------------------+-----------------------------------+----------------------------------------+ | Cache name | Environment Variable | Data Put there | +==================+===================================+========================================+ | downloads | NUITKA_CACHE_DIR_DOWNLOADS | Downloads made, e.g. dependency walker | +------------------+-----------------------------------+----------------------------------------+ | ccache | NUITKA_CACHE_DIR_CCACHE | Object files created by gcc | +------------------+-----------------------------------+----------------------------------------+ | clcache | NUITKA_CACHE_DIR_CLCACHE | Object files created by MSVC | +------------------+-----------------------------------+----------------------------------------+ | bytecode | NUITKA_CACHE_DIR_BYTECODE | Bytecode of demoted modules | +------------------+-----------------------------------+----------------------------------------+ | dll-dependencies | NUITKA_CACHE_DIR_DLL_DEPENDENCIES | DLL dependencies | +------------------+-----------------------------------+----------------------------------------+ Runners ======= Avoid running the ``nuitka`` binary, doing ``python -m nuitka`` will make a 100% sure you are using what you think you are. Using the wrong Python will make it give you ``SyntaxError`` for good code or ``ImportError`` for installed modules. That is happening, when you run Nuitka with Python2 on Python3 code and vice versa. By explicitly calling the same Python interpreter binary, you avoid that issue entirely. Fastest C Compilers =================== The fastest binaries of ``pystone.exe`` on Windows with 64 bits Python proved to be significantly faster with MinGW64, roughly 20% better score. So it is recommended for use over MSVC. Using ``clang-cl.exe`` of Clang7 was faster than MSVC, but still significantly slower than MinGW64, and it will be harder to use, so it is not recommended. On Linux, for ``pystone.bin``, the binary produced by ``clang6`` was faster than ``gcc-6.3``, but not by a significant margin. Since gcc is more often already installed, that is recommended to use for now. Differences in C compilation times have not yet been examined. Unexpected Slowdowns ==================== Using the Python DLL, like standard CPython does, can lead to unexpected slowdowns, e.g. in uncompiled code that works with Unicode strings. This is because calling to the DLL rather than residing in the DLL causes overhead, and this even happens to the DLL with itself, being slower, than a Python all contained in one binary. So if feasible, aim at static linking, which is currently only possible with Anaconda Python on non-Windows, Debian Python2, self compiled Pythons (do not activate ``--enable-shared``, not needed), and installs created with ``pyenv``. .. note:: On Anaconda, you may need to execute ``conda install libpython-static`` Standalone executables and dependencies ======================================= The process of making standalone executables for Windows traditionally involves using an external dependency walker to copy necessary libraries along with the compiled executables to the distribution folder. There are plenty of ways to find that something is missing. Do not manually copy things into the folder, esp. not DLLs, as that's not going to work. Instead, make bug reports to get these handled by Nuitka properly. Windows errors with resources ============================= On Windows, the Windows Defender tool and the Windows Indexing Service both scan the freshly created binaries, while Nuitka wants to work with it, e.g. adding more resources, and then preventing operations randomly due to holding locks. Make sure to exclude your compilation stage from these services. Windows standalone program redistribution ========================================= Whether compiling with MingW or MSVC, the standalone programs have external dependencies to Visual C Runtime libraries. Nuitka tries to ship those dependent DLLs by copying them from your system. Beginning with Microsoft Windows 10, Microsoft ships ``ucrt.dll`` (Universal C Runtime libraries) which handles calls to ``api-ms-crt-*.dll``. With earlier Windows platforms (and wine/ReactOS), you should consider installing Visual C runtime libraries before executing a Nuitka standalone compiled program. Depending on the used C compiler, you'll need the following redist versions on the target machines. However, notice that compilation using the 14.3 based version is always recommended, working and best supported, unless you want to target Windows 7. +------------------+-------------+----------+ | Visual C version | Redist Year | CPython | +==================+=============+==========+ | 14.3 | 2022 | 3.11 | +------------------+-------------+----------+ | 14.2 | 2019 | 3.5-3.10 | +------------------+-------------+----------+ | 14.1 | 2017 | 3.5-3.8 | +------------------+-------------+----------+ | 14.0 | 2015 | 3.5-3.8 | +------------------+-------------+----------+ | 10.0 | 2010 | 3.4 | +------------------+-------------+----------+ | 9.0 | 2008 | 2.6, 2.7 | +------------------+-------------+----------+ When using MingGW64 as downloaded by Nuitka, you'll need the following redist versions: +----------------------------+-------------+---------------------+ | MingGW64 version | Redist Year | CPython | +============================+=============+=====================+ | WinLibs automatic download | 2015 | 2.6, 2.7, 3.4- 3.11 | +----------------------------+-------------+---------------------+ Once the corresponding runtime libraries are installed on the target system, you may remove all ``api-ms-crt-*.dll`` files from your Nuitka compiled dist folder. Detecting Nuitka at run time ============================ Nuitka does *not* ``sys.frozen`` unlike other tools because it usually triggers inferior code for no reason. For Nuitka, we have the module attribute ``__compiled__`` to test if a specific module was compiled, and the function attribute ``__compiled__`` to test if a specific function was compiled. Providing extra Options to Nuitka C compilation =============================================== Nuitka will apply values from the environment variables ``CCFLAGS``, ``LDFLAGS`` during the compilation on top of what it determines to be necessary. Beware, of course, that is this is only useful if you know what you are doing, so should this pose issues, raise them only with perfect information. Producing a 32 bit binary on a 64 bit Windows system ==================================================== Nuitka will automatically target the architecture of the Python you are using. If this is 64 bit, it will create a 64 bit binary, if it is 32 bit, it will create a 32 bit binary. You have the option to select the bits when you download the Python. In the output of ``python -m nuitka --version`` there is a line for the architecture. It's ``Arch: x86_64`` for 64 bits, and just ``Arch: x86`` for 32 bits. The C compiler will be picked to match that more or less automatically. If you specify it explicitly, and it mismatches, you will get a warning about the mismatch and informed that your compiler choice was rejected. ******************** Compilation Report ******************** When you use ``--report=compilation-report.xml`` Nuitka will create an XML file with detailed information about the compilation and packaging process. This is growing in completeness with every release and exposes module usage attempts, timings of the compilation, plugin influences, data file paths, DLLs, and reasons why things are included or not. At this time, the report contains absolute paths in some places, with your private information. The goal is to make this blended out by default because we also want to become able to compare compilation reports from different setups, e.g. with updated packages, and see the changes to Nuitka. The report is, however, recommended for your bug reporting. Also, another form is available, where the report is free form and according to a Jinja2 template of yours, and one that is included in Nuitka. The same information as used to produce the XML file is accessible. However, right now, this is not yet documented, but we plan to add a table with the data. For a reader of the source code that is familiar with Jinja2, however, it will be easy to do it now already. If you have a template, you can use it like this ``--report-template=your_template.rst.j2:your_report.rst`` and of course, the usage of restructured text, is only an example. You can use Markdown, your own XML, or whatever you see fit. Nuitka will just expand the template with the compilation report data. Currently, the following reports are included in Nuitka. You just use the name as a filename, and Nuitka will pick that one instead. +---------------+--------------+--------------------------------------------------------+ | Report Name | Status | Purpose | +===============+==============+========================================================+ | LicenseReport | experimental | Distributions used in a compilation with license texts | +---------------+--------------+--------------------------------------------------------+ .. note:: The community can and should contribute more report types and help enhancing the existing ones for good looks. ************* Performance ************* This chapter gives an overview, of what to currently expect in terms of performance from Nuitka. It's a work in progress and is updated as we go. The current focus for performance measurements is Python 2.7, but 3.x is going to follow later. pystone results =============== The results are the top value from this kind of output, running pystone 1000 times and taking the minimal value. The idea is that the fastest run is most meaningful, and eliminates usage spikes. .. code:: bash echo "Uncompiled Python2" for i in {1..100}; do BENCH=1 python2 tests/benchmarks/pystone.py ; done | sort -rn | head -n 1 python2 -m nuitka --lto=yes --pgo tests/benchmarks/pystone.py echo "Compiled Python2" for i in {1..100}; do BENCH=1 ./pystone.bin ; done | sort -n | head -rn 1 echo "Uncompiled Python3" for i in {1..100}; do BENCH=1 python3 tests/benchmarks/pystone3.py ; done | sort -rn | head -n 1 python3 -m nuitka --lto=yes --pgo tests/benchmarks/pystone3.py echo "Compiled Python3" for i in {1..100}; do BENCH=1 ./pystone3.bin ; done | sort -rn | head -n 1 +-------------------+-------------------+----------------------+---------------------+ | Python | Uncompiled | Compiled LTO | Compiled PGO | +===================+===================+======================+=====================+ | Debian Python 2.7 | 137497.87 (1.000) | 460995.20 (3.353) | 503681.91 (3.663) | +-------------------+-------------------+----------------------+---------------------+ | Nuitka Python 2.7 | 144074.78 (1.048) | 479271.51 (3.486) | 511247.44 (3.718) | +-------------------+-------------------+----------------------+---------------------+ Report issues or bugs ===================== Should you encounter any issues, bugs, or ideas, please visit the `Nuitka bug tracker `__ and report them. Best practices for reporting bugs: - Please always include the following information in your report, for the underlying Python version. You can easily copy&paste this into your report. It does contain more information than you think. Do not write something manually. You may always add, of course, .. code:: bash python -m nuitka --version - Try to make your example minimal. That is, try to remove code that does not contribute to the issue as much as possible. Ideally, come up with a small reproducing program that illustrates the issue, using ``print`` with different results when the program runs compiled or native. - If the problem occurs spuriously (i.e. not each time), try to set the environment variable ``PYTHONHASHSEED`` to ``0``, disabling hash randomization. If that makes the problem go away, try increasing in steps of 1 to a hash seed value that makes it happen every time, include it in your report. - Do not include the created code in your report. Given proper input, it's redundant, and it's not likely that I will look at it without the ability to change the Python or Nuitka source and re-run it. - Do not send screenshots of text, that is bad and lazy. Instead, capture text outputs from the console. *************************** Unsupported functionality *************************** The ``co_code`` attribute of code objects ========================================= The code objects are empty for native compiled functions. There is no bytecode with Nuitka's compiled function objects, so there is no way to provide it. PDB === There is no tracing of compiled functions to attach a debugger to. ================================================ FILE: SECURITY.md ================================================ # Security Policy ## Supported Versions There are no LTS supported versions of Nuitka, but mostly the stable version is hot-fixed, and would be for security issues. If possible, git rebases would be done just as they are for corruption bugs, which would then allow to use these, but usually newer Nuitka is the expected to use version, with main always being as bug free as possible. | Version | Supported | | ------- | ------------------ | | main | :white_check_mark: | | develop | :white_check_mark: | ## Reporting a Vulnerability When you email me at `kay.hayen@gmail.com` with a well defined report, I guarantee a reaction within 72h, and correction as soon as possible. Generally private emails are not acceptable for questions, there I would point to GitHub, but for sensitive information only, it's great. ================================================ FILE: Standard-Plugins-Documentation.rst ================================================ ####################################### Nuitka Standard Plugins Documentation ####################################### .. |ups| replace:: user plugins .. |sps| replace:: standard plugins .. |ops| replace:: optional standard plugins **************************** Background: Nuitka Plugins **************************** Plugins are a feature to modify the way how Nuitka compiles Python programs in extremely flexible ways. Plugins can automatically include data files and additional shared libraries, import modules which are not detectable by source code analysis, modify or extend the to-be-compiled source code, gather statistics, change Nuitka's parameter defaults and much more. Any number of plugins may be used in each compilation. Plugins come in two variants: **standard** plugins and **user** plugins. User plugins are not part of the Nuitka package: they must be provided otherwise. To use them in a compilation, Nuitka must be able to find them using their path / filename. If |ups| are specified, Nuitka will activate them **before** it activates any of its standard plugins. Standard plugins are part of the Nuitka package and thus always available. Nuitka also differentiates between "mandatory" and "optional" |sps|. **Mandatory** |sps| are always enabled and "invisible" to the user. Their behaviour cannot be influenced other than by modifying them. **Optional** |sps| must be enabled via the command line parameter ``--enable-plugin=name``, with an identifying string ``name``. Even when not enabled however, |ops| can detect, whether their use might have been "forgotten" and issue an appropriate warning. Where appropriate, the behaviour of optional |sps| (like with |ups|) can be controlled via *options* (see "Using Plugin Options"). ******************* A Word of Caution ******************* Almost all |ops| are relevant for standalone mode only. Specifying all the right plugins is up to the user and critical for success: For example, if you are using package *numpy* and forget to activate that plugin, then your compile will - end with no error, but a warning about missing numpy support, - not generate a working binary. Also: - |ups| are able to programmatically enable |ops|, the **reverse is not possible**. The user must know the requirements of his script and specify all appropriate |ops|, including any required *options* (see below). - There is currently no way to automatically react to interdependencies. For example, when compiling a script using the *tensorflow* package in standalone mode, you must enable (at least) **both**, the ``tensorflow`` **and** the ``numpy`` plugin. - Like every compiler, Nuitka cannot always decide, whether a script will **actually execute** an *import* statement. This knowledge must be provided by you, e.g. with PGO information that is going to be supported. *********************************** List of Optional Standard Plugins *********************************** Create a list of available optional |sps| giving their identifier together with a short description via ``--plugin-list``: The following optional standard plugins are available in Nuitka: .. code:: anti-bloat Patch stupid imports out of widely used library modules source codes. data-files data-hiding Commercial: Hide program constant Python data from offline inspection of created binaries. datafile-inclusion-ng Commercial: Load file trusted file contents at compile time. dill-compat enum-compat ethereum Commercial: Required for ethereum packages in standalone mode eventlet Support for including 'eventlet' dependencies and its need for 'dns' package monkey patching gevent Required by the gevent package gi Support for GI dependencies glfw Required for glfw in standalone mode implicit-imports multiprocessing Required by Python's multiprocessing module numpy Required for numpy, scipy, pandas, matplotlib, etc. pbr-compat pkg-resources Resolve version numbers at compile time. pmw-freezer Required by the Pmw package pylint-warnings Support PyLint / PyDev linting source markers pyqt5 Required by the PyQt5 package. pyside2 Required by the PySide2 package. pyside6 Required by the PySide6 package for standalone mode. pyzmq Required for pyzmq in standalone mode tensorflow Required by the tensorflow package tk-inter Required by Python's Tk modules torch Required by the torch / torchvision packages traceback-encryption Commercial: Encrypt tracebacks (de-Jong-Stacks). windows-service Commercial: Create Windows Service files .. note:: This list is continuously growing and most likely out of date. ***************************************** Optional Standard Plugins Documentation ***************************************** dill-compat =========== - Required by the *dill* module. Dill extends Python's pickle module for serializing and de-serializing objects. - Options: none. eventlet ======== - Required by the *eventlet* package. Eventlet is a concurrent networking library. - Options: none. gevent ====== - Required by the *gevent* package. Gevent is a coroutine-based Python networking library that uses greenlet to provide a high-level synchronous API. - Options: none. pmw-freezer =========== - Required by the *Pmw* package. Pmw is a toolkit for building high-level compound widgets. - Options: none. pylint-warnings =============== - Support *PyLint* / *PyDev* linting source markers. Python static code analysis tools which help enforcing a coding standard. - Options: none pyside2, pyside6, pyqt5, pyqt6 ============================== - Required by the *PySide* and *PyQt* and GUI packages, only one can be activated at a time. - Options: With ``--include-qt-plugins`` you can select which Qt plugins to include. By default a relatively small set, called ``sensible`` that is defined in the code is include, but you can add more, and even ``all``, which will add a terrible amount of dependencies though. But without the proper Qt plugins, functionality of Qt might be broken, crashes can occur, or appearance can be inferior. - These plugins also inhibit other GUI frameworks from being included in standalone distributions. tk-inter ======== - Required by Python's Tk modules. - Options: Can override the automatic detection of Tcl and Tk directories with ``--tk-library-dir`` and ``--tcl-library-dir`` but that should not be needed. ================================================ FILE: UserPlugin-Creation.rst ================================================ ############################# How To Create a User Plugin ############################# ********************************************** Background: Nuitka Standard and User Plugins ********************************************** User plugins are technically built and structured in the same way as Nuitka's own *standard* plugins are. There also is no difference with respect to what they can do. Both types are invoked via parameters in Nuitka's command line. The difference is the invocation format: - A standard plugin is invoked by ``--enable-plugin=``. The string ```` is a unique identifier by which Nuitka identifies it. As soon as Nuitka has found the corresponding plugin, it will call its initialization method. Nuitka also has some standard plugins which are always activated. A standard plugin is represented by a Python script living in ``nuitka/plugins/standard``. Standard plugins also internally have an object which can issue warnings when it encounters situations looking like it is required. - A user plugin is invoked by ``--user-plugin=``. Nuitka will import the script and call its initialization method just like for a standard plugin. The plugin must have a non-empty string specified in its variable ``plugin_name``. It must also not equal one of the de-activated standard plugin strings. Best practice is filling it with the filename, e.g. ``plugin_name == __file__``, because this allows providing it with options. User plugins are always activated once successfully loaded. They therefore have no mechanism to warn if not being used. ********************* Example User Plugin ********************* This is a simple demo user plugin. It will display source code lines of the main program if they contain calls to the ``math`` module, if an option named "trace" is active: .. code:: python import os import sys from nuitka import Options from nuitka.plugins.PluginBase import NuitkaPluginBase class NuitkaPluginMine(NuitkaPluginBase): # Derive from filename, but can and should also be explicit. plugin_name = __name__.split(".")[-1] def __init__(self, trace_my_plugin): # demo only: extract and display my options list # check whether some specific option is set self.check = trace_my_plugin self.info(" 'trace' is set to '%s'" % self.check) # do more init work here ... @classmethod def addPluginCommandLineOptions(cls, group): group.add_option( "--trace-my-plugin", action="store_true", dest="trace_my_plugin", default=False, help="This is show in help output." ) def onModuleSourceCode(self, module_name, source_filename, source_code): # if this is the main script and tracing should be done ... if module_name == "__main__" and self.check: self.info("") self.info(" Calls to 'math' module:") for i, l in enumerate(source_code.splitlines()): if "math." in l: self.info(" %i: %s" % (i+1, l)) self.info("") return source_code Sample invocation line and output: .. code:: bash python -m nuitka --standalone --user-plugin=user_plugin.py=trace script.py .. code:: Nuitka:INFO: 'user_plugin.py' options: ['trace'] Nuitka:INFO: 'trace' is set to True Nuitka:INFO:User plugin 'user_plugin.py' loaded. Nuitka:INFO: Nuitka:INFO: Calls to 'math' module: Nuitka:INFO: 125: print(math.sqrt(2)) Nuitka:INFO: ************************* Nuitka Options Overview ************************* About 60 methods are available to access option information for the current Nuitka execution. Import the ``Options`` module (``from nuitka import Options``) and use one of the following. Please note that ``str`` results may return ``None``. Except very few, the methods have no argument. +--------------------------------------+-----------------------------------------------------------------------------------+ | **Method** | **Description** | +======================================+===================================================================================+ | assumeYesForDownloads | *bool* = ``--assume-yes-for-downloads`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isExperimental | *bool*, check for items of ``--experimental=`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | getFileReferenceMode | *str*, one of ``runtime``, ``original`` or ``frozen`` (``--file-reference-mode``) | +--------------------------------------+-----------------------------------------------------------------------------------+ | getWindowsIconPaths | *list*, values of Windows icon options | +--------------------------------------+-----------------------------------------------------------------------------------+ | getLinuxIconPaths | *list*, values of Linux icon options | +--------------------------------------+-----------------------------------------------------------------------------------+ | getMacOSIconPaths | *list*, values of macOS icon options | +--------------------------------------+-----------------------------------------------------------------------------------+ | getJobLimit | *int*, value of ``--jobs`` / ``-j`` or number of CPU kernels | +--------------------------------------+-----------------------------------------------------------------------------------+ | getMainArgs | *tuple*, arguments following the optional arguments | +--------------------------------------+-----------------------------------------------------------------------------------+ | getMsvcVersion | *str*, value of ``--msvc`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | getMustIncludeModules | *list*, items of ``--include-module=`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | getMustIncludePackages | *list*, items of ``--include-package=`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | getOutputDir | *str*, value of ``--output-dir`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | getOutputFilename | *str*, value of ``-o`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | getOutputPath(path) | *str*, os.path.join(getOutputDir(), path) | +--------------------------------------+-----------------------------------------------------------------------------------+ | getPluginsDisabled | *tuple*, items of ``--disable-plugin=`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | getPluginsEnabled | *tuple*, enabled plugins (including user plugins) | +--------------------------------------+-----------------------------------------------------------------------------------+ | getPluginOptions(plugin_name) | *list*, options for specified plugin | +--------------------------------------+-----------------------------------------------------------------------------------+ | getPositionalArgs | *tuple*, command line positional arguments | +--------------------------------------+-----------------------------------------------------------------------------------+ | getPythonFlags | *list*, value of ``--python-flag`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | getPythonPathForScons | *str*, value of ``--python-for-scons`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | getShallFollowExtra | *list*, items of ``--include-plugin-directory=`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | getShallFollowExtraFilePatterns | *list*, items of ``--include-plugin-files=`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | getShallFollowInNoCase | *list*, items of ``--nofollow-import-to=`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | getShallFollowModules | *list*, items of ``--follow-import-to=`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | getUserPlugins | *tuple*, items of ``--user-plugin=`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isAllowedToReexecute | *bool* = **not** ``--must-not-re-execute`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isClang | *bool* = ``--clang`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isDebug | *bool* = ``--debug`` or ``--debugger`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isExperimental("feature") | *bool* = ``--experimental=feature`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isFullCompat | *bool* = ``--full-compat`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isLto | *bool* = ``--lto`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isMingw64 | *bool* = ``--mingw64`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isProfile | *bool* = ``--profile`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallUsePythonDebug | *bool* = ``--python-debug`` or ``sys.flags.debug`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isRemoveBuildDir | *bool* = ``--remove-output`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isShowInclusion | *bool* = ``--show-modules`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isShowMemory | *bool* = ``--show-memory`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isShowProgress | *bool* = ``--show-progress`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isShowScons | *bool* = ``--show-scons`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isStandaloneMode | *bool* = ``--standalone`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isUnstripped | *bool* = ``--unstripped`` or ``--profile`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | isVerbose | *bool* = ``--verbose`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallCreatePyiFile | *bool* = **not** ``--no-pyi-file`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallDetectMissingPlugins | *bool* = **not** ``--plugin-no-detection`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallDisableConsoleWindow | *bool* = ``--win-disable-console`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallExecuteImmediately | *bool* = ``--run`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallExplainImports | *bool* = ``--explain-imports`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallFollowAllImports | *bool* = ``--follow-imports`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallFollowNoImports | *bool* = ``--nofollow-imports`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallListPlugins | *bool* = ``--plugin-list`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallMakeModule | *bool* = ``--module`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallNotDoExecCCompilerCall | *bool* = ``--generate-c-only`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallNotStoreDependsExeCachedResults | *bool* = ``--disable-dll-dependency-cache`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallNotUseDependsExeCachedResults | *bool* = ``--disable-dll-dependency-cache`` or | | | ``--force-dll-dependency-cache-update`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallOnlyExecCCompilerCall | *bool* = ``--recompile-c-only`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallRunInDebugger | *bool* = ``--debug`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallTraceExecution | *bool* = ``--trace-execution`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallWarnImplicitRaises | *bool* = ``--warn-implicit-exceptions`` | +--------------------------------------+-----------------------------------------------------------------------------------+ | shallWarnUnusualCode | *bool* = ``--warn-unusual-code`` | +--------------------------------------+-----------------------------------------------------------------------------------+ ================================================ FILE: Using-Plugin-Options.rst ================================================ ########################### How To Use Plugin Options ########################### **************************** Background: Nuitka Plugins **************************** Plugins are a feature to modify the way how Nuitka compiles Python programs in extremely flexible ways. Plugins can automatically include data files and additional shared libraries, import modules not detectable by source code examination, modify or extend the to-be-compiled source code, gather statistics, change Nuitka's parameter defaults and much more. Any number of plugins may be used in each compilation. A **whole new dimension of flexibility** can be added by using **options** to control a plugin's functioning. ********************** Option Specification ********************** **Standard plugins** are activated by the command line parameter ``--enable-plugin=``. The parameter ``plugin_name`` must equal the plugin's variable with the same name, so that Nuitka can identify it. **User plugins** are activated by the command line parameter ``--user-plugin=``, where the parameter is a filename (-path) of a Python script implementing the plugin protocol, i.e. it must be a class that inherits ``nuitka.plugins.PluginBase.UserPluginBase`` just like every Nuitka plugin. Plugin options can be added by overloading the method .. code:: python @classmethod def addPluginCommandLineOptions(cls, group): ... # add options to "group" here. Here you extend the optparser group with any amount of options you choose. Be careful with the ``dest`` names, try to make names that will not collide with other plugins, as we have no per plugin namespace here. ********* Example ********* To see a working example for a user plugin with options, consult `this `__ document. ================================================ FILE: bin/autoformat-nuitka-source ================================================ #!/usr/bin/env python3 # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for autoformat tool. """ import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start from nuitka.tools.quality.auto_format.__main__ import main main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/check-nuitka-with-codespell ================================================ #!/usr/bin/env python3 # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for codespell checker tool. """ import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start from nuitka.tools.quality.codespell.__main__ import main main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/check-nuitka-with-pylint ================================================ #!/usr/bin/env python3 # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for pylint checker tool. """ import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start from nuitka.tools.quality.pylint.__main__ import main main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/check-nuitka-with-restlint ================================================ #!/usr/bin/env python3 # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for rest lint checker tool. """ import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start from nuitka.tools.quality.restlint.__main__ import main main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/check-nuitka-with-yamllint ================================================ #!/usr/bin/env python3 # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for yamllint checker tool. """ import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start from nuitka.tools.quality.yamllint.__main__ import main main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/check-reference-counts ================================================ #!/usr/bin/env python # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for reference count checking tool. """ import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start from nuitka.tools.testing.check_reference_counts.__main__ import main main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/compare_with_cpython ================================================ #!/usr/bin/env python # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for output comparison tool. """ import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start from nuitka.tools.testing.compare_with_cpython.__main__ import main main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/compare_with_xml ================================================ #!/usr/bin/env python # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Tool to compare XML outputs of two Nuitka versions. """ import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start import difflib from nuitka.tools.testing.Common import my_print from nuitka.utils.Execution import executeProcess nuitka1 = sys.argv[1] nuitka2 = sys.argv[2] filename = sys.argv[3] my_print( """\ Comparing output of '{filename}' using '{nuitka1}' <-> '{nuitka2}' ...""".format( filename=filename, nuitka1=nuitka1, nuitka2=nuitka2 ) ) extra_options = os.getenv("NUITKA_EXTRA_OPTIONS", "") nuitka1_cmd = "{nuitka1} --xml {filename}".format(nuitka1=nuitka1, filename=filename) nuitka2_cmd = "{nuitka2} --xml {filename}".format(nuitka2=nuitka2, filename=filename) stdout_nuitka1, stderr_nuitka1, exit_nuitka1 = executeProcess(nuitka1_cmd, shell=True) stdout_nuitka2, stderr_nuitka2, exit_nuitka2 = executeProcess(nuitka2_cmd, shell=True) def makeDiffable(output): result = [] for line in output.split(b"\n"): line = str(line) result.append(line) return result def compareOutput(kind, out1, out2): diff = difflib.unified_diff( makeDiffable(out1), makeDiffable(out2), "{program} ({detail})".format(program="nuitka1 " + filename, detail=kind), "{program} ({detail})".format(program="nuitka2 " + filename, detail=kind), None, None, n=3, ) result = list(diff) if result: for line in result: my_print(line, end="\n" if not line.startswith("---") else "") return 1 else: return 0 exit_code_stdout = compareOutput("stdout", stdout_nuitka1, stdout_nuitka2) exit_code_return = exit_nuitka1 != exit_nuitka2 if exit_code_return: my_print( """\ Exit codes {exit_nuitka1:d} ({nuitka1}) != {exit_nuitka2:d} ({nuitka2})""".format( exit_nuitka1=exit_nuitka1, nuitka1=nuitka1, exit_nuitka2=exit_nuitka2, nuitka2=nuitka2, ) ) exit_code = exit_code_stdout or exit_code_return if exit_code: sys.exit("Error, outputs differed.") my_print("OK, same outputs.") # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/find_sxs_modules ================================================ #!/usr/bin/env python # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for reporting SxS using extension modules. """ import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start from nuitka.tools.testing.find_sxs_modules.__main__ import main main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/generate-specialized-c-code ================================================ #!/usr/bin/env python3 # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for static C code generation tool. """ import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start from nuitka.tools.specialize.SpecializeC import main main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/generate-specialized-python-code ================================================ #!/usr/bin/env python3 # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for static Python code generation tool. """ import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start from nuitka.tools.specialize.SpecializePython import main main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/measure-construct-performance ================================================ #!/usr/bin/env python # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for construct performance tool. """ import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start from nuitka.tools.testing.measure_construct_performance.__main__ import main main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/nuitka ================================================ #!/usr/bin/env python # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for Nuitka the compiler itself. """ # Import as little as possible initially, because we might be re-executing # soon. import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start import nuitka.__main__ # false alarm, pylint: disable=I0021,no-name-in-module # Remove the nuitka package directory again, it might contain other stuff that we # do not want added automatically. del sys.path[0] # The bin folder of the runner can't be that helpful, but got added automatically, # so attempt to remove it. sys.path = [ path_element for path_element in sys.path if os.path.dirname(os.path.abspath(__file__)) != path_element ] # Now execute Nuitka in a clean environment. nuitka.__main__.main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/nuitka-run ================================================ #!/usr/bin/env python # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for Nuitka the compiler itself. """ # Import as little as possible initially, because we might be re-executing # soon. import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start import nuitka.__main__ # false alarm, pylint: disable=I0021,no-name-in-module # Remove the nuitka package directory again, it might contain other stuff that we # do not want added automatically. del sys.path[0] # The bin folder of the runner can't be that helpful, but got added automatically, # so attempt to remove it. sys.path = [ path_element for path_element in sys.path if os.path.dirname(os.path.abspath(__file__)) != path_element ] # Now execute Nuitka in a clean environment. nuitka.__main__.main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/nuitka-watch ================================================ #!/usr/bin/env python3 # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for Nuitka watch tool. For the "Nuitka-Watch" repository, this is intended to scan it and execute test cases for detecting PyPI updates that cause regressions, or changes in Nuitka that do. """ # Import as little as possible initially, because we might be re-executing # soon. import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start from nuitka.tools.watch.__main__ import main main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/nuitka3 ================================================ #!/usr/bin/env python3 # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for Nuitka the compiler itself. """ # Import as little as possible initially, because we might be re-executing # soon. import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start import nuitka.__main__ nuitka.__main__.main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/nuitka3-run ================================================ #!/usr/bin/env python3 # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for Nuitka the compiler itself. """ # Import as little as possible initially, because we might be re-executing # soon. import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start import nuitka.__main__ nuitka.__main__.main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: bin/run-inside-nuitka-container ================================================ #!/usr/bin/env python # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file """ Launcher for running a script inside a container """ import os import sys # Unchanged, running from checkout, use the parent directory, the nuitka # package ought to be there. sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) # isort:start from nuitka.tools.podman.__main__ import main main() # Part of "Nuitka", an optimizing Python compiler that is compatible and # integrates with CPython, but also works on its own. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ================================================ FILE: debian/README.source ================================================ The source used to build Nuitka has modifications compared to normal releases: - The benchmark programs are not included. They are not really useful and can be used from other sources in a better way. - The inline copy of scons and appdirs are removed. It is not needed as the dependency on scons leads to an installed scons in the system. The original package uses the installed scons in preference, so the inline copy would (at best) only be dead code. ================================================ FILE: debian/changelog ================================================ nuitka (2.2~rc4+ds-1) unstable; urgency=medium * New upstream pre-release. -- Kay Hayen Sat, 06 Apr 2024 15:37:16 +0200 nuitka (2.1.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 06 Apr 2024 13:02:40 +0200 nuitka (2.1.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 27 Mar 2024 01:02:54 +0100 nuitka (2.1.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 21 Mar 2024 11:07:28 +0100 nuitka (2.1.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 14 Mar 2024 10:05:02 +0100 nuitka (2.1.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 11 Mar 2024 18:02:57 +0100 nuitka (2.1+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Mon, 04 Mar 2024 10:14:00 +0100 nuitka (2.0.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 01 Mar 2024 13:27:15 +0100 nuitka (2.0.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 26 Feb 2024 16:39:28 +0100 nuitka (2.0.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 25 Feb 2024 11:23:55 +0100 nuitka (2.0.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 18 Feb 2024 10:37:35 +0100 nuitka (2.0.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 09 Feb 2024 12:18:45 +0100 nuitka (2.0.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 02 Feb 2024 16:21:39 +0100 nuitka (2.0+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Fri, 26 Jan 2024 12:44:50 +0100 nuitka (1.9.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 07 Jan 2024 06:26:44 +0100 nuitka (1.9.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 29 Dec 2023 14:52:54 +0100 nuitka (1.9.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 14 Dec 2023 13:50:11 +0100 nuitka (1.9.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 06 Dec 2023 21:58:31 +0100 nuitka (1.9.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 01 Dec 2023 14:35:43 +0100 nuitka (1.9.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 27 Nov 2023 04:42:21 +0100 nuitka (1.9.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 24 Nov 2023 12:45:23 +0100 nuitka (1.9+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Tue, 21 Nov 2023 07:05:50 +0100 nuitka (1.8.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 11 Nov 2023 12:02:30 +0100 nuitka (1.8.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 27 Oct 2023 12:46:19 +0200 nuitka (1.8.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 08 Oct 2023 12:01:03 +0200 nuitka (1.8.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 28 Sep 2023 15:30:04 +0200 nuitka (1.8.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 19 Sep 2023 05:39:14 +0200 nuitka (1.8.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 10 Sep 2023 11:03:41 +0200 nuitka (1.8+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Thu, 31 Aug 2023 01:32:29 +0200 nuitka (1.7.10+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 11 Aug 2023 12:06:42 +0200 nuitka (1.7.9+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 03 Aug 2023 19:53:32 +0200 nuitka (1.7.8+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 01 Aug 2023 13:48:24 +0200 nuitka (1.7.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 27 Jul 2023 11:57:01 +0200 nuitka (1.7.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 22 Jul 2023 11:47:47 +0200 nuitka (1.7.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 14 Jul 2023 04:09:33 +0200 nuitka (1.7.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 11 Jul 2023 14:54:05 +0200 nuitka (1.7.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 09 Jul 2023 18:53:35 +0200 nuitka (1.7.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 07 Jul 2023 09:40:11 +0200 nuitka (1.7.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 05 Jul 2023 16:29:43 +0200 nuitka (1.7+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Mon, 03 Jul 2023 10:57:55 +0200 nuitka (1.6.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 22 Jun 2023 04:01:33 +0200 nuitka (1.6.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 19 Jun 2023 15:31:28 +0200 nuitka (1.6.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 10 Jun 2023 09:34:49 +0200 nuitka (1.6.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 09 Jun 2023 12:00:01 +0200 nuitka (1.6.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 05 Jun 2023 11:35:18 +0200 nuitka (1.6+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sun, 28 May 2023 21:05:53 +0200 nuitka (1.5.8+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 15 May 2023 10:19:45 +0200 nuitka (1.5.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 24 Apr 2023 16:45:23 +0200 nuitka (1.5.8+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 15 May 2023 10:19:45 +0200 nuitka (1.5.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 24 Apr 2023 16:45:23 +0200 nuitka (1.5.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 11 Apr 2023 10:09:53 +0200 nuitka (1.5.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 04 Apr 2023 08:43:30 +0200 nuitka (1.5.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 26 Mar 2023 10:24:29 +0200 nuitka (1.5.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 16 Mar 2023 20:51:55 +0100 nuitka (1.5.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 16 Mar 2023 13:44:56 +0100 nuitka (1.5.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 13 Mar 2023 15:52:36 +0100 nuitka (1.5+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sat, 11 Mar 2023 15:55:37 +0100 nuitka (1.4.8+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 21 Feb 2023 09:18:59 +0100 nuitka (1.4.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 13 Feb 2023 14:38:57 +0100 nuitka (1.4.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 12 Feb 2023 19:11:46 +0100 nuitka (1.4.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 10 Feb 2023 07:36:27 +0100 nuitka (1.4.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 07 Feb 2023 19:03:45 +0100 nuitka (1.4.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 04 Feb 2023 07:24:47 +0100 nuitka (1.4.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 31 Jan 2023 07:17:15 +0100 nuitka (1.4.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 29 Jan 2023 23:21:23 +0100 nuitka (1.4+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Thu, 26 Jan 2023 14:56:48 +0100 nuitka (1.3.8+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 16 Jan 2023 11:05:41 +0100 nuitka (1.3.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 09 Jan 2023 16:51:14 +0100 nuitka (1.3.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 06 Jan 2023 09:10:31 +0100 nuitka (1.3.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 01 Jan 2023 09:39:39 +0100 nuitka (1.3.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 28 Dec 2022 21:20:25 +0100 nuitka (1.3.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 26 Dec 2022 10:39:49 +0100 nuitka (1.3.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 23 Dec 2022 08:19:05 +0100 nuitka (1.3.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 21 Dec 2022 19:14:46 +0100 nuitka (1.3+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Wed, 21 Dec 2022 13:14:49 +0100 nuitka (1.2.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 13 Dec 2022 11:16:23 +0100 nuitka (1.2.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 08 Dec 2022 07:18:44 +0100 nuitka (1.2.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 07 Dec 2022 15:57:44 +0100 nuitka (1.2.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 03 Dec 2022 13:45:31 +0100 nuitka (1.2.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 26 Nov 2022 11:07:57 +0100 nuitka (1.2.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 19 Nov 2022 17:05:08 +0100 nuitka (1.2.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 16 Nov 2022 17:15:00 +0100 nuitka (1.2+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Tue, 08 Nov 2022 09:42:28 +0100 nuitka (1.1.7+ds-1) unstable; urgency=medium * New upstream hotfix release. * Handle Debian sid change in release number (Closes: #1022400) -- Kay Hayen Wed, 26 Oct 2022 14:46:14 +0200 nuitka (1.1.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 19 Oct 2022 18:36:12 +0200 nuitka (1.1.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 14 Oct 2022 08:19:39 +0200 nuitka (1.1.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 14 Oct 2022 08:19:33 +0200 nuitka (1.1.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 08 Oct 2022 17:40:59 +0200 nuitka (1.1.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 04 Oct 2022 14:39:39 +0200 nuitka (1.1.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 02 Oct 2022 11:10:07 +0200 nuitka (1.1+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sun, 25 Sep 2022 18:58:01 +0200 nuitka (1.0.8+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 19 Sep 2022 08:18:45 +0200 nuitka (1.0.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 11 Sep 2022 10:34:06 +0200 nuitka (1.0.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 23 Aug 2022 20:07:27 +0200 nuitka (1.0.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 21 Aug 2022 08:24:28 +0200 nuitka (1.0.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 13 Aug 2022 16:13:29 +0200 nuitka (1.0.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 10 Aug 2022 13:16:19 +0200 nuitka (1.0.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 08 Aug 2022 08:13:46 +0200 nuitka (1.0.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 04 Aug 2022 16:55:17 +0200 nuitka (1.0+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sat, 30 Jul 2022 16:16:40 +0200 nuitka (0.9.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 17 Jul 2022 18:40:22 +0200 nuitka (0.9.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 15 Jul 2022 13:59:28 +0200 nuitka (0.9.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 07 Jul 2022 09:24:53 +0200 nuitka (0.9.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 02 Jul 2022 18:49:29 +0200 nuitka (0.9.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 30 Jun 2022 08:40:14 +0200 nuitka (0.9.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 26 Jun 2022 10:41:06 +0200 nuitka (0.9+ds-1) unstable; urgency=medium * New upstream release. * Python 3.10 is now compatible again. (Closes: #1006051) * Solved CVE-2022-2054 (Closes: #1012762) -- Kay Hayen Thu, 23 Jun 2022 08:36:25 +0200 nuitka (0.8.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 07 Jun 2022 17:21:39 +0200 nuitka (0.8.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 28 May 2022 14:59:01 +0200 nuitka (0.8.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 26 May 2022 08:23:28 +0200 nuitka (0.8.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 23 May 2022 08:31:51 +0200 nuitka (0.8+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Thu, 19 May 2022 14:24:06 +0200 nuitka (0.7.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 01 Apr 2022 12:01:36 +0200 nuitka (0.7.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 19 Mar 2022 13:44:59 +0100 nuitka (0.7.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 14 Mar 2022 18:55:11 +0100 nuitka (0.7.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 12 Mar 2022 13:50:50 +0100 nuitka (0.7.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 27 Feb 2022 13:58:34 +0100 nuitka (0.7.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 26 Feb 2022 16:54:03 +0100 nuitka (0.7.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 24 Feb 2022 13:22:40 +0100 nuitka (0.7+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sun, 20 Feb 2022 09:09:50 +0100 nuitka (0.6.19.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 11 Feb 2022 14:37:34 +0100 nuitka (0.6.19.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 03 Feb 2022 10:30:39 +0100 nuitka (0.6.19.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 01 Feb 2022 18:53:20 +0100 nuitka (0.6.19.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 19 Jan 2022 10:02:04 +0100 nuitka (0.6.19.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 16 Jan 2022 11:32:51 +0100 nuitka (0.6.19.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 14 Jan 2022 11:03:16 +0100 nuitka (0.6.19.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 11 Jan 2022 07:59:24 +0100 nuitka (0.6.19+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sun, 09 Jan 2022 13:14:29 +0100 nuitka (0.6.18.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 29 Dec 2021 19:42:43 +0100 nuitka (0.6.18.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 20 Dec 2021 13:41:00 +0100 nuitka (0.6.18.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 16 Dec 2021 08:31:41 +0100 nuitka (0.6.18.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 10 Dec 2021 17:49:19 +0100 nuitka (0.6.18.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 09 Dec 2021 14:52:56 +0100 nuitka (0.6.18.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 04 Dec 2021 18:39:19 +0100 nuitka (0.6.18+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Thu, 02 Dec 2021 17:33:56 +0100 nuitka (0.6.17.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 15 Nov 2021 14:33:27 +0100 nuitka (0.6.17.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 08 Nov 2021 14:07:11 +0100 nuitka (0.6.17.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 28 Oct 2021 11:52:02 +0200 nuitka (0.6.17.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 21 Oct 2021 13:03:34 +0200 nuitka (0.6.17.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 14 Oct 2021 10:32:17 +0200 nuitka (0.6.17.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 05 Oct 2021 17:21:29 +0200 nuitka (0.6.17.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 29 Sep 2021 12:28:39 +0200 nuitka (0.6.17+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Mon, 27 Sep 2021 13:38:42 +0200 nuitka (0.6.16.5+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 06 Sep 2021 10:46:40 +0200 nuitka (0.6.16.4+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 25 Aug 2021 11:51:44 +0200 nuitka (0.6.16.3+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 07 Aug 2021 18:14:58 +0200 nuitka (0.6.16.2+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 02 Jul 2021 10:40:08 +0200 nuitka (0.6.16.1+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 25 Jun 2021 16:45:43 +0200 nuitka (0.6.16+ds-1) experimental; urgency=medium * New upstream release. -- Kay Hayen Thu, 24 Jun 2021 11:52:37 +0200 nuitka (0.6.15.3+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 06 Jun 2021 12:18:06 +0200 nuitka (0.6.15.2+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 03 Jun 2021 11:41:07 +0200 nuitka (0.6.15.1+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 31 May 2021 17:12:04 +0200 nuitka (0.6.15+ds-1) experimental; urgency=medium * New upstream release. -- Kay Hayen Mon, 24 May 2021 12:26:59 +0200 nuitka (0.6.14.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 10 May 2021 16:25:14 +0200 nuitka (0.6.14.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 03 May 2021 07:57:04 +0200 nuitka (0.6.14.5+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 22 Apr 2021 08:51:05 +0200 nuitka (0.6.14.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 18 Apr 2021 16:13:42 +0200 nuitka (0.6.14.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 18 Apr 2021 10:29:07 +0200 nuitka (0.6.14.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 17 Apr 2021 11:03:23 +0200 nuitka (0.6.14.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 16 Apr 2021 07:49:30 +0200 nuitka (0.6.14+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Thu, 15 Apr 2021 11:09:55 +0200 nuitka (0.6.13.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 04 Apr 2021 11:11:56 +0200 nuitka (0.6.13.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 27 Mar 2021 19:44:51 +0100 nuitka (0.6.13.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 26 Mar 2021 14:28:02 +0100 nuitka (0.6.13+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Wed, 17 Mar 2021 08:58:23 +0100 nuitka (0.6.12.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 11 Mar 2021 12:16:01 +0100 nuitka (0.6.12.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 21 Feb 2021 06:04:51 +0100 nuitka (0.6.12.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 14 Feb 2021 14:25:06 +0100 nuitka (0.6.12.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 10 Feb 2021 00:23:11 +0100 nuitka (0.6.12+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Tue, 09 Feb 2021 11:08:35 +0100 nuitka (0.6.11.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 07 Feb 2021 19:59:48 +0100 nuitka (0.6.11.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 01 Feb 2021 12:17:21 +0100 nuitka (0.6.11.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 27 Jan 2021 17:09:48 +0100 nuitka (0.6.11.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 26 Jan 2021 11:16:07 +0100 nuitka (0.6.11.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 25 Jan 2021 20:14:39 +0100 nuitka (0.6.11.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 24 Jan 2021 17:55:22 +0100 nuitka (0.6.11+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sat, 23 Jan 2021 10:01:54 +0100 nuitka (0.6.10.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 07 Jan 2021 11:04:59 +0100 nuitka (0.6.10.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 29 Dec 2020 16:17:44 +0100 nuitka (0.6.10.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 24 Dec 2020 16:30:17 +0100 nuitka (0.6.10.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 20 Dec 2020 10:56:00 +0100 nuitka (0.6.10.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 13 Dec 2020 19:47:53 +0100 nuitka (0.6.10+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Mon, 07 Dec 2020 12:44:03 +0100 nuitka (0.6.9.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 16 Nov 2020 11:20:22 +0100 nuitka (0.6.9.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 04 Nov 2020 08:32:22 +0100 nuitka (0.6.9.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 30 Oct 2020 13:49:19 +0100 nuitka (0.6.9.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 19 Oct 2020 10:55:17 +0200 nuitka (0.6.9.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 12 Oct 2020 17:17:10 +0200 nuitka (0.6.9.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 04 Oct 2020 12:47:36 +0200 nuitka (0.6.9.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 19 Sep 2020 14:38:08 +0200 nuitka (0.6.9+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Mon, 14 Sep 2020 15:40:36 +0200 nuitka (0.6.8.4+ds-1) unstable; urgency=medium * New upstream hotfix release. * Source only upload. (Closes: #961896) * Updated VCS URLs. (Closes: #961895) -- Kay Hayen Sat, 06 Jun 2020 09:58:32 +0200 nuitka (0.6.8.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 23 May 2020 13:56:13 +0200 nuitka (0.6.8.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 21 May 2020 15:04:13 +0200 nuitka (0.6.8.1+ds-1) unstable; urgency=medium * New upstream hotfix release. * Corrected copyright file format to not have emails. -- Kay Hayen Fri, 15 May 2020 08:32:39 +0200 nuitka (0.6.8+ds-1) unstable; urgency=medium * New upstream release. * Changed dependencies to prefer Debian 11 packages. (Closes: #937166). -- Kay Hayen Mon, 11 May 2020 16:41:34 +0200 nuitka (0.6.7+ds-1) unstable; urgency=medium * New upstream release. * The rst2pdf dependency is finally fixed (Closes: #943645) (Closes: #947573). * Enabled package build without Python2 (Closes: #937166) -- Kay Hayen Thu, 23 Jan 2020 12:34:10 +0100 nuitka (0.6.6+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Fri, 27 Dec 2019 08:47:38 +0100 nuitka (0.6.6~rc7+ds-1) unstable; urgency=medium * New upstream pre-release. -- Kay Hayen Tue, 24 Sep 2019 08:49:41 +0200 nuitka (0.6.5+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sat, 27 Jul 2019 12:07:20 +0200 nuitka (0.6.4+ds-1) experimental; urgency=medium * New upstream release. -- Kay Hayen Fri, 07 Jun 2019 23:30:22 +0200 nuitka (0.6.3.1+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 25 Apr 2019 22:08:36 +0200 nuitka (0.6.3+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Thu, 04 Apr 2019 06:12:30 +0200 nuitka (0.6.2+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sat, 16 Feb 2019 08:48:51 +0100 nuitka (0.6.1.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 24 Jan 2019 09:13:53 +0100 nuitka (0.6.1+ds-1) unstable; urgency=medium * New upstream release. * Depend on python-pil over python-imaging (Closes: #917694). -- Kay Hayen Sat, 05 Jan 2019 12:41:57 +0100 nuitka (0.6.0.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 31 Oct 2018 09:03:57 +0100 nuitka (0.6.0.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 18 Oct 2018 23:11:34 +0200 nuitka (0.6.0.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 14 Oct 2018 08:26:48 +0200 nuitka (0.6.0.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 06 Oct 2018 10:43:33 +0200 nuitka (0.6.0.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 03 Oct 2018 10:41:52 +0200 nuitka (0.6.0.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 27 Sep 2018 09:57:05 +0200 nuitka (0.6.0+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Wed, 26 Sep 2018 07:00:04 +0200 nuitka (0.5.33+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Thu, 13 Sep 2018 19:01:48 +0200 nuitka (0.5.32.8+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 04 Sep 2018 14:58:47 +0200 nuitka (0.5.32.7+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 23 Aug 2018 22:06:00 +0200 nuitka (0.5.32.6+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 23 Aug 2018 20:05:18 +0200 nuitka (0.5.32.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 15 Aug 2018 19:06:01 +0200 nuitka (0.5.32.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 10 Aug 2018 12:06:44 +0200 nuitka (0.5.32.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 04 Aug 2018 10:40:31 +0200 nuitka (0.5.32.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 01 Aug 2018 17:38:43 +0200 nuitka (0.5.32.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 28 Jul 2018 20:16:29 +0200 nuitka (0.5.32+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sat, 28 Jul 2018 15:07:21 +0200 nuitka (0.5.31+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Mon, 09 Jul 2018 08:23:02 +0200 nuitka (0.5.30+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Mon, 30 Apr 2018 09:50:54 +0200 nuitka (0.5.29.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 25 Apr 2018 09:33:55 +0200 nuitka (0.5.29.4+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 09 Apr 2018 20:22:37 +0200 nuitka (0.5.29.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 31 Mar 2018 16:12:25 +0200 nuitka (0.5.29.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 29 Mar 2018 10:19:24 +0200 nuitka (0.5.29.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 27 Mar 2018 18:22:54 +0200 nuitka (0.5.29+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Mon, 26 Mar 2018 20:13:44 +0200 nuitka (0.5.28.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 29 Nov 2017 15:09:28 +0100 nuitka (0.5.28.1+ds-1) unstable; urgency=medium * New upstream hotfix release. * Also ignore sbuild non-existent directory (Closes: #871125). -- Kay Hayen Sun, 22 Oct 2017 10:44:31 +0200 nuitka (0.5.28+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Tue, 17 Oct 2017 10:03:56 +0200 nuitka (0.5.27+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sat, 22 Jul 2017 16:21:37 +0200 nuitka (0.5.26.4+ds-1) unstable; urgency=medium * New upstream hotfix release. * Recommend actual PyQT package (Closes: #866540). -- Kay Hayen Mon, 03 Jul 2017 08:59:37 +0200 nuitka (0.5.26.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 22 Jun 2017 08:08:53 +0200 nuitka (0.5.26.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 17 Jun 2017 11:37:12 +0200 nuitka (0.5.26.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 10 Jun 2017 13:09:51 +0200 nuitka (0.5.26+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Wed, 07 Jun 2017 08:15:19 +0200 nuitka (0.5.25+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Tue, 24 Jan 2017 06:13:46 +0100 nuitka (0.5.24.4+ds-1) unstable; urgency=medium * New upstream hotfix release. * Better detection of acceptable shared library loads from system paths for standalone tests (Closes: #844902). -- Kay Hayen Sat, 10 Dec 2016 12:25:35 +0100 nuitka (0.5.24.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 09 Dec 2016 06:50:55 +0100 nuitka (0.5.24.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 30 Nov 2016 09:32:03 +0100 nuitka (0.5.24.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 16 Nov 2016 08:16:53 +0100 nuitka (0.5.24+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Mon, 14 Nov 2016 09:41:31 +0100 nuitka (0.5.23.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 07 Nov 2016 07:55:11 +0100 nuitka (0.5.23.1+ds-1) unstable; urgency=medium * New upstream hotfix release. * Use of C11 compiler instead of C++ compiler, so we drop the versioned dependencies. (Closes: #835954) -- Kay Hayen Sun, 16 Oct 2016 10:40:59 +0200 nuitka (0.5.23+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sun, 02 Oct 2016 18:14:41 +0200 nuitka (0.5.22+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Tue, 16 Aug 2016 11:22:16 +0200 nuitka (0.5.21.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 26 May 2016 14:51:39 +0200 nuitka (0.5.21.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 14 May 2016 14:43:28 +0200 nuitka (0.5.21.1+ds-1) unstable; urgency=medium * New upstream hotfix release. * Depends on g++-5 now. -- Kay Hayen Sat, 30 Apr 2016 07:59:57 +0200 nuitka (0.5.21+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sun, 24 Apr 2016 14:06:29 +0200 nuitka (0.5.20+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sun, 20 Mar 2016 08:11:16 +0100 nuitka (0.5.19.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 15 Mar 2016 09:11:57 +0100 nuitka (0.5.19+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Mon, 01 Feb 2016 07:53:08 +0100 nuitka (0.5.18.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 24 Jan 2016 07:52:03 +0100 nuitka (0.5.18+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Fri, 15 Jan 2016 07:48:41 +0100 nuitka (0.5.17.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 14 Jan 2016 23:21:51 +0100 nuitka (0.5.17+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sun, 27 Dec 2015 15:18:39 +0100 nuitka (0.5.16.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 03 Dec 2015 07:04:12 +0100 nuitka (0.5.16+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Mon, 09 Nov 2015 18:30:07 +0100 nuitka (0.5.15+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Mon, 12 Oct 2015 08:57:03 +0200 nuitka (0.5.14.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 13 Sep 2015 12:26:59 +0200 nuitka (0.5.14.2+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 07 Sep 2015 00:30:11 +0200 nuitka (0.5.14.1+ds-1) UNRELEASED; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 06 Sep 2015 22:37:22 +0200 nuitka (0.5.14+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Thu, 27 Aug 2015 06:24:11 +0200 nuitka (0.5.13.8+ds-1) UNRELEASED; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 20 Aug 2015 11:55:53 +0200 nuitka (0.5.13.7+ds-1) UNRELEASED; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 18 Aug 2015 21:55:08 +0200 nuitka (0.5.13.6+ds-1) UNRELEASED; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 16 Aug 2015 14:38:46 +0200 nuitka (0.5.13.5+ds-1) UNRELEASED; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 16 Aug 2015 13:42:02 +0200 nuitka (0.5.13.4+ds-1) UNRELEASED; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 31 Jul 2015 17:24:40 +0200 nuitka (0.5.13.3+ds-1) UNRELEASED; urgency=medium * New upstream hotfix release. -- Kay Hayen Wed, 29 Jul 2015 10:54:05 +0200 nuitka (0.5.13.2+ds-1) UNRELEASED; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 16 Jun 2015 10:29:12 +0200 nuitka (0.5.13.1+ds-1) UNRELEASED; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 04 May 2015 09:27:19 +0200 nuitka (0.5.13+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Fri, 01 May 2015 10:44:27 +0200 nuitka (0.5.12.2+ds-1) UNRELEASED; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 26 Apr 2015 08:51:37 +0200 nuitka (0.5.12.1+ds-1) UNRELEASED; urgency=medium * New upstream hotfix release. -- Kay Hayen Sat, 18 Apr 2015 09:35:06 +0200 nuitka (0.5.12+ds-1) experimental; urgency=medium * New upstream release. -- Kay Hayen Mon, 06 Apr 2015 17:20:44 +0200 nuitka (0.5.11.2+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 26 Mar 2015 20:09:06 +0100 nuitka (0.5.11.1+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 23 Mar 2015 10:34:17 +0100 nuitka (0.5.11+ds-1) experimental; urgency=medium * New upstream release. -- Kay Hayen Wed, 18 Mar 2015 08:38:39 +0100 nuitka (0.5.10.2+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Tue, 10 Mar 2015 07:46:24 +0100 nuitka (0.5.10.1+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 08 Mar 2015 11:56:55 +0100 nuitka (0.5.10+ds-1) experimental; urgency=medium * New upstream release. -- Kay Hayen Thu, 05 Mar 2015 07:43:43 +0100 nuitka (0.5.9+ds-1) experimental; urgency=medium * New upstream release. -- Kay Hayen Thu, 29 Jan 2015 08:18:06 +0100 nuitka (0.5.8+ds-1) experimental; urgency=medium * New upstream release. -- Kay Hayen Thu, 15 Jan 2015 04:11:03 +0100 nuitka (0.5.7.1+ds-1) experimental; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 09 Jan 2015 13:52:15 +0100 nuitka (0.5.7+ds-1) UNRELEASED; urgency=medium * New upstream release. -- Kay Hayen Thu, 01 Jan 2015 10:52:03 +0100 nuitka (0.5.6.1+ds-1) UNRELEASED; urgency=medium * New upstream hotfix release. -- Kay Hayen Sun, 21 Dec 2014 08:32:58 +0100 nuitka (0.5.6+ds-1) UNRELEASED; urgency=medium * New upstream release. * Added support for hardening-wrapper to be installed. -- Kay Hayen Fri, 19 Dec 2014 08:39:17 +0100 nuitka (0.5.5.3+ds-1) unstable; urgency=medium * New upstream hotfix release. * Added support for armhf architecture. -- Kay Hayen Fri, 24 Oct 2014 17:33:59 +0200 nuitka (0.5.5.2+ds-1) unstable; urgency=medium * New upstream hotfix release. * Bump to Standards Version 3.9.6, no changes needed. -- Kay Hayen Fri, 17 Oct 2014 07:56:05 +0200 nuitka (0.5.5+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Sun, 05 Oct 2014 19:28:20 +0200 nuitka (0.5.4.3+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 21 Aug 2014 09:41:37 +0200 nuitka (0.5.3.5+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Fri, 18 Jul 2014 07:28:17 +0200 nuitka (0.5.3.3+ds-1) unstable; urgency=medium * New upstream release. * Original version didn't build for all versions due to error message changes, this release adapts to. -- Kay Hayen Sat, 12 Jul 2014 20:50:01 +0200 nuitka (0.5.2+ds-1) unstable; urgency=medium * New upstream release. * Permit building using cowbuilder, eatmydata (Closes: #749518) * Do not require gcc in build-depends (Closes: #747984) (Closes: #748005) (Closes: #751325) -- Kay Hayen Mon, 23 Jun 2014 08:17:57 +0200 nuitka (0.5.1.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Thu, 06 Mar 2014 10:44:28 +0100 nuitka (0.5.1+ds-1) unstable; urgency=medium * New upstream release. -- Kay Hayen Thu, 06 Mar 2014 09:33:51 +0100 nuitka (0.5.0.1+ds-1) unstable; urgency=medium * New upstream hotfix release. -- Kay Hayen Mon, 13 Jan 2014 23:37:37 +0100 nuitka (0.5.0+ds-1) unstable; urgency=medium * New upstream release. * Added missing build dependency to process PNG images. -- Kay Hayen Fri, 03 Jan 2014 19:18:18 +0100 nuitka (0.4.7.1+ds-1) unstable; urgency=low * New upstream hotfix release. -- Kay Hayen Tue, 03 Dec 2013 08:44:31 +0100 nuitka (0.4.7+ds-1) UNRELEASED; urgency=low * New upstream release. * Handle unknown encoding error message change of CPython 2.7.6 that was backported to CPython 2.7.5+ as well. (Closes: #730956) -- Kay Hayen Mon, 02 Dec 2013 09:15:12 +0100 nuitka (0.4.6.2+ds-1) unstable; urgency=low * New upstream hotfix release. -- Kay Hayen Fri, 01 Nov 2013 19:07:42 +0100 nuitka (0.4.6+ds-1) unstable; urgency=low * New upstream release. -- Kay Hayen Sun, 27 Oct 2013 21:29:26 +0100 nuitka (0.4.5.1+ds-1) unstable; urgency=low * New upstream hotfix release. * Corrects upstream Issue#106. -- Kay Hayen Wed, 25 Sep 2013 14:29:55 +0200 nuitka (0.4.5+ds-1) unstable; urgency=low * New upstream release. -- Kay Hayen Sun, 18 Aug 2013 09:06:29 +0200 nuitka (0.4.4.2+ds-1) unstable; urgency=low * New upstream hotfix release. * Corrects upstream Issue#98. * Corrects upstream Issue#100. * Corrects upstream Issue#101. * Corrects upstream Issue#102. -- Kay Hayen Sat, 20 Jul 2013 09:08:29 +0200 nuitka (0.4.4.1+ds-1) unstable; urgency=low * New upstream hotfix release. * Corrects upstream Issue#95. * Corrects upstream Issue#96. -- Kay Hayen Sat, 13 Jul 2013 11:56:21 +0200 nuitka (0.4.4+ds-1) unstable; urgency=low * New upstream release. * Upstream now supports Python3.3 and threads. * Bump to Standards Version 3.9.4, no changes needed. * Fix support for modules and Python3 was broken (Closes: #711459) * Fix encoding error changes Python 2.7.5 (Closes: #713531) -- Kay Hayen Tue, 25 Jun 2013 10:46:40 +0200 nuitka (0.4.3+ds-1) unstable; urgency=low * New upstream release. -- Kay Hayen Sat, 18 May 2013 10:16:25 +0200 nuitka (0.4.2+ds-1) unstable; urgency=low * New upstream release. -- Kay Hayen Fri, 29 Mar 2013 11:05:08 +0100 nuitka (0.4.1+ds-1) unstable; urgency=low * New upstream release. -- Kay Hayen Tue, 05 Mar 2013 08:15:41 +0100 nuitka (0.4.0+ds-1) UNRELEASED; urgency=low * New upstream release. * Changes so the Debian package can be backported to Squeeze as well. -- Kay Hayen Sat, 09 Feb 2013 10:08:15 +0100 nuitka (0.3.25+ds-1) unstable; urgency=low * New upstream release. * Register the User Manual with "doc-base". -- Kay Hayen Sun, 11 Nov 2012 13:57:32 +0100 nuitka (0.3.24.1+ds-1) unstable; urgency=low * New upstream hotfix release. * Corrects upstream Issue#46. -- Kay Hayen Sat, 08 Sep 2012 22:30:11 +0000 nuitka (0.3.24+ds-1) unstable; urgency=low * New upstream release. * Detect the absence of "g++" and gracefully fallback to the compiler depended on. (Closes: #682146) * Changed usage of "temp" files in developer scripts to be secure. (Closes: #682145) * Added support for "DEB_BUILD_OPTIONS=nocheck" to skip the test runs. (Closes: #683090) -- Kay Hayen Sat, 18 Aug 2012 21:19:17 +0200 nuitka (0.3.23.1+ds-1) unstable; urgency=low * New upstream hotfix release. * Corrects upstream Issue#40, Issue#41, and Issue#42. -- Kay Hayen Mon, 16 Jul 2012 07:25:41 +0200 nuitka (0.3.23+ds-1) unstable; urgency=low * New upstream release. * License for Nuitka is now Apache License 2.0, no more GPLv3. * Corrects upstream Issue#37 and Issue#38. -- Kay Hayen Sun, 01 Jul 2012 00:00:57 +0200 nuitka (0.3.22.1+ds-1) unstable; urgency=low * New upstream hotfix release. * Corrected copyright file syntax error found by new lintian version. * Corrects upstream Issue#19. -- Kay Hayen Sat, 16 Jun 2012 08:58:30 +0200 nuitka (0.3.22+ds-1) unstable; urgency=low * New upstream release. -- Kay Hayen Sun, 13 May 2012 12:51:16 +0200 nuitka (0.3.21+ds-1) unstable; urgency=low * New upstream release. -- Kay Hayen Thu, 12 Apr 2012 20:24:01 +0200 nuitka (0.3.20.2+ds-1) unstable; urgency=low * New upstream hotfix release. * Corrects upstream Issue#35. * Bump to Standards Version 3.9.3, no changes needed. * In the alternative build dependencies, designed to make the Python3 build dependency optional, put option that is going to work on "unstable" first. (Closes: #665021) -- Kay Hayen Tue, 03 Apr 2012 22:31:36 +0200 nuitka (0.3.20.1+ds-1) unstable; urgency=low * New upstream hotfix release. * Corrects upstream Issue#34. -- Kay Hayen Sat, 03 Mar 2012 10:18:30 +0100 nuitka (0.3.20+ds-1) unstable; urgency=low * New upstream release. * Added upstream "Changelog.rst" as "changelog" -- Kay Hayen Mon, 27 Feb 2012 09:32:10 +0100 nuitka (0.3.19.2+ds-1) unstable; urgency=low * New upstream hotfix release. * Corrects upstream Issue#32. -- Kay Hayen Sun, 12 Feb 2012 20:33:30 +0100 nuitka (0.3.19.1+ds-1) unstable; urgency=low * New upstream hotfix release. * Corrects upstream Issue#30 and Issue#31. -- Kay Hayen Sat, 28 Jan 2012 07:27:38 +0100 nuitka (0.3.19+ds-1) unstable; urgency=low * New upstream release. * Improvements to option groups layout in manpages, and broken whitespace for "--recurse-to" option. (Closes: #655910) * Documented new option "--recurse-directory" in man page with example. * Made the "debian/watch" file ignore upstream pre-releases, these shall not be considered for this package. * Aligned depended version with build depended versions. * Depend on "python-dev" as well, needed to compile against "libpython". * Build depend on "python-dev-all" and "python-dbg-all" to execute tests with both all supported Python versions. * Build depend on "python3.2-dev-all" and "python3-dbg-all" to execute tests with Python3 as well. It is currently not supported by upstream, this is only preparatory. * Added suggestion of "ccache", can speed up the compilation process. -- Kay Hayen Tue, 17 Jan 2012 10:29:45 +0100 nuitka (0.3.18+ds-1) unstable; urgency=low * New upstream release. * Lowered dependencies so that a backport to Ubuntu Natty and higher is now feasible. A "scons >=2.0.0" is good enough, and so is "g++-4.5" as well. * Don't require the PDF generation to be successful on older Ubuntu versions as it crashes due to old "rst2pdf" bugs. -- Kay Hayen Thu, 12 Jan 2012 19:55:43 +0100 nuitka (0.3.18~pre2+ds-1) unstable; urgency=low * New upstream pre-release. * First upload to unstable, many thanks to my reviewer and sponsor Yaroslav Halchenko * New maintainer (Closes: #648489) * Added Developer Manual to the generated PDF documentation. * Added python-dbg to Build-Depends to also execute reference count tests. * Changed copyright file to reference Apache license via its standard Debian location as well. -- Kay Hayen Tue, 10 Jan 2012 22:21:56 +0100 nuitka (0.3.17+ds-1) UNRELEASED; urgency=low * New upstream release. * Updated man page to use new "--recurse-*" options in examples over removed "--deep*" options. * Completed copyright file according to "licensecheck" findings and updated files accordingly. Put the included tests owned by upstream into public domain. * Use a "+ds" file as orig source with inline copy of Scons already removed instead of doing it as a patch. * Also removed the benchmark tests from "+ds" file, not useful to be provided with Nuitka. * Added syntax tests, these were omitted by mistake previously. * Run the test suite at package build time, it checks the basic tests, syntax error tests, program tests, and the compile itself test. * Added run time dependencies also as build time dependencies to be able to execute the tests. * Corrected handling of upstream pre-release names in the watch file. * Changed contributor notice to only require "Apache License 2.0" for the new parts. * Put Debian packaging and owned tests under "Apache License 2.0" as well. -- Kay Hayen Mon, 09 Jan 2012 09:02:19 +0100 nuitka (0.3.16-1) UNRELEASED; urgency=low * New upstream release. * Updated debian/copyright URI to match the latest one. * Updated debian/copyright to DEP5 changes. * Added Nuitka homepage to debian/control. * Added watch file, so uscan works. * Added git pointers to git repository and gitweb to the package control file. * Corrected examples section in man page to correctly escape "-". * Added meaningful "what is" to manpages. * Bump to Standards Version 3.9.2, no changes needed. * Added extended description to address lintian warning. -- Kay Hayen Sun, 18 Dec 2011 13:01:10 +0100 nuitka (0.3.15-1) UNRELEASED; urgency=low * New upstream release. * Renamed "/usr/bin/Python" to "/usr/bin/nuitka-python". * Added man pages for "nuitka" and "nuitka-python", the first with an examples section that shows the most important uses of the "nuitka" binary. * Removed foreign code for Windows generators, removed from debian/copyright. * Lowered dependency for Scons to what Ubuntu Oneiric has and what we have as an inline copy, (scons >=2.0.1) should be sufficient. * Recommend python-lxml, as it's used by Nuitka to dump XML representation. * Recommend python-qt4, as it may be used to display the node tree in a window. * Removed inline copy of Scons from the binary package. * Added patch to remove the setting nuitka package in sys.path, not needed in Debian. -- Kay Hayen Thu, 01 Dec 2011 22:43:33 +0100 nuitka (0.3.15pre2-1) UNRELEASED; urgency=low * Initial Debian package. -- Kay Hayen Fri, 11 Nov 2011 20:58:55 +0100 ================================================ FILE: debian/compat ================================================ 9 ================================================ FILE: debian/control ================================================ Source: nuitka Maintainer: Kay Hayen Section: python Priority: optional Build-Depends: debhelper (>= 9), lsb-release, dh-python | base-files (<< 9.6), base-files (>= 11) | python (>= 2.6.6-2), base-files (>= 11) | python-all-dbg (>= 2.6.6-2), base-files (>= 11) | python-all-dev (>= 2.6.6-2), base-files (>= 11) | python-setuptools, base-files (>= 11) | python-jinja2, base-files (>= 11) | python-yaml, base-files (>= 11) | base-files (<< 9.10) | python-glob2, scons, python3-all-dev (>= 3.3), python3-all-dbg (>= 3.3), python3-setuptools, python3-jinja2, python3-yaml, zlib1g-dev, base-files (>= 11) | python-appdirs, python3-appdirs | base-files (<< 7.2), python3-glob2 | base-files (<< 9.10), rst2pdf, fontconfig, base-files (>= 11) | python-pil | python-imaging, python3-pil | base-files (<< 11), ccache, strace, patchelf, libzstd-dev | base-files (<= 9), gdb | lldb Rules-Requires-Root: no Vcs-Git: https://github.com/Nuitka/Nuitka.git Vcs-Browser: https://github.com/Nuitka/Nuitka Homepage: https://nuitka.net Standards-Version: 4.4.1 X-Python-Version: >= 2.6 X-Python3-Version: >= 3.3 Package: nuitka Architecture: all Depends: gcc (>= 5.0) | g++ (>= 4.4) | clang (>= 3.0), scons (>= 2.0.0), python3-jinja2, python3-appdirs | base-files (<< 7.2), python3-glob2 | base-files (<< 9.10), python3-dev, base-files (>= 11) | python-jinja2, base-files (>= 11) | python-yaml, base-files (>= 11) | base-files (<< 9.10) | python-glob2, zlib1g-dev, libzstd-dev | base-files (<= 9), ccache, patchelf, ${misc:Depends}, ${python:Depends}, ${python3:Depends} Recommends: python3-lxml, python3-tqdm, strace, libfuse2, gdb | lldb Description: Python compiler with full language support and CPython compatibility This Python compiler achieves full language compatibility and compiles Python code into compiled objects that are not second class at all. Instead they can be used in the same way as pure Python objects. ================================================ FILE: debian/copyright ================================================ Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=166 Upstream-Name: nuitka Upstream-Contact: Kay Hayen Source: https://nuitka.net/ # No spell checking for this file, spell-checker: disable Files: * Copyright: 2024 Kay Hayen 2020 Batakrishna Sahu 2020 Jan Teske 2020 Jorj McKie 2020 Paweł Kierzkowski 2020 Tommy Li License: Apache+Nuitka_comment Part of "Nuitka", an optimizing Python compiler that is compatible and integrates with CPython, but also works on its own. . Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. . On Debian GNU/Linux systems, the complete text of the Apache 2.0 license can be found in `/usr/share/common-licenses/Apache-2.0'. Files: tests/basics tests/programs tests/reflected tests/type_inference Copyright: 2024 Kay Hayen License: Apache+Nuitka_test_origin Python tests originally created or extracted from other peoples work. The parts were too small to be protected. . Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. . On Debian GNU/Linux systems, the complete text of the Apache 2.0 license can be found in `/usr/share/common-licenses/Apache-2.0'. Files: nuitka/containers/OrderedDicts.py Copyright: 2008 by Armin Ronacher and PEP 273 authors License: BSD-3-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the organizations nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. . THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Files: nuitka/containers/OrderedSetsFallback.py Copyright: 2009 Raymond Hettinger License: MIT+Hettinger Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Files: nuitka/build/include/nuitka/hedley.h Copyright: 2020 Evan Nemerson License: public-domain To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. . For details, see . SPDX-License-Identifier: CC0-1.0 Files: nuitka/build/include/nuitka/incbin.h Copyright: 2020 Dale Weiler License: public-domain This is free and unencumbered software released into the public domain. . Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. . In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. . For more information, please refer to SPDX-License-Identifier: CC0-1.0 Files: debian Copyright: 2024 Kay Hayen License: Apache Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. . On Debian GNU/Linux systems, the complete text of the Apache 2.0 license can be found in `/usr/share/common-licenses/Apache-2.0'. ================================================ FILE: debian/nuitka.docs ================================================ changelog ================================================ FILE: debian/nuitka.manpages ================================================ doc/nuitka.1 doc/nuitka-run.1 ================================================ FILE: debian/pbuilder-hookdir/B92test-installed-nuitka ================================================ #!/bin/bash # Make sure we error exit if something goes wrong. set -e echo "Checking package installation and running some tests with it too." # The current directory is the top of the source-tree. cd /tmp/buildd/*/debian/.. echo "Removing unneeded stuff (build, binaries of nuitka, nuitka package, debian directory):" rm -rf build bin/nuitka* nuitka debian echo "Installing the Debian package." # Install the single package, and then the dependencies. Idea taken from "B92test-pkg" dpkg -i /tmp/buildd/*.deb || true apt-get install -y -f "${APTGETOPT[@]}" # Remove tests that only work in checkouts. rm tests/basics/Referencing*.py # Run the basic tests with default options and installed nuitka. export NUITKA=/usr/bin/nuitka if [ -f "$NUITKA" ] then $(head -n1 $NUITKA | cut -d'!' -f2) ./tests/basics/run_all.py search fi export NUITKA=/usr/bin/nuitka3 $(head -n1 $NUITKA | cut -d'!' -f2) ./tests/basics/run_all.py search echo "Thanks passed the tests with installed package it seems." ================================================ FILE: debian/rules ================================================ #!/usr/bin/make -f export DH_VERBOSE = 1 export PYBUILD_NAME = nuitka # This disables the building with debug Python, not sure why we need to # set PYBUILD_VERSIONS too, but it seemed that way. export PYBUILD_INTERPRETERS = python{version} # Do not use Python2 for Debian 11 or higher, need to find a way for Ubuntu # to cover, Debian 11 inheritance. DEB_VENDOR=$(shell dpkg-vendor --query vendor) ifeq ($(DEB_VENDOR), Debian) BUILD_ONLY_PYTHON3 := $(shell [ `lsb_release -r -s | sed -e s/unstable/11/ -e 's/n\/a/11/' -e s/testing/11/ -e s/buildd-// -e 's/\..*//'` -ge 11 ] && echo true) else ifeq ($(DEB_VENDOR), Ubuntu) BUILD_ONLY_PYTHON3 := $(shell [ `lsb_release -r -s | sed -e 's/\.//' ` -ge 2004 ] && echo true) else BUILD_ONLY_PYTHON3 := false endif export BUILD_ONLY_PYTHON3 ifeq ($(BUILD_ONLY_PYTHON3),true) export PYBUILD_VERSIONS = $(shell py3versions -vr) export BUILD_WITH_ARGUMENT = "python3" export RUN_TEST_OPTIONS = --no-python2.7 --no-python2.6 export RUN_TEST_PYTHON = python3 else export PYBUILD_VERSIONS = $(shell pyversions -vr) $(shell py3versions -vr) export BUILD_WITH_ARGUMENT = "python2,python3" export RUN_TEST_OPTIONS = export RUN_TEST_PYTHON = python2 endif %: set -x dh $@ --with $(BUILD_WITH_ARGUMENT) --buildsystem=pybuild override_dh_auto_build: cp Changelog.rst changelog cp Developer_Manual.rst Developer_Manual.txt override_dh_auto_test: # The RUN_TEST_PYTHON is not the one to execute tests, just the for the # test runner. $(RUN_TEST_PYTHON) ./tests/run-tests --skip-reflection-test $(RUN_TEST_OPTIONS) ================================================ FILE: debian/source/format ================================================ 3.0 (quilt) ================================================ FILE: debian/source/lintian-overrides ================================================ # The build dependency on python-dev stems from the running of tests which # will build extensions or programs that embed CPython. Only the builder # arch needs to be installed. nuitka source: build-depends-on-python-dev-with-no-arch-any # I am doing test builds on Debian stable, while the upload target is # unstable. For these, ignore the too new standards version. nuitka source: newer-standards-version # We continue to support very old distributions and therefore allow # the relatively ancient Python releases. nuitka source: ancient-python-version-field # We have generated code with sometimes bizarre length of identifiers nuitka source: very-long-line-length-in-source-file # We are really working with compat level up to what we say, but we # want to build with distributions that don't have it. nuitka source: package-needs-versioned-debhelper-build-depends # Our include directory for C is named after the project. nuitka: repeated-path-segment nuitka usr/lib/python3/dist-packages/nuitka/build/include/nuitka/ ================================================ FILE: debian/upstream-signing-key.pgp ================================================ -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.15 (GNU/Linux) mQINBFJ/+gwBEADG5uZfKLmI3gg2BoWd3K2C63cPMeVVVDvQtCKZHqnJ6x+ERDCt 6kASBqpvFIkBLUF28cV+PhNRosNBsYn05WcIz2b5+QbxfTukhG8hXfr6HWL2lwiP LJcSwU1GhDvnFps6DgDZUhSDJ9VuOjShWdxPaJ917C3bs054bmZdSYrw2i3NjUrX q6tb/kh7/yFW4UT6O/V3XHeD81yA7hKUsf25hKiVEcPxE3LFXJP4qJB7XH7hn650 LOuznQ4dXL8wPM0FpeDo1K//3S2xaTLuYtokUu3755NuLVSZj/f0324QUzdzOE4L HS7pdOVAUqHWlS5V97XsJBayRthGEC5n834p7Mtqt7kMkaWThMwKwXUqrNGbZ7FK X+D1MA78LAxVARybdnyElAhSbB8QMoW2sMjNAzd39PAYikMnkjtEaxOSM7UF8Itq 3rgHE2Zi0pCSR0kO3aEP9fQxznJ20kMcfkC10VSg7ucufqklfNJo1CMY+VVB5d35 orhL6odoMBGBwf10W+In3VwQ1oOiY84IwaYKNJuO9q+QOdwDVQX1+RacGKKtnFKS PYQV3UtqYyqdydB5rk2Dg1CgF9Z6m7VtN6Dp9DOzs5vwCRa65u/77l8J4DEx3DYd QVYQzRwhvjD0+H34vlARpWUeWT6IEF5yYl0C+dp824lpP95kOVGuFhN4iQARAQAB tB9LYXkgSGF5ZW4gPGtheS5oYXllbkBnbWFpbC5jb20+iQI+BBMBAgAoBQJSf/oM AhsDBQkDwmcABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRAb/DN1KRK5nMsa D/4kheo2e1ce0+LU6UXhIYSwTV7O1Zc8FelWj0tFX2YaNR8S6m9Ad6jmNVyFSyth DyKCx6tzdTyXKf+Rog8LFC6V+IStktnCV/MdRBJGZvBr3rPVcKEfQErhHdAA8UvN ArkAGErqLGiOsaMLmEcEyD0cU3w+nu12fEdRW1S7Q8R1X+DoT+plhs/xfgtP4M3/ Gk1mGNQ+p4wMK52tfz7rV/IHX/5DxH8OGb/aZliYSPB9Dnn1WD4KS1F4VWZsDJBe N8XT6+qyhK0S6waXHAL3Qkfcl4fp//QTI4+P+yzMtLk2m37fDk4GRUKR6oyHN+8Z EeXQ0cykxL6P83ui4HztlQOEb2PSjC0ZSoN7IZcwwhS97BorpAs2/OV8FBuCTNXQ oEzDH8fNwgDk840PNPk1GmsQl3yhIiKOdoYyFRQUvVV6objyMhDThe667hYHcaES 6tlW066gLQLuUyX5zTPncxvrc+Ow8kEnYzv+ODrIKGS4rTyCu964yas72de2bT9S H7aYarnN7dgT4pmpFic9jMG9O415838eBzQcBuRejIJUuS+lGwaqishkPW8j1v63 WriU4ane58v9buqC9camUYS14bIEp6qpDvnLR39WOLwjRq2u3ga5gLOgC2oLyKxr DieTM5YKRUnbwY67KAAla06uoClKE4jMKXYTPdPX6F4lubkCDQRSf/oMARAAkef8 rQLhgajKazmlcnb7pp7+2sP/NXn23U6GCtaAA6EgYP5tcSHAlfKmYR2xlHUTU+9G mfNXWOzaCqpeQZi7o+pkDwroB9IiGTfxRZJfBWTxLpgBRFV8NWc0atlhk9pjcIuD ha0Dt0acNW7/SKQHouKPbtKuX46GOL/szPhVWp1Ph+t8CHKhF9g7mJcnDdCrnmsx 1wI6Dcrmikj7STW3jnPyX3SsV9fHOp6CJwUQLVQNCoUS/n7Cx1UC+vDmxiewcBgo XXTRszmZZvM/7Uo7lrmPoP2KrImrcjypRyZ2rqVdf2Ac4TIFx+ySyB5puKtA4O0U hdRtotEK5fpeLt/etcLVs3Gk4Eol8fQiwjYEIfrT9+vcPthA691aTdMBFsKaWuCX T8m5c2LOP/dBjYdiLz7YByLPt0V4y8meit2emSmLHwsXLHZEU7BlKxc5xpnGGZ65 3Jgpps9FqhDHoHiboSeLwpuiB+9VSQWJL9xpgNeXZWjWu7UC3mdGe+Iq2LSm+S4F e2hzHzO4dNQI+LttvTqS7V9pYLsG49VztTm/xIoAMs7bCsIFYGUl9VlmR0dZOZle 8bCBoNdYelT/e/8xvestLSjNnQl5e9YRoVy1TybxXz6n/d65Klw1mfHUl/GqgdXc DZBxBDrJvXyMuIyspj6zZMJ9QOwB3Xn9zGukxCcAEQEAAYkCJQQYAQIADwUCUn/6 DAIbDAUJA8JnAAAKCRAb/DN1KRK5nErDD/wNc7827lo+2q3KeCMiFngMw/WQ6mlp ytzQjXHW4p7Fs13X0ebP/j6rIT/LUqeHPVoUpns98yyAFgo5G3Q0GqC8EP9n4mbE 6QA2ctdCPoNX+rdM9yBq4PoZSzz0vpITfToa7cdo0nrlbmiaEYnhlSM+416Nw8c/ yqFcHt65Lh71GgDhpT7Q5q7C2cT21cS3O/N4xul2n5SJkGm97W+sPo9uOscTRLbI ye959Z1EffKfB+izItxYqSlTyIqIgf+1yffjo5+pPh4ZsxtNYTohZiiPhbvlbwnM 5u540366XoJHBmHgyPAYkVUQAJZwGdXI23DXmyg45avzeEO8mIrZ4aU++5UZ/+h8 HCM4vfOpRTg8+IfIq7vArjlMoSDeqCSVJVlJxLppreCld2f1VHg9PEEcpPv2siPh lhzU5M6KcJYgTiDoHMfeO8qlKjG62/aA0rBXzZanL580eldCEr96rpEFhdaOMyWv TJ58LULfdHXsif8yq2mI4+6MrnC9IYDSLZHyR1aCgbXCKhI5r+g/DYvGxjFObf9m XoRhS0dCVNZHT4y0Bu6YBuvUUELXnNa0CDveBH4wj10fRR5+q/GUlQygGfnFhrgG Bn3HOx+kxz441CBIcaGtmCYhH6CFo5hcMKNHF7yG1AlWW97Zu629uT1nqK45JQqq qI5vOLPGcTsOVQ== =uGbZ -----END PGP PUBLIC KEY BLOCK----- ================================================ FILE: debian/watch ================================================ version=3 opts=dversionmangle=s/\+ds$//,uversionmangle=s/pre/~pre/,pgpsigurlmangle=s/$/.sig/ \ https://nuitka.net/releases/Nuitka-([\d\.]+).tar.gz debian uupdate ================================================ FILE: doc/Doxyfile.template ================================================ # Copyright 2024, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file # Doxyfile 1.8.12 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all text # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv # built into libc) for the transcoding. See http://www.gnu.org/software/libiconv # for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = "Nuitka" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "The Python compiler" # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. PROJECT_LOGO = doc/images/Nuitka-Logo-Symbol.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. # The default value is: NO. ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, # Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), # Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, # Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, # Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, # Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, # Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new # page for each member. If set to NO, the documentation of a member will be part # of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = YES # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: # FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: # Fortran. In the later case the parser tries to guess whether the code is fixed # or free formatted code, this is the default for Fortran type files), VHDL. For # instance to make doxygen treat .inc files as Fortran files (default is PHP), # and .f files as C (default is Fortran), use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. # Minimum value: 0, maximum value: 99, default value: 0. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 0 # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO # If one adds a struct or class to a group and this option is enabled, then also # any nested class or struct is added to the same group. By default this option # is disabled and one has to add nested compounds explicitly via \ingroup. # The default value is: NO. GROUP_NESTED_COMPOUNDS = NO # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option # has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # (class|struct|union) declarations. If set to NO, these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will # append additional text to a page's title, such as Class Reference. If set to # YES the compound reference will be hidden. # The default value is: NO. HIDE_COMPOUND_REFERENCE= NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo # list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test # list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters # in a documented function, or documenting parameters that don't exist or using # markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO, doxygen will only warn about wrong or incomplete # parameter documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = NO # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when # a warning is encountered. # The default value is: NO. WARN_AS_ERROR = NO # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = doxygen-warnings.log #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = . INPUT += nuitka INPUT += nuitka/nodes INPUT += nuitka/nodes/shapes INPUT += nuitka/tree INPUT += nuitka/code_generation INPUT += nuitka/code_generation/templates/ INPUT += nuitka/containers INPUT += nuitka/finalizations INPUT += nuitka/optimizations INPUT += nuitka/utils INPUT += nuitka/importing INPUT += nuitka/freezer INPUT += nuitka/plugins INPUT += nuitka/plugins/standard INPUT += nuitka/build INPUT += nuitka/build/include INPUT += nuitka/build/include/nuitka INPUT += nuitka/build/include/nuitka/helper INPUT += nuitka/build/static_src # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: http://www.gnu.org/software/libiconv) for the list of # possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, # *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, # *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, # *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.idl \ *.ddl \ *.odl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.cs \ *.d \ *.php \ *.php4 \ *.php5 \ *.phtml \ *.inc \ *.m \ *.markdown \ *.md \ *.mm \ *.dox \ *.py \ *.pyw \ *.f90 \ *.f95 \ *.f03 \ *.f08 \ *.f \ *.for \ *.tcl \ *.vhd \ *.vhdl \ *.ucf \ *.qsf # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = YES # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = Mini*.py # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. FILTER_PATTERNS = *.py=%DOXYPYPY% # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. # TODO: Enable later SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. # TODO: Enable later INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see http://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES # If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the # clang parser (see: http://clang.llvm.org/) for more accurate parsing at the # cost of reduced performance. This can be particularly helpful with template # rich C++ code for which doxygen's built-in parser lacks the necessary type # information. # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse-libclang=ON option for CMake. # The default value is: NO. CLANG_ASSISTED_PARSING = NO # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that # the include paths will already be set by doxygen for the files and directories # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. CLANG_OPTIONS = #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = YES # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = doc/custom.css # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to YES can help to show when doxygen was last run and thus if the # documentation is up to date. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: http://developer.apple.com/tools/xcode/), introduced with # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated # (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- # folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = YES # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANSPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from http://www.mathjax.org before deployment. # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /