Nuitka-winsvc 1.6.6__cp310-cp310-win_amd64.whl → 1.7.5__cp310-cp310-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {Nuitka_winsvc-1.6.6.dist-info → Nuitka_winsvc-1.7.5.dist-info}/METADATA +1 -1
- {Nuitka_winsvc-1.6.6.dist-info → Nuitka_winsvc-1.7.5.dist-info}/RECORD +84 -81
- nuitka/Builtins.py +7 -1
- nuitka/MainControl.py +4 -0
- nuitka/OptionParsing.py +5 -3
- nuitka/Options.py +17 -2
- nuitka/Serialization.py +28 -5
- nuitka/Version.py +2 -2
- nuitka/build/Backend.scons +16 -3
- nuitka/build/CCompilerVersion.scons +1 -1
- nuitka/build/DataComposerInterface.py +15 -9
- nuitka/build/Onefile.scons +1 -1
- nuitka/build/SconsCompilerSettings.py +1 -0
- nuitka/build/SconsProgress.py +11 -2
- nuitka/build/SconsSpawn.py +15 -15
- nuitka/build/include/nuitka/builtins.h +2 -0
- nuitka/build/include/nuitka/filesystem_paths.h +4 -0
- nuitka/build/include/nuitka/helper/attributes.h +3 -0
- nuitka/build/include/nuitka/helper/import_hard.h +6 -0
- nuitka/build/include/nuitka/helpers.h +1 -1
- nuitka/build/include/nuitka/safe_string_ops.h +10 -3
- nuitka/build/static_src/CompiledCodeHelpers.c +0 -200
- nuitka/build/static_src/HelpersAttributes.c +185 -8
- nuitka/build/static_src/HelpersFilesystemPaths.c +528 -7
- nuitka/build/static_src/HelpersImportHard.c +38 -0
- nuitka/build/static_src/HelpersSafeStrings.c +6 -278
- nuitka/build/static_src/MainProgram.c +273 -73
- nuitka/build/static_src/MetaPathBasedLoaderResourceReaderFiles.c +6 -0
- nuitka/build/static_src/OnefileBootstrap.c +19 -36
- nuitka/build/static_src/OnefileSplashScreen.cpp +1 -0
- nuitka/code_generation/AttributeCodes.py +42 -23
- nuitka/code_generation/CodeGeneration.py +4 -0
- nuitka/code_generation/FunctionCodes.py +18 -3
- nuitka/code_generation/GlobalConstants.py +8 -1
- nuitka/code_generation/PackageResourceCodes.py +40 -0
- nuitka/code_generation/templates/CodeTemplatesModules.py +1 -7
- nuitka/freezer/DllDependenciesMacOS.py +18 -1
- nuitka/freezer/IncludedDataFiles.py +6 -10
- nuitka/importing/ImportResolving.py +6 -0
- nuitka/importing/Recursion.py +24 -68
- nuitka/nodes/AttributeNodes.py +72 -19
- nuitka/nodes/ChildrenHavingMixins.py +203 -234
- nuitka/nodes/ExpressionBasesGenerated.py +136 -0
- nuitka/nodes/HardImportNodesGenerated.py +94 -0
- nuitka/nodes/ImportHardNodes.py +3 -3
- nuitka/nodes/ImportNodes.py +14 -4
- nuitka/nodes/ModuleNodes.py +4 -2
- nuitka/nodes/PackageMetadataNodes.py +12 -10
- nuitka/nodes/PackageResourceNodes.py +115 -0
- nuitka/nodes/TypeNodes.py +5 -1
- nuitka/plugins/PluginBase.py +32 -8
- nuitka/plugins/Plugins.py +44 -7
- nuitka/plugins/standard/AntiBloatPlugin.py +166 -72
- nuitka/plugins/standard/DataFilesPlugin.py +10 -0
- nuitka/plugins/standard/DllFilesPlugin.py +1 -2
- nuitka/plugins/standard/MatplotlibPlugin.py +24 -22
- nuitka/plugins/standard/MultiprocessingPlugin.py +5 -12
- nuitka/plugins/standard/OptionsNannyPlugin.py +2 -2
- nuitka/plugins/standard/PySidePyQtPlugin.py +18 -6
- nuitka/plugins/standard/PywebViewPlugin.py +4 -2
- nuitka/plugins/standard/TkinterPlugin.py +3 -0
- nuitka/plugins/standard/TransformersPlugin.py +11 -1
- nuitka/plugins/standard/TrioPlugin.py +6 -66
- nuitka/plugins/standard/standard.nuitka-package.config.yml +367 -21
- nuitka/plugins/standard/stdlib3.nuitka-package.config.yml +16 -4
- nuitka/specs/HardImportSpecs.py +6 -0
- nuitka/tools/data_composer/DataComposer.py +25 -27
- nuitka/tools/general/find_module/FindModuleCode.py +5 -2
- nuitka/tools/podman/Podman.py +53 -0
- nuitka/tools/podman/__init__.py +18 -0
- nuitka/tools/podman/__main__.py +255 -0
- nuitka/tools/specialize/SpecializePython.py +37 -3
- nuitka/tools/testing/RuntimeTracing.py +4 -0
- nuitka/tree/Building.py +1 -1
- nuitka/tree/ReformulationFunctionStatements.py +137 -10
- nuitka/utils/Execution.py +11 -1
- nuitka/utils/ModuleNames.py +1 -1
- nuitka/utils/SharedLibraries.py +7 -7
- {Nuitka_winsvc-1.6.6.data → Nuitka_winsvc-1.7.5.data}/scripts/nuitka-run.bat +0 -0
- {Nuitka_winsvc-1.6.6.data → Nuitka_winsvc-1.7.5.data}/scripts/nuitka.bat +0 -0
- {Nuitka_winsvc-1.6.6.dist-info → Nuitka_winsvc-1.7.5.dist-info}/LICENSE.txt +0 -0
- {Nuitka_winsvc-1.6.6.dist-info → Nuitka_winsvc-1.7.5.dist-info}/WHEEL +0 -0
- {Nuitka_winsvc-1.6.6.dist-info → Nuitka_winsvc-1.7.5.dist-info}/entry_points.txt +0 -0
- {Nuitka_winsvc-1.6.6.dist-info → Nuitka_winsvc-1.7.5.dist-info}/top_level.txt +0 -0
nuitka/plugins/PluginBase.py
CHANGED
|
@@ -28,10 +28,12 @@ it being used.
|
|
|
28
28
|
|
|
29
29
|
import ast
|
|
30
30
|
import functools
|
|
31
|
+
import imp
|
|
31
32
|
import inspect
|
|
32
33
|
import os
|
|
33
34
|
import sys
|
|
34
35
|
|
|
36
|
+
from nuitka import Options
|
|
35
37
|
from nuitka.__past__ import getMetaClassBase
|
|
36
38
|
from nuitka.containers.Namedtuples import makeNamedtupleClass
|
|
37
39
|
from nuitka.containers.OrderedSets import OrderedSet
|
|
@@ -61,7 +63,10 @@ from nuitka.Options import (
|
|
|
61
63
|
shallShowExecutedCommands,
|
|
62
64
|
)
|
|
63
65
|
from nuitka.PythonFlavors import isAnacondaPython, isDebianPackagePython
|
|
64
|
-
from nuitka.PythonVersions import
|
|
66
|
+
from nuitka.PythonVersions import (
|
|
67
|
+
getTestExecutionPythonVersions,
|
|
68
|
+
python_version,
|
|
69
|
+
)
|
|
65
70
|
from nuitka.Tracing import plugins_logger
|
|
66
71
|
from nuitka.utils.Distributions import isDistributionCondaPackage
|
|
67
72
|
from nuitka.utils.Execution import NuitkaCalledProcessError, check_output
|
|
@@ -84,6 +89,10 @@ _warned_unused_plugins = set()
|
|
|
84
89
|
# TODO: Could share data cache with meta data nodes
|
|
85
90
|
_package_versions = {}
|
|
86
91
|
|
|
92
|
+
# Populated during plugin instance creation from their tags given by
|
|
93
|
+
# "getEvaluationConditionControlTags" value.
|
|
94
|
+
control_tags = {}
|
|
95
|
+
|
|
87
96
|
|
|
88
97
|
def _convertVersionToTuple(version_str):
|
|
89
98
|
def numberize(v):
|
|
@@ -418,10 +427,13 @@ class NuitkaPluginBase(getMetaClassBase("Plugin")):
|
|
|
418
427
|
# Virtual method, pylint: disable=no-self-use,unused-argument
|
|
419
428
|
return ()
|
|
420
429
|
|
|
421
|
-
def onModuleEncounter(
|
|
430
|
+
def onModuleEncounter(
|
|
431
|
+
self, using_module_name, module_name, module_filename, module_kind
|
|
432
|
+
):
|
|
422
433
|
"""Help decide whether to include a module.
|
|
423
434
|
|
|
424
435
|
Args:
|
|
436
|
+
using_module_name: module that does this (can be None if user)
|
|
425
437
|
module_name: full module name
|
|
426
438
|
module_filename: filename
|
|
427
439
|
module_kind: one of "py", "extension" (shared library)
|
|
@@ -432,7 +444,7 @@ class NuitkaPluginBase(getMetaClassBase("Plugin")):
|
|
|
432
444
|
return None
|
|
433
445
|
|
|
434
446
|
def onModuleRecursion(
|
|
435
|
-
self, module_name, module_filename, module_kind,
|
|
447
|
+
self, module_name, module_filename, module_kind, using_module_name, source_ref
|
|
436
448
|
):
|
|
437
449
|
"""React to recursion to a module coming up.
|
|
438
450
|
|
|
@@ -440,7 +452,7 @@ class NuitkaPluginBase(getMetaClassBase("Plugin")):
|
|
|
440
452
|
module_name: full module name
|
|
441
453
|
module_filename: filename
|
|
442
454
|
module_kind: one of "py", "extension" (shared library)
|
|
443
|
-
|
|
455
|
+
using_module_name: name of module that does the usage (None if it is a user choice)
|
|
444
456
|
source_ref: code making the import (None if it is a user choice)
|
|
445
457
|
Returns:
|
|
446
458
|
None
|
|
@@ -1066,9 +1078,12 @@ except ImportError:
|
|
|
1066
1078
|
).key
|
|
1067
1079
|
|
|
1068
1080
|
def onFunctionBodyParsing(self, module_name, function_name, body):
|
|
1069
|
-
"""Provide a different function body for the function of that module.
|
|
1081
|
+
"""Provide a different function body for the function of that module.
|
|
1082
|
+
|
|
1083
|
+
Should return a boolean, indicating if any actual change was done.
|
|
1084
|
+
"""
|
|
1070
1085
|
# Virtual method, pylint: disable=no-self-use,unused-argument
|
|
1071
|
-
return
|
|
1086
|
+
return False
|
|
1072
1087
|
|
|
1073
1088
|
def getCacheContributionValues(self, module_name):
|
|
1074
1089
|
"""Provide values that represent the include of a plugin on the compilation.
|
|
@@ -1095,7 +1110,11 @@ except ImportError:
|
|
|
1095
1110
|
"""Provide package version of a distribution."""
|
|
1096
1111
|
return _getPackageVersion(distribution_name)
|
|
1097
1112
|
|
|
1098
|
-
def
|
|
1113
|
+
def getEvaluationConditionControlTags(self):
|
|
1114
|
+
# Virtual method, pylint: disable=no-self-use
|
|
1115
|
+
return {}
|
|
1116
|
+
|
|
1117
|
+
def evaluateCondition(self, full_name, condition):
|
|
1099
1118
|
# Note: Caching makes no sense yet, this should all be very fast and
|
|
1100
1119
|
# cache themselves. TODO: Allow plugins to contribute their own control
|
|
1101
1120
|
# tag values during creation and during certain actions.
|
|
@@ -1125,6 +1144,8 @@ except ImportError:
|
|
|
1125
1144
|
"no_asserts": hasPythonFlagNoAsserts(),
|
|
1126
1145
|
"no_docstrings": hasPythonFlagNoDocStrings(),
|
|
1127
1146
|
"no_annotations": hasPythonFlagNoAnnotations(),
|
|
1147
|
+
# Querying package properties
|
|
1148
|
+
"has_builtin_module": imp.is_builtin,
|
|
1128
1149
|
}
|
|
1129
1150
|
)
|
|
1130
1151
|
|
|
@@ -1137,7 +1158,7 @@ except ImportError:
|
|
|
1137
1158
|
}
|
|
1138
1159
|
)
|
|
1139
1160
|
|
|
1140
|
-
versions =
|
|
1161
|
+
versions = getTestExecutionPythonVersions()
|
|
1141
1162
|
|
|
1142
1163
|
for version in versions:
|
|
1143
1164
|
big, major = version.split(".")
|
|
@@ -1154,6 +1175,9 @@ except ImportError:
|
|
|
1154
1175
|
try:
|
|
1155
1176
|
result = eval(condition, context)
|
|
1156
1177
|
except Exception as e: # Catch all the things, pylint: disable=broad-except
|
|
1178
|
+
if Options.is_debug:
|
|
1179
|
+
raise
|
|
1180
|
+
|
|
1157
1181
|
self.sysexit(
|
|
1158
1182
|
"Error, failed to evaluate condition '%s' in this context, exception was '%s'."
|
|
1159
1183
|
% (condition, e)
|
nuitka/plugins/Plugins.py
CHANGED
|
@@ -57,7 +57,7 @@ from nuitka.utils.ModuleNames import (
|
|
|
57
57
|
pre_module_load_trigger_name,
|
|
58
58
|
)
|
|
59
59
|
|
|
60
|
-
from .PluginBase import NuitkaPluginBase
|
|
60
|
+
from .PluginBase import NuitkaPluginBase, control_tags
|
|
61
61
|
|
|
62
62
|
# Maps plugin name to plugin instances.
|
|
63
63
|
active_plugins = OrderedDict()
|
|
@@ -127,12 +127,30 @@ def _addActivePlugin(plugin_class, args, force=False):
|
|
|
127
127
|
|
|
128
128
|
active_plugins[plugin_name] = plugin_instance
|
|
129
129
|
|
|
130
|
+
is_gui_toolkit_plugin = getattr(plugin_class, "plugin_gui_toolkit", False)
|
|
131
|
+
|
|
130
132
|
# Singleton, pylint: disable=global-statement
|
|
131
133
|
global has_active_gui_toolkit_plugin
|
|
132
|
-
has_active_gui_toolkit_plugin =
|
|
133
|
-
|
|
134
|
+
has_active_gui_toolkit_plugin = (
|
|
135
|
+
has_active_gui_toolkit_plugin or is_gui_toolkit_plugin
|
|
134
136
|
)
|
|
135
137
|
|
|
138
|
+
# Do GUI toolkit exclusion control tags generically. You may have two of
|
|
139
|
+
# them and we don't want them to override each other.
|
|
140
|
+
if is_gui_toolkit_plugin:
|
|
141
|
+
for binding_name in getGUIBindingNames():
|
|
142
|
+
is_matching = binding_name.lower() == plugin_class.binding_name.lower()
|
|
143
|
+
|
|
144
|
+
tag_name = "use_%s" % binding_name.lower()
|
|
145
|
+
|
|
146
|
+
# Set if matching, set to False only if not matching and not already set.
|
|
147
|
+
if is_matching:
|
|
148
|
+
control_tags[tag_name] = True
|
|
149
|
+
elif is_matching not in control_tags:
|
|
150
|
+
control_tags[tag_name] = False
|
|
151
|
+
|
|
152
|
+
control_tags.update(plugin_instance.getEvaluationConditionControlTags())
|
|
153
|
+
|
|
136
154
|
|
|
137
155
|
def getActivePlugins():
|
|
138
156
|
"""Return list of active plugins.
|
|
@@ -146,6 +164,7 @@ def getActivePlugins():
|
|
|
146
164
|
|
|
147
165
|
|
|
148
166
|
def getActiveQtPlugin():
|
|
167
|
+
"""Get active Qt plugin name."""
|
|
149
168
|
for plugin_name in getQtPluginNames():
|
|
150
169
|
if hasActivePlugin(plugin_name):
|
|
151
170
|
if hasActivePlugin(plugin_name):
|
|
@@ -154,6 +173,16 @@ def getActiveQtPlugin():
|
|
|
154
173
|
return None
|
|
155
174
|
|
|
156
175
|
|
|
176
|
+
def getActiveQtPluginBindingName():
|
|
177
|
+
"""Get active Qt plugin binding name."""
|
|
178
|
+
plugin_name = getActiveQtPlugin()
|
|
179
|
+
|
|
180
|
+
if plugin_name is None:
|
|
181
|
+
return None
|
|
182
|
+
else:
|
|
183
|
+
return getPluginClass(plugin_name).binding_name
|
|
184
|
+
|
|
185
|
+
|
|
157
186
|
def getQtBindingNames():
|
|
158
187
|
return ("PySide", "PySide2", "PySide6", "PyQt4", "PyQt5", "PyQt6")
|
|
159
188
|
|
|
@@ -162,6 +191,10 @@ def getOtherGUIBindingNames():
|
|
|
162
191
|
return ("wx", "tkinter", "Tkinter")
|
|
163
192
|
|
|
164
193
|
|
|
194
|
+
def getGUIBindingNames():
|
|
195
|
+
return getQtBindingNames() + getOtherGUIBindingNames()
|
|
196
|
+
|
|
197
|
+
|
|
165
198
|
def getQtPluginNames():
|
|
166
199
|
return tuple(qt_binding_name.lower() for qt_binding_name in getQtBindingNames())
|
|
167
200
|
|
|
@@ -428,6 +461,7 @@ class Plugins(object):
|
|
|
428
461
|
|
|
429
462
|
# This will get back to all other plugins allowing them to inhibit it though.
|
|
430
463
|
decision, reason = Recursion.decideRecursion(
|
|
464
|
+
using_module_name=module.getFullName(),
|
|
431
465
|
module_filename=module_filename,
|
|
432
466
|
module_name=full_name,
|
|
433
467
|
module_kind=module_kind,
|
|
@@ -439,7 +473,7 @@ class Plugins(object):
|
|
|
439
473
|
module_name=full_name,
|
|
440
474
|
module_filename=module_filename,
|
|
441
475
|
module_kind=module_kind,
|
|
442
|
-
|
|
476
|
+
using_module_name=module.module_name,
|
|
443
477
|
source_ref=module.getSourceReference(),
|
|
444
478
|
reason=reason,
|
|
445
479
|
)
|
|
@@ -969,12 +1003,13 @@ class Plugins(object):
|
|
|
969
1003
|
return bytecode
|
|
970
1004
|
|
|
971
1005
|
@staticmethod
|
|
972
|
-
def onModuleEncounter(module_name, module_filename, module_kind):
|
|
1006
|
+
def onModuleEncounter(using_module_name, module_name, module_filename, module_kind):
|
|
973
1007
|
result = None
|
|
974
1008
|
deciding_plugins = []
|
|
975
1009
|
|
|
976
1010
|
for plugin in getActivePlugins():
|
|
977
1011
|
must_recurse = plugin.onModuleEncounter(
|
|
1012
|
+
using_module_name=using_module_name,
|
|
978
1013
|
module_name=module_name,
|
|
979
1014
|
module_filename=module_filename,
|
|
980
1015
|
module_kind=module_kind,
|
|
@@ -1002,14 +1037,14 @@ class Plugins(object):
|
|
|
1002
1037
|
|
|
1003
1038
|
@staticmethod
|
|
1004
1039
|
def onModuleRecursion(
|
|
1005
|
-
module_name, module_filename, module_kind,
|
|
1040
|
+
module_name, module_filename, module_kind, using_module_name, source_ref
|
|
1006
1041
|
):
|
|
1007
1042
|
for plugin in getActivePlugins():
|
|
1008
1043
|
plugin.onModuleRecursion(
|
|
1009
1044
|
module_name=module_name,
|
|
1010
1045
|
module_filename=module_filename,
|
|
1011
1046
|
module_kind=module_kind,
|
|
1012
|
-
|
|
1047
|
+
using_module_name=using_module_name,
|
|
1013
1048
|
source_ref=source_ref,
|
|
1014
1049
|
)
|
|
1015
1050
|
|
|
@@ -1281,6 +1316,8 @@ class Plugins(object):
|
|
|
1281
1316
|
module_name = provider.getParentModule().getFullName()
|
|
1282
1317
|
|
|
1283
1318
|
for plugin in getActivePlugins():
|
|
1319
|
+
# TODO: Could record what functions got modified by what plugin
|
|
1320
|
+
# and in what way checking the return value
|
|
1284
1321
|
plugin.onFunctionBodyParsing(
|
|
1285
1322
|
module_name=module_name,
|
|
1286
1323
|
function_name=function_name,
|
|
@@ -33,7 +33,7 @@ from nuitka.plugins.PluginBase import NuitkaPluginBase
|
|
|
33
33
|
from nuitka.utils.ModuleNames import ModuleName
|
|
34
34
|
from nuitka.utils.Yaml import getYamlPackageConfiguration
|
|
35
35
|
|
|
36
|
-
# spell-checker: ignore dask,numba
|
|
36
|
+
# spell-checker: ignore dask,numba,statsmodels,matplotlib
|
|
37
37
|
|
|
38
38
|
_mode_choices = ("error", "warning", "nofollow", "allow")
|
|
39
39
|
|
|
@@ -86,47 +86,66 @@ class NuitkaPluginAntiBloat(NuitkaPluginBase):
|
|
|
86
86
|
self.control_tags = OrderedDict()
|
|
87
87
|
|
|
88
88
|
if noinclude_setuptools_mode != "allow":
|
|
89
|
-
self.handled_modules["setuptools"] = noinclude_setuptools_mode
|
|
90
|
-
self.handled_modules["setuptools_scm"] =
|
|
89
|
+
self.handled_modules["setuptools"] = noinclude_setuptools_mode, "setuptools"
|
|
90
|
+
self.handled_modules["setuptools_scm"] = (
|
|
91
|
+
noinclude_setuptools_mode,
|
|
92
|
+
"setuptools",
|
|
93
|
+
)
|
|
91
94
|
else:
|
|
92
95
|
self.control_tags["use_setuptools"] = True
|
|
93
96
|
|
|
94
97
|
if noinclude_pytest_mode != "allow":
|
|
95
|
-
self.handled_modules["_pytest"] = noinclude_pytest_mode
|
|
96
|
-
self.handled_modules["pytest"] = noinclude_pytest_mode
|
|
97
|
-
self.handled_modules["py"] = noinclude_pytest_mode
|
|
98
|
-
self.handled_modules["nose2"] = noinclude_pytest_mode
|
|
99
|
-
self.handled_modules["nose"] = noinclude_pytest_mode
|
|
98
|
+
self.handled_modules["_pytest"] = noinclude_pytest_mode, "pytest"
|
|
99
|
+
self.handled_modules["pytest"] = noinclude_pytest_mode, "pytest"
|
|
100
|
+
self.handled_modules["py"] = noinclude_pytest_mode, "pytest"
|
|
101
|
+
self.handled_modules["nose2"] = noinclude_pytest_mode, "pytest"
|
|
102
|
+
self.handled_modules["nose"] = noinclude_pytest_mode, "pytest"
|
|
103
|
+
self.handled_modules["statsmodels.tools._testing"] = (
|
|
104
|
+
noinclude_pytest_mode,
|
|
105
|
+
"pytest",
|
|
106
|
+
)
|
|
100
107
|
else:
|
|
101
108
|
self.control_tags["use_pytest"] = True
|
|
102
109
|
|
|
103
110
|
if noinclude_unittest_mode != "allow":
|
|
104
|
-
self.handled_modules["unittest"] = noinclude_unittest_mode
|
|
105
|
-
self.handled_modules["doctest"] = noinclude_unittest_mode
|
|
111
|
+
self.handled_modules["unittest"] = noinclude_unittest_mode, "unittest"
|
|
112
|
+
self.handled_modules["doctest"] = noinclude_unittest_mode, "unittest"
|
|
106
113
|
else:
|
|
107
114
|
self.control_tags["use_unittest"] = True
|
|
108
115
|
|
|
109
116
|
if noinclude_ipython_mode != "allow":
|
|
110
|
-
self.handled_modules["IPython"] = noinclude_ipython_mode
|
|
117
|
+
self.handled_modules["IPython"] = noinclude_ipython_mode, "IPython"
|
|
118
|
+
self.handled_modules["matplotlib_inline.backend_inline"] = (
|
|
119
|
+
noinclude_ipython_mode,
|
|
120
|
+
"IPython",
|
|
121
|
+
)
|
|
111
122
|
else:
|
|
112
123
|
self.control_tags["use_ipython"] = True
|
|
113
124
|
|
|
114
125
|
if noinclude_dask_mode != "allow":
|
|
115
|
-
self.handled_modules["dask"] = noinclude_dask_mode
|
|
126
|
+
self.handled_modules["dask"] = noinclude_dask_mode, "dask"
|
|
127
|
+
self.handled_modules["distributed"] = noinclude_dask_mode, "dask"
|
|
116
128
|
else:
|
|
117
129
|
self.control_tags["use_dask"] = True
|
|
118
130
|
|
|
119
131
|
if noinclude_numba_mode != "allow":
|
|
120
|
-
self.handled_modules["numba"] = noinclude_numba_mode
|
|
121
|
-
self.handled_modules["sparse"] = noinclude_numba_mode
|
|
132
|
+
self.handled_modules["numba"] = noinclude_numba_mode, "numba"
|
|
133
|
+
self.handled_modules["sparse"] = noinclude_numba_mode, "numba"
|
|
134
|
+
self.handled_modules["stumpy"] = noinclude_numba_mode, "numba"
|
|
135
|
+
self.handled_modules["pandas.core._numba.kernels"] = (
|
|
136
|
+
noinclude_numba_mode,
|
|
137
|
+
"numba",
|
|
138
|
+
)
|
|
122
139
|
else:
|
|
123
140
|
self.control_tags["use_numba"] = True
|
|
124
141
|
|
|
125
142
|
for custom_choice in custom_choices:
|
|
126
|
-
if ":"
|
|
143
|
+
if custom_choice.count(":") != 1:
|
|
127
144
|
self.sysexit(
|
|
128
|
-
"
|
|
129
|
-
|
|
145
|
+
"""\
|
|
146
|
+
Error, malformed value '%s' for '--noinclude-custom-mode' used. It has to be of \
|
|
147
|
+
form 'module_name:[%s]'."""
|
|
148
|
+
% (custom_choice, "|".join(_mode_choices))
|
|
130
149
|
)
|
|
131
150
|
|
|
132
151
|
module_name, mode = custom_choice.rsplit(":", 1)
|
|
@@ -137,19 +156,40 @@ class NuitkaPluginAntiBloat(NuitkaPluginBase):
|
|
|
137
156
|
% (mode, custom_choice)
|
|
138
157
|
)
|
|
139
158
|
|
|
140
|
-
self.handled_modules[ModuleName(module_name)] = mode
|
|
159
|
+
self.handled_modules[ModuleName(module_name)] = mode, module_name
|
|
141
160
|
|
|
142
161
|
if mode == "allow":
|
|
143
162
|
self.control_tags["use_%s" % module_name] = True
|
|
144
163
|
|
|
164
|
+
self.handled_module_namespaces = {}
|
|
165
|
+
|
|
166
|
+
for handled_module_name, (
|
|
167
|
+
mode,
|
|
168
|
+
intended_module_name,
|
|
169
|
+
) in self.handled_modules.items():
|
|
170
|
+
if mode == "warning":
|
|
171
|
+
if intended_module_name not in self.handled_module_namespaces:
|
|
172
|
+
self.handled_module_namespaces[intended_module_name] = set()
|
|
173
|
+
self.handled_module_namespaces[intended_module_name].add(
|
|
174
|
+
handled_module_name
|
|
175
|
+
)
|
|
176
|
+
|
|
145
177
|
self.warnings_given = set()
|
|
146
178
|
|
|
179
|
+
def getEvaluationConditionControlTags(self):
|
|
180
|
+
return self.control_tags
|
|
181
|
+
|
|
147
182
|
def getCacheContributionValues(self, module_name):
|
|
148
183
|
config = self.config.get(module_name, section="anti-bloat")
|
|
149
184
|
|
|
150
185
|
if config:
|
|
151
186
|
yield str(config)
|
|
152
187
|
|
|
188
|
+
# TODO: Until we can change the evaluation to tell us exactly what
|
|
189
|
+
# control tag values were used, we have to make this one. We sort
|
|
190
|
+
# the values, to try and have order changes in code not matter.
|
|
191
|
+
yield str(tuple(sorted(self.handled_modules.items())))
|
|
192
|
+
|
|
153
193
|
@classmethod
|
|
154
194
|
def addPluginCommandLineOptions(cls, group):
|
|
155
195
|
group.add_option(
|
|
@@ -382,10 +422,7 @@ which can and should be a top level package and then one choice, "error",
|
|
|
382
422
|
def onModuleSourceCode(self, module_name, source_code):
|
|
383
423
|
for anti_bloat_config in self.config.get(module_name, section="anti-bloat"):
|
|
384
424
|
if self.evaluateCondition(
|
|
385
|
-
full_name=module_name,
|
|
386
|
-
condition=anti_bloat_config.get("when", "True"),
|
|
387
|
-
# Allow disabling config for a module with matching control tags.
|
|
388
|
-
control_tags=self.control_tags,
|
|
425
|
+
full_name=module_name, condition=anti_bloat_config.get("when", "True")
|
|
389
426
|
):
|
|
390
427
|
source_code = self._onModuleSourceCode(
|
|
391
428
|
module_name=module_name,
|
|
@@ -414,79 +451,105 @@ which can and should be a top level package and then one choice, "error",
|
|
|
414
451
|
function_name,
|
|
415
452
|
)
|
|
416
453
|
|
|
417
|
-
if replace_code is
|
|
418
|
-
|
|
419
|
-
exec(context_code, context)
|
|
420
|
-
context_ready = True
|
|
454
|
+
if replace_code is None:
|
|
455
|
+
return False
|
|
421
456
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
self.sysexit(
|
|
426
|
-
"Error, cannot evaluate code '%s' in '%s' due to: %s"
|
|
427
|
-
% (replace_code, context_code, e)
|
|
428
|
-
)
|
|
457
|
+
if not context_ready:
|
|
458
|
+
exec(context_code, context)
|
|
459
|
+
context_ready = True
|
|
429
460
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
461
|
+
try:
|
|
462
|
+
replacement = eval(replace_code, context)
|
|
463
|
+
except Exception as e: # pylint: disable=broad-except
|
|
464
|
+
self.sysexit(
|
|
465
|
+
"Error, cannot evaluate code '%s' in '%s' due to: %s"
|
|
466
|
+
% (replace_code, context_code, e)
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
# Single node is required, extract the generated module body with
|
|
470
|
+
# single expression only statement value or a function body.
|
|
471
|
+
replacement = ast.parse(replacement).body[0]
|
|
472
|
+
|
|
473
|
+
if type(replacement) is ast.Expr:
|
|
474
|
+
if type(replacement.value) is ast.Lambda:
|
|
475
|
+
body[:] = [ast.Return(replacement.value.body)]
|
|
441
476
|
else:
|
|
442
|
-
body[:] = replacement.
|
|
477
|
+
body[:] = [ast.Return(replacement.value)]
|
|
478
|
+
elif type(replacement) is ast.Raise:
|
|
479
|
+
body[:] = [replacement]
|
|
480
|
+
else:
|
|
481
|
+
body[:] = replacement.body
|
|
443
482
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
483
|
+
if self.show_changes:
|
|
484
|
+
self.info(
|
|
485
|
+
"Updated module '%s' function '%s'."
|
|
486
|
+
% (module_name.asString(), function_name)
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
return True
|
|
449
490
|
|
|
450
491
|
def onFunctionBodyParsing(self, module_name, function_name, body):
|
|
492
|
+
result = False
|
|
493
|
+
|
|
451
494
|
config = self.config.get(module_name, section="anti-bloat")
|
|
452
495
|
|
|
453
496
|
if config:
|
|
454
497
|
for anti_bloat_config in config:
|
|
455
|
-
self._onFunctionBodyParsing(
|
|
498
|
+
if self._onFunctionBodyParsing(
|
|
456
499
|
module_name=module_name,
|
|
457
500
|
anti_bloat_config=anti_bloat_config,
|
|
458
501
|
function_name=function_name,
|
|
459
502
|
body=body,
|
|
460
|
-
)
|
|
503
|
+
):
|
|
504
|
+
result = True
|
|
505
|
+
|
|
506
|
+
return result
|
|
461
507
|
|
|
462
508
|
def onModuleRecursion(
|
|
463
|
-
self, module_name, module_filename, module_kind,
|
|
509
|
+
self, module_name, module_filename, module_kind, using_module_name, source_ref
|
|
464
510
|
):
|
|
465
|
-
|
|
511
|
+
# This will allow "unittest.mock" to pass these things.
|
|
512
|
+
if module_name == "unittest.mock" and module_name not in self.handled_modules:
|
|
513
|
+
return
|
|
514
|
+
|
|
515
|
+
for handled_module_name, (
|
|
516
|
+
mode,
|
|
517
|
+
intended_module_name,
|
|
518
|
+
) in self.handled_modules.items():
|
|
519
|
+
# This will ignore internal usages. In case of error, e.g. above unittest
|
|
520
|
+
# could cause them to happen.
|
|
521
|
+
if using_module_name is not None and using_module_name.hasNamespace(
|
|
522
|
+
handled_module_name
|
|
523
|
+
):
|
|
524
|
+
return
|
|
525
|
+
|
|
466
526
|
if module_name.hasNamespace(handled_module_name):
|
|
467
527
|
# Make sure the compilation aborts or warns if asked to
|
|
468
528
|
if mode == "error":
|
|
469
|
-
raise NuitkaForbiddenImportEncounter(
|
|
470
|
-
|
|
471
|
-
(
|
|
472
|
-
using_module is None
|
|
473
|
-
or not using_module.getFullName().hasNamespace(
|
|
474
|
-
handled_module_name
|
|
475
|
-
)
|
|
529
|
+
raise NuitkaForbiddenImportEncounter(
|
|
530
|
+
module_name, intended_module_name
|
|
476
531
|
)
|
|
477
|
-
|
|
478
|
-
|
|
532
|
+
if mode == "warning" and source_ref is not None:
|
|
533
|
+
if using_module_name.hasOneOfNamespaces(
|
|
534
|
+
self.handled_module_namespaces[intended_module_name]
|
|
535
|
+
):
|
|
536
|
+
continue
|
|
537
|
+
|
|
479
538
|
key = (
|
|
480
|
-
|
|
481
|
-
|
|
539
|
+
module_name,
|
|
540
|
+
using_module_name,
|
|
482
541
|
source_ref.getLineNumber(),
|
|
483
542
|
)
|
|
543
|
+
|
|
484
544
|
if key not in self.warnings_given:
|
|
485
545
|
self.warning(
|
|
486
|
-
"
|
|
546
|
+
"""\
|
|
547
|
+
Undesirable import of '%s' (intending to avoid '%s') in \
|
|
548
|
+
'%s' (at '%s') encountered. It may slow down compilation."""
|
|
487
549
|
% (
|
|
488
550
|
handled_module_name,
|
|
489
|
-
|
|
551
|
+
intended_module_name,
|
|
552
|
+
using_module_name,
|
|
490
553
|
source_ref.getAsString(),
|
|
491
554
|
),
|
|
492
555
|
mnemonic="unwanted-module",
|
|
@@ -494,26 +557,57 @@ which can and should be a top level package and then one choice, "error",
|
|
|
494
557
|
|
|
495
558
|
self.warnings_given.add(key)
|
|
496
559
|
|
|
497
|
-
def onModuleEncounter(
|
|
498
|
-
|
|
560
|
+
def onModuleEncounter(
|
|
561
|
+
self, using_module_name, module_name, module_filename, module_kind
|
|
562
|
+
):
|
|
563
|
+
for handled_module_name, (
|
|
564
|
+
mode,
|
|
565
|
+
intended_module_name,
|
|
566
|
+
) in self.handled_modules.items():
|
|
499
567
|
if module_name.hasNamespace(handled_module_name):
|
|
500
568
|
# Either issue a warning, or pretend the module doesn't exist for standalone or
|
|
501
569
|
# at least will not be included.
|
|
502
570
|
if mode == "nofollow":
|
|
503
571
|
if self.show_changes:
|
|
504
572
|
self.info(
|
|
505
|
-
"Forcing import of '%s' to not be followed."
|
|
573
|
+
"Forcing import of '%s' (intending to avoid '%s') to not be followed."
|
|
574
|
+
% (module_name, intended_module_name)
|
|
506
575
|
)
|
|
507
576
|
return (
|
|
508
577
|
False,
|
|
509
|
-
"user requested to not follow '%s'
|
|
578
|
+
"user requested to not follow '%s' (intending to avoid '%s') import"
|
|
579
|
+
% (module_name, intended_module_name),
|
|
510
580
|
)
|
|
511
581
|
|
|
582
|
+
if using_module_name is not None:
|
|
583
|
+
config = self.config.get(using_module_name, section="anti-bloat")
|
|
584
|
+
|
|
585
|
+
if config:
|
|
586
|
+
for anti_bloat_config in config:
|
|
587
|
+
match, reason = module_name.matchesToShellPatterns(
|
|
588
|
+
anti_bloat_config.get("no-auto-follow", ())
|
|
589
|
+
)
|
|
590
|
+
|
|
591
|
+
if match:
|
|
592
|
+
if self.evaluateCondition(
|
|
593
|
+
full_name=module_name,
|
|
594
|
+
condition=anti_bloat_config.get("when", "True"),
|
|
595
|
+
):
|
|
596
|
+
|
|
597
|
+
return (
|
|
598
|
+
False,
|
|
599
|
+
"according to yaml 'no-auto-follow' configuration of '%s' and '%s'"
|
|
600
|
+
% (using_module_name, reason),
|
|
601
|
+
)
|
|
602
|
+
|
|
512
603
|
# Do not provide an opinion about it.
|
|
513
604
|
return None
|
|
514
605
|
|
|
515
606
|
def decideCompilation(self, module_name):
|
|
516
|
-
for handled_module_name,
|
|
607
|
+
for handled_module_name, (
|
|
608
|
+
mode,
|
|
609
|
+
_intended_module_name,
|
|
610
|
+
) in self.handled_modules.items():
|
|
517
611
|
if mode != "bytecode":
|
|
518
612
|
continue
|
|
519
613
|
|
|
@@ -23,9 +23,11 @@ import os
|
|
|
23
23
|
import pkgutil
|
|
24
24
|
|
|
25
25
|
from nuitka import Options
|
|
26
|
+
from nuitka.code_generation.ConstantCodes import addDistributionMetadataValue
|
|
26
27
|
from nuitka.containers.OrderedSets import OrderedSet
|
|
27
28
|
from nuitka.plugins.PluginBase import NuitkaPluginBase
|
|
28
29
|
from nuitka.PythonFlavors import isDebianPackagePython
|
|
30
|
+
from nuitka.utils.Distributions import getDistribution
|
|
29
31
|
from nuitka.utils.FileOperations import (
|
|
30
32
|
changeFilenameExtension,
|
|
31
33
|
getFileList,
|
|
@@ -168,6 +170,14 @@ class NuitkaPluginDataFileCollector(NuitkaPluginBase):
|
|
|
168
170
|
tags="config",
|
|
169
171
|
)
|
|
170
172
|
|
|
173
|
+
distribution_names = data_file_config.get("include-metadata", ())
|
|
174
|
+
|
|
175
|
+
for distribution_name in distribution_names:
|
|
176
|
+
distribution = getDistribution(distribution_name)
|
|
177
|
+
|
|
178
|
+
if distribution is not None:
|
|
179
|
+
addDistributionMetadataValue(distribution_name, distribution)
|
|
180
|
+
|
|
171
181
|
def considerDataFiles(self, module):
|
|
172
182
|
full_name = module.getFullName()
|
|
173
183
|
|
|
@@ -157,8 +157,7 @@ class NuitkaPluginDllFiles(NuitkaPluginBase):
|
|
|
157
157
|
def _handleDllConfigByCode(self, dll_config, full_name, dest_path, count):
|
|
158
158
|
# The "when" is at that level too for these.
|
|
159
159
|
if not self.evaluateCondition(
|
|
160
|
-
full_name=full_name,
|
|
161
|
-
condition=dll_config.get("when", "True"),
|
|
160
|
+
full_name=full_name, condition=dll_config.get("when", "True")
|
|
162
161
|
):
|
|
163
162
|
return
|
|
164
163
|
|