Nuitka-winsvc 1.8.6__cp312-cp312-win_amd64.whl → 1.9.3__cp312-cp312-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.
Files changed (214) hide show
  1. {Nuitka_winsvc-1.8.6.dist-info → Nuitka_winsvc-1.9.3.dist-info}/METADATA +1 -1
  2. {Nuitka_winsvc-1.8.6.dist-info → Nuitka_winsvc-1.9.3.dist-info}/RECORD +212 -203
  3. {Nuitka_winsvc-1.8.6.dist-info → Nuitka_winsvc-1.9.3.dist-info}/WHEEL +1 -1
  4. nuitka/BytecodeCaching.py +4 -1
  5. nuitka/HardImportRegistry.py +348 -0
  6. nuitka/MainControl.py +45 -25
  7. nuitka/OptionParsing.py +31 -20
  8. nuitka/Options.py +47 -16
  9. nuitka/Progress.py +32 -2
  10. nuitka/PythonFlavors.py +1 -1
  11. nuitka/PythonVersions.py +61 -0
  12. nuitka/Tracing.py +25 -12
  13. nuitka/TreeXML.py +5 -5
  14. nuitka/Variables.py +15 -24
  15. nuitka/Version.py +16 -6
  16. nuitka/__main__.py +15 -0
  17. nuitka/__past__.py +15 -17
  18. nuitka/build/Backend.scons +44 -35
  19. nuitka/build/CCompilerVersion.scons +10 -9
  20. nuitka/build/Onefile.scons +11 -26
  21. nuitka/build/SconsCaching.py +2 -0
  22. nuitka/build/SconsCompilerSettings.py +72 -22
  23. nuitka/build/SconsHacks.py +1 -0
  24. nuitka/build/SconsInterface.py +5 -0
  25. nuitka/build/SconsSpawn.py +16 -3
  26. nuitka/build/SconsUtils.py +11 -12
  27. nuitka/build/include/nuitka/checksum_tools.h +0 -4
  28. nuitka/build/include/nuitka/compiled_asyncgen.h +1 -1
  29. nuitka/build/include/nuitka/compiled_coroutine.h +1 -1
  30. nuitka/build/include/nuitka/compiled_frame.h +7 -4
  31. nuitka/build/include/nuitka/compiled_function.h +13 -3
  32. nuitka/build/include/nuitka/compiled_generator.h +1 -1
  33. nuitka/build/include/nuitka/constants.h +2 -0
  34. nuitka/build/include/nuitka/environment_variables.h +45 -0
  35. nuitka/build/include/nuitka/exceptions.h +32 -4
  36. nuitka/build/include/nuitka/filesystem_paths.h +6 -1
  37. nuitka/build/include/nuitka/freelists.h +11 -1
  38. nuitka/build/include/nuitka/helper/dictionaries.h +1 -1
  39. nuitka/build/include/nuitka/helper/import_hard.h +3 -0
  40. nuitka/build/include/nuitka/helpers.h +2 -0
  41. nuitka/build/include/nuitka/importing.h +3 -0
  42. nuitka/build/include/nuitka/prelude.h +17 -6
  43. nuitka/build/include/nuitka/unfreezing.h +1 -1
  44. nuitka/build/inline_copy/bin/scons.py +14 -0
  45. nuitka/build/inline_copy/tqdm/tqdm/__init__.py +2 -2
  46. nuitka/build/inline_copy/tqdm/tqdm/utils.py +14 -8
  47. nuitka/build/inline_copy/zlib/LICENSE +22 -0
  48. nuitka/build/inline_copy/zlib/crc32.c +1049 -0
  49. nuitka/build/inline_copy/zlib/crc32.h +9446 -0
  50. nuitka/build/inline_copy/zlib/zconf.h +551 -0
  51. nuitka/build/inline_copy/zlib/zlib.h +1938 -0
  52. nuitka/build/inline_copy/zlib/zutil.h +275 -0
  53. nuitka/build/static_src/CompiledAsyncgenType.c +41 -41
  54. nuitka/build/static_src/CompiledCodeHelpers.c +14 -7
  55. nuitka/build/static_src/CompiledCoroutineType.c +60 -51
  56. nuitka/build/static_src/CompiledFrameType.c +12 -12
  57. nuitka/build/static_src/CompiledFunctionType.c +149 -28
  58. nuitka/build/static_src/CompiledGeneratorType.c +64 -65
  59. nuitka/build/static_src/CompiledGeneratorTypeUncompiledIntegration.c +1 -1
  60. nuitka/build/static_src/CompiledMethodType.c +5 -3
  61. nuitka/build/static_src/HelperEnvironmentVariables.c +120 -0
  62. nuitka/build/static_src/HelpersAttributes.c +1 -1
  63. nuitka/build/static_src/HelpersBuiltin.c +1 -1
  64. nuitka/build/static_src/HelpersChecksumTools.c +19 -4
  65. nuitka/build/static_src/HelpersComparisonEq.c +4 -4
  66. nuitka/build/static_src/HelpersComparisonNe.c +4 -4
  67. nuitka/build/static_src/HelpersConstantsBlob.c +40 -23
  68. nuitka/build/static_src/HelpersDictionaries.c +3 -1
  69. nuitka/build/static_src/HelpersDictionariesGenerated.c +9 -9
  70. nuitka/build/static_src/HelpersFilesystemPaths.c +12 -2
  71. nuitka/build/static_src/HelpersImport.c +29 -1
  72. nuitka/build/static_src/HelpersImportHard.c +19 -0
  73. nuitka/build/static_src/HelpersOperationInplaceAddUtils.c +5 -4
  74. nuitka/build/static_src/HelpersPythonPgo.c +5 -5
  75. nuitka/build/static_src/HelpersSafeStrings.c +2 -1
  76. nuitka/build/static_src/HelpersStrings.c +12 -10
  77. nuitka/build/static_src/HelpersTypes.c +1 -1
  78. nuitka/build/static_src/InspectPatcher.c +3 -2
  79. nuitka/build/static_src/MainProgram.c +182 -214
  80. nuitka/build/static_src/MetaPathBasedLoader.c +36 -23
  81. nuitka/build/static_src/MetaPathBasedLoaderImportlibMetadataDistribution.c +4 -2
  82. nuitka/build/static_src/MetaPathBasedLoaderResourceReaderFiles.c +38 -2
  83. nuitka/build/static_src/OnefileBootstrap.c +124 -93
  84. nuitka/code_generation/CodeGeneration.py +4 -2
  85. nuitka/code_generation/CodeObjectCodes.py +5 -1
  86. nuitka/code_generation/ConstantCodes.py +4 -0
  87. nuitka/code_generation/Contexts.py +111 -3
  88. nuitka/code_generation/DictCodes.py +5 -5
  89. nuitka/code_generation/FunctionCodes.py +4 -2
  90. nuitka/code_generation/GlobalConstants.py +10 -0
  91. nuitka/code_generation/ImportCodes.py +69 -33
  92. nuitka/code_generation/ModuleCodes.py +4 -1
  93. nuitka/code_generation/Namify.py +6 -5
  94. nuitka/code_generation/YieldCodes.py +3 -3
  95. nuitka/code_generation/templates/CodeTemplatesModules.py +61 -95
  96. nuitka/code_generation/templates_c/HelperDictionaryCopy.c.j2 +3 -3
  97. nuitka/code_generation/templates_c/HelperOperationComparisonUnicode.c.j2 +2 -2
  98. nuitka/distutils/DistutilCommands.py +3 -0
  99. nuitka/finalizations/FinalizeMarkups.py +1 -1
  100. nuitka/freezer/DependsExe.py +2 -1
  101. nuitka/freezer/DllDependenciesPosix.py +11 -1
  102. nuitka/freezer/IncludedEntryPoints.py +54 -16
  103. nuitka/freezer/Onefile.py +7 -3
  104. nuitka/freezer/Standalone.py +39 -17
  105. nuitka/importing/Importing.py +195 -62
  106. nuitka/importing/PreloadedPackages.py +2 -1
  107. nuitka/importing/Recursion.py +98 -27
  108. nuitka/importing/StandardLibrary.py +7 -4
  109. nuitka/nodes/BuiltinOpenNodes.py +28 -1
  110. nuitka/nodes/BuiltinRangeNodes.py +2 -2
  111. nuitka/nodes/BuiltinSumNodes.py +1 -1
  112. nuitka/nodes/ChildrenHavingMixins.py +326 -2
  113. nuitka/nodes/HardImportNodesGenerated.py +141 -38
  114. nuitka/nodes/ImportHardNodes.py +0 -8
  115. nuitka/nodes/ImportNodes.py +267 -361
  116. nuitka/nodes/IterationHandles.py +36 -17
  117. nuitka/nodes/LocalsScopes.py +3 -1
  118. nuitka/nodes/NodeBases.py +8 -14
  119. nuitka/nodes/OperatorNodes.py +9 -9
  120. nuitka/nodes/OutlineNodes.py +3 -3
  121. nuitka/nodes/PackageMetadataNodes.py +19 -9
  122. nuitka/nodes/SliceNodes.py +1 -1
  123. nuitka/nodes/VariableAssignNodes.py +25 -15
  124. nuitka/nodes/VariableRefNodes.py +7 -7
  125. nuitka/nodes/YieldNodes.py +2 -2
  126. nuitka/nodes/shapes/BuiltinTypeShapes.py +81 -6
  127. nuitka/nodes/shapes/ShapeMixins.py +21 -0
  128. nuitka/nodes/shapes/StandardShapes.py +9 -3
  129. nuitka/optimizations/OptimizeBuiltinCalls.py +1 -1
  130. nuitka/optimizations/TraceCollections.py +75 -0
  131. nuitka/pgo/PGO.py +14 -6
  132. nuitka/plugins/PluginBase.py +83 -11
  133. nuitka/plugins/Plugins.py +78 -35
  134. nuitka/plugins/standard/AntiBloatPlugin.py +46 -1
  135. nuitka/plugins/standard/ConsiderPyLintAnnotationsPlugin.py +1 -1
  136. nuitka/plugins/standard/DelvewheelPlugin.py +2 -1
  137. nuitka/plugins/standard/DillPlugin.py +3 -99
  138. nuitka/plugins/standard/DllFilesPlugin.py +45 -0
  139. nuitka/plugins/standard/GiPlugin.py +23 -10
  140. nuitka/plugins/standard/GlfwPlugin.py +1 -0
  141. nuitka/plugins/standard/ImplicitImports.py +267 -15
  142. nuitka/plugins/standard/KivyPlugin.py +1 -0
  143. nuitka/plugins/standard/MatplotlibPlugin.py +43 -25
  144. nuitka/plugins/standard/OptionsNannyPlugin.py +5 -6
  145. nuitka/plugins/standard/PkgResourcesPlugin.py +1 -1
  146. nuitka/plugins/standard/PmwPlugin.py +1 -1
  147. nuitka/plugins/standard/PySidePyQtPlugin.py +37 -20
  148. nuitka/plugins/standard/TkinterPlugin.py +44 -30
  149. nuitka/plugins/standard/TransformersPlugin.py +3 -1
  150. nuitka/plugins/standard/standard.nuitka-package.config.yml +522 -86
  151. nuitka/plugins/standard/stdlib3.nuitka-package.config.yml +8 -1
  152. nuitka/reports/CompilationReportReader.py +53 -0
  153. nuitka/reports/LicenseReport.rst.j2 +4 -4
  154. nuitka/reports/Reports.py +129 -47
  155. nuitka/specs/HardImportSpecs.py +6 -0
  156. nuitka/tools/data_composer/DataComposer.py +29 -17
  157. nuitka/tools/onefile_compressor/OnefileCompressor.py +173 -110
  158. nuitka/tools/podman/__main__.py +17 -2
  159. nuitka/tools/scanning/DisplayPackageDLLs.py +11 -2
  160. nuitka/tools/scanning/DisplayPackageData.py +1 -1
  161. nuitka/tools/specialize/CTypeDescriptions.py +36 -27
  162. nuitka/tools/specialize/SpecializeC.py +1 -1
  163. nuitka/tools/specialize/SpecializePython.py +16 -0
  164. nuitka/tools/testing/Common.py +3 -4
  165. nuitka/tools/testing/OutputComparison.py +23 -0
  166. nuitka/tools/testing/SearchModes.py +2 -2
  167. nuitka/tools/testing/compare_with_cpython/__main__.py +13 -4
  168. nuitka/tools/testing/measure_construct_performance/__main__.py +2 -5
  169. nuitka/tools/watch/__main__.py +194 -56
  170. nuitka/tree/Building.py +8 -2
  171. nuitka/tree/ComplexCallHelperFunctions.py +45 -15
  172. nuitka/tree/ReformulationAssignmentStatements.py +18 -12
  173. nuitka/tree/ReformulationCallExpressions.py +1 -1
  174. nuitka/tree/ReformulationClasses.py +11 -5
  175. nuitka/tree/ReformulationClasses3.py +30 -12
  176. nuitka/tree/ReformulationComparisonExpressions.py +4 -2
  177. nuitka/tree/ReformulationContractionExpressions.py +19 -11
  178. nuitka/tree/ReformulationDictionaryCreation.py +9 -3
  179. nuitka/tree/ReformulationExecStatements.py +6 -6
  180. nuitka/tree/ReformulationForLoopStatements.py +5 -5
  181. nuitka/tree/ReformulationFunctionStatements.py +6 -2
  182. nuitka/tree/ReformulationImportStatements.py +7 -2
  183. nuitka/tree/ReformulationLambdaExpressions.py +1 -1
  184. nuitka/tree/ReformulationMatchStatements.py +3 -1
  185. nuitka/tree/ReformulationNamespacePackages.py +7 -3
  186. nuitka/tree/ReformulationPrintStatements.py +1 -1
  187. nuitka/tree/ReformulationSequenceCreation.py +18 -6
  188. nuitka/tree/ReformulationWithStatements.py +8 -8
  189. nuitka/tree/ReformulationYieldExpressions.py +2 -2
  190. nuitka/tree/SourceHandling.py +27 -5
  191. nuitka/tree/VariableClosure.py +11 -1
  192. nuitka/utils/AppDirs.py +2 -2
  193. nuitka/utils/CStrings.py +39 -3
  194. nuitka/utils/CommandLineOptions.py +42 -1
  195. nuitka/utils/Distributions.py +305 -38
  196. nuitka/utils/Download.py +27 -8
  197. nuitka/utils/FileOperations.py +103 -20
  198. nuitka/utils/Hashing.py +2 -3
  199. nuitka/utils/Importing.py +60 -3
  200. nuitka/utils/InstalledPythons.py +31 -36
  201. nuitka/utils/Jinja2.py +11 -5
  202. nuitka/utils/ModuleNames.py +11 -3
  203. nuitka/utils/ReExecute.py +7 -0
  204. nuitka/utils/SharedLibraries.py +38 -14
  205. nuitka/utils/SlotMetaClasses.py +55 -0
  206. nuitka/utils/Utils.py +10 -0
  207. nuitka/utils/Yaml.py +9 -1
  208. nuitka/build/inline_copy/tqdm/tqdm/_tqdm_gui.py +0 -9
  209. nuitka/build/inline_copy/tqdm/tqdm/gui.py +0 -191
  210. {Nuitka_winsvc-1.8.6.data → Nuitka_winsvc-1.9.3.data}/scripts/nuitka-run.bat +0 -0
  211. {Nuitka_winsvc-1.8.6.data → Nuitka_winsvc-1.9.3.data}/scripts/nuitka.bat +0 -0
  212. {Nuitka_winsvc-1.8.6.dist-info → Nuitka_winsvc-1.9.3.dist-info}/LICENSE.txt +0 -0
  213. {Nuitka_winsvc-1.8.6.dist-info → Nuitka_winsvc-1.9.3.dist-info}/entry_points.txt +0 -0
  214. {Nuitka_winsvc-1.8.6.dist-info → Nuitka_winsvc-1.9.3.dist-info}/top_level.txt +0 -0
@@ -111,6 +111,13 @@
111
111
  change_function:
112
112
  '_main': "'(lambda: None)'"
113
113
 
114
+ - module-name: 'enum'
115
+ anti-bloat:
116
+ - replacements_plain:
117
+ 'def __call__(cls, value,': 'def __call__(cls, value=None,'
118
+ 'return cls.__new__(cls, value)': 'return cls.__new__(cls, value if value is not None or cls.__module__ != "PySide6.QtCore" else 0)'
119
+ when: 'plugin("pyside6")'
120
+
114
121
  - module-name: 'formatter'
115
122
  anti-bloat:
116
123
  - description: 'remove module ability to run as a binary'
@@ -327,7 +334,7 @@
327
334
  raise\n\
328
335
  sys.exit("Nuitka: Need to use '--enable-plugin=tk-inter' option during compilation for tk-inter to work!")
329
336
  """, " ")
330
- when: 'not deployment'
337
+ when: 'not deployment and not plugin("tk-inter")'
331
338
  options:
332
339
  checks:
333
340
  - console: 'recommend'
@@ -0,0 +1,53 @@
1
+ # Copyright 2023, Kay Hayen, mailto:kay.hayen@gmail.com
2
+ #
3
+ # Part of "Nuitka", an optimizing Python compiler that is compatible and
4
+ # integrates with CPython, but also works on its own.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ """ This is for use in testing, but also for user tools too."""
19
+
20
+
21
+ from nuitka.containers.OrderedDicts import OrderedDict
22
+ from nuitka.TreeXML import fromFile
23
+ from nuitka.utils.ModuleNames import ModuleName
24
+
25
+
26
+ def parseCompilationReport(filename):
27
+ return fromFile(filename)
28
+
29
+
30
+ def extractModulesUsedByModule(compilation_report, module_name):
31
+ # Note: Avoiding usage of "xpath", to lower requirements to not need lxml.
32
+ for module_node in compilation_report.findall("module"):
33
+ if module_node.attrib["name"] != module_name:
34
+ continue
35
+
36
+ result = OrderedDict()
37
+
38
+ for module_usage_node in module_node.find("module_usages").findall(
39
+ "module_usage"
40
+ ):
41
+ entry = OrderedDict(module_usage_node.attrib)
42
+
43
+ used_module_name = ModuleName(entry["name"])
44
+ del entry["name"]
45
+ entry["line"] = int(entry["line"])
46
+ entry["excluded"] = bool(entry["finding"] == "excluded")
47
+
48
+ result[used_module_name] = entry
49
+
50
+ return result
51
+
52
+ # Not found, no usages, user needs to handle that.
53
+ return None
@@ -22,13 +22,13 @@ This software was compiled with Nuitka and contains parts of the following softw
22
22
 
23
23
  {% for distribution in all_distributions %}
24
24
 
25
- {{ distribution.metadata["Name"] }}
26
- ===================================
25
+ {{ get_distribution_name(distribution) }}
26
+ =========================================
27
27
 
28
- Version {{ distribution.metadata["Version"] }} of {{ distribution.metadata["Name"] }} was included and is
28
+ Version {{ get_distribution_version(distribution) }} of {{ get_distribution_name(distribution) }} was included and is
29
29
  under license "{{ get_distribution_license(distribution) }}".
30
30
 
31
- {% if distribution_modules[distribution] != [distribution.metadata["Name"]] %}
31
+ {% if distribution_modules[distribution] != [get_distribution_name(distribution)] %}
32
32
  The contained {{"packages are" if len(distribution_modules[distribution]) > 1 else "package is"}} {{" ,".join(quoted(distribution_modules[distribution]))}}.
33
33
  {% endif %}
34
34
 
nuitka/reports/Reports.py CHANGED
@@ -33,6 +33,7 @@ from nuitka.containers.OrderedSets import OrderedSet
33
33
  from nuitka.freezer.IncludedDataFiles import getIncludedDataFiles
34
34
  from nuitka.freezer.IncludedEntryPoints import getStandaloneEntryPoints
35
35
  from nuitka.importing.Importing import getPackageSearchPath
36
+ from nuitka.importing.Recursion import getRecursionDecisions
36
37
  from nuitka.ModuleRegistry import (
37
38
  getDoneModules,
38
39
  getModuleInclusionInfoByName,
@@ -49,7 +50,13 @@ from nuitka.plugins.Plugins import getActivePlugins
49
50
  from nuitka.PythonFlavors import getPythonFlavorName
50
51
  from nuitka.PythonVersions import getSystemPrefixPath, python_version_full_str
51
52
  from nuitka.Tracing import ReportingSystemExit, reports_logger
52
- from nuitka.utils.Distributions import getDistributionsFromModuleName
53
+ from nuitka.utils.Distributions import (
54
+ getDistributionInstallerName,
55
+ getDistributionLicense,
56
+ getDistributionName,
57
+ getDistributionsFromModuleName,
58
+ getDistributionVersion,
59
+ )
53
60
  from nuitka.utils.FileOperations import getReportPath, putTextFileContents
54
61
  from nuitka.utils.Jinja2 import getTemplate
55
62
  from nuitka.utils.MemoryUsage import getMemoryInfos
@@ -88,8 +95,14 @@ def _getReportInputData(aborted):
88
95
  for module in getDoneModules()
89
96
  )
90
97
 
98
+ module_usages = dict(
99
+ (module.getFullName(), tuple(module.getUsedModules()))
100
+ for module in getDoneModules()
101
+ )
102
+
91
103
  module_distributions = {}
92
104
  distribution_modules = {}
105
+
93
106
  for module in getDoneModules():
94
107
  module_distributions[module.getFullName()] = getDistributionsFromModuleName(
95
108
  module.getFullName()
@@ -100,9 +113,19 @@ def _getReportInputData(aborted):
100
113
 
101
114
  distribution_modules[_distribution].add(module.getFullName())
102
115
 
103
- module_usages = dict(
104
- (module.getFullName(), module.getUsedModules()) for module in getDoneModules()
105
- )
116
+ module_distribution_usages = {}
117
+ for module in getDoneModules():
118
+ module_distribution_usages[module.getFullName()] = OrderedSet()
119
+
120
+ for _module_usage in module_usages[module.getFullName()]:
121
+ if _module_usage.module_name not in module_usages:
122
+ continue
123
+
124
+ module_distribution_usages[module.getFullName()].update(
125
+ dist
126
+ for dist in module_distributions[_module_usage.module_name]
127
+ if dist not in module_distributions[module.getFullName()]
128
+ )
106
129
 
107
130
  module_distribution_names = dict(
108
131
  (module.getFullName(), module.getUsedDistributions())
@@ -112,10 +135,45 @@ def _getReportInputData(aborted):
112
135
  all_distributions = tuple(
113
136
  sorted(
114
137
  set(sum(module_distributions.values(), ())),
115
- key=lambda dist: dist.metadata["Name"],
138
+ key=getDistributionName,
116
139
  )
117
140
  )
118
141
 
142
+ module_distribution_installers = dict(
143
+ (
144
+ getDistributionName(dist),
145
+ getDistributionInstallerName(getDistributionName(dist)),
146
+ )
147
+ for dist in all_distributions
148
+ )
149
+
150
+ module_exclusions = dict((module.getFullName(), {}) for module in getDoneModules())
151
+
152
+ # TODO: The module filename, and other things can be None. Once we change to
153
+ # namedtuples, we need to adapt the type check.
154
+ def _replaceNoneWithString(value):
155
+ if type(value) is tuple:
156
+ return tuple(_replaceNoneWithString(element) for element in value)
157
+
158
+ return value if value is not None else ""
159
+
160
+ for (
161
+ _using_module_name,
162
+ _module_filename,
163
+ _module_name,
164
+ _module_kind,
165
+ _extra_recursion,
166
+ ), (_decision, _reason) in sorted(
167
+ getRecursionDecisions().items(), key=_replaceNoneWithString
168
+ ):
169
+ if _decision is not False:
170
+ continue
171
+
172
+ if _using_module_name is None:
173
+ continue
174
+
175
+ module_exclusions[_using_module_name][_module_name] = _reason
176
+
119
177
  memory_infos = getMemoryInfos()
120
178
 
121
179
  python_exe = sys.executable
@@ -188,6 +246,13 @@ def _addModulesToReport(root, report_input_data, diffable):
188
246
  ),
189
247
  )
190
248
 
249
+ distributions = report_input_data["module_distributions"][module_name]
250
+
251
+ if distributions:
252
+ module_xml_node.attrib["distribution"] = ",".join(
253
+ getDistributionName(dist) for dist in distributions
254
+ )
255
+
191
256
  for plugin_name, influence, detail in report_input_data[
192
257
  "module_plugin_influences"
193
258
  ][module_name]:
@@ -219,19 +284,19 @@ def _addModulesToReport(root, report_input_data, diffable):
219
284
 
220
285
  module_xml_node.append(timing_xml_node)
221
286
 
222
- distributions = report_input_data["module_distributions"][module_name]
287
+ distributions = report_input_data["module_distribution_usages"][module_name]
223
288
 
224
289
  if distributions:
225
290
  distributions_xml_node = TreeXML.appendTreeElement(
226
291
  module_xml_node,
227
- "distributions",
292
+ "distribution-usages",
228
293
  )
229
294
 
230
295
  for distribution in distributions:
231
296
  TreeXML.appendTreeElement(
232
297
  distributions_xml_node,
233
- "distribution-used",
234
- name=distribution.metadata["Name"],
298
+ "distribution-usage",
299
+ name=getDistributionName(distribution),
235
300
  )
236
301
 
237
302
  module_distribution_names = report_input_data["module_distribution_names"][
@@ -247,7 +312,7 @@ def _addModulesToReport(root, report_input_data, diffable):
247
312
  for distribution_name, found in module_distribution_names.items():
248
313
  TreeXML.appendTreeElement(
249
314
  module_distribution_names_xml_node,
250
- "distribution",
315
+ "distribution-lookup",
251
316
  name=distribution_name,
252
317
  found="yes" if found else "no",
253
318
  )
@@ -258,7 +323,7 @@ def _addModulesToReport(root, report_input_data, diffable):
258
323
  )
259
324
 
260
325
  for used_module in report_input_data["module_usages"][module_name]:
261
- TreeXML.appendTreeElement(
326
+ module_usage_node = TreeXML.appendTreeElement(
262
327
  used_modules_xml_node,
263
328
  "module_usage",
264
329
  name=used_module.module_name.asString(),
@@ -266,6 +331,16 @@ def _addModulesToReport(root, report_input_data, diffable):
266
331
  line=str(used_module.source_ref.getLineNumber()),
267
332
  )
268
333
 
334
+ exclusion_reason = report_input_data["module_exclusions"][module_name].get(
335
+ used_module.module_name
336
+ )
337
+
338
+ # Include reason why a module was excluded unless it is obvious like
339
+ # with built-in modules.
340
+ if exclusion_reason is not None and used_module.module_kind != "built-in":
341
+ module_usage_node.attrib["finding"] = "excluded"
342
+ module_usage_node.attrib["exclusion_reason"] = exclusion_reason
343
+
269
344
 
270
345
  def _addMemoryInfosToReport(performance_xml_node, memory_infos, diffable):
271
346
  for key, value in memory_infos.items():
@@ -460,8 +535,11 @@ def writeCompilationReport(report_filename, report_input_data, diffable):
460
535
  TreeXML.appendTreeElement(
461
536
  distributions_xml_node,
462
537
  "distribution",
463
- name=distribution.metadata["Name"],
464
- version=distribution.metadata["Version"],
538
+ name=getDistributionName(distribution),
539
+ version=getDistributionVersion(distribution),
540
+ installer=report_input_data["module_distribution_installers"][
541
+ getDistributionName(distribution)
542
+ ],
465
543
  )
466
544
 
467
545
  python_xml_node = TreeXML.appendTreeElement(
@@ -474,22 +552,27 @@ def writeCompilationReport(report_filename, report_input_data, diffable):
474
552
  arch_name=report_input_data["arch_name"],
475
553
  )
476
554
 
477
- search_path_xml_node = TreeXML.appendTreeElement(
478
- python_xml_node,
479
- "search_path",
480
- )
555
+ search_path = getPackageSearchPath(None)
481
556
 
482
- for search_path in getPackageSearchPath(None):
483
- TreeXML.appendTreeElement(
484
- search_path_xml_node,
485
- "path",
486
- value=_getCompilationReportPath(search_path),
557
+ if search_path is not None:
558
+ search_path_xml_node = TreeXML.appendTreeElement(
559
+ python_xml_node,
560
+ "search_path",
487
561
  )
488
562
 
563
+ for search_path in getPackageSearchPath(None):
564
+ TreeXML.appendTreeElement(
565
+ search_path_xml_node,
566
+ "path",
567
+ value=_getCompilationReportPath(search_path),
568
+ )
569
+
489
570
  _addUserDataToReport(root=root, user_data=report_input_data["user_data"])
490
571
 
491
572
  try:
492
- putTextFileContents(filename=report_filename, contents=TreeXML.toString(root))
573
+ putTextFileContents(
574
+ filename=report_filename, contents=TreeXML.toString(root), encoding="utf8"
575
+ )
493
576
  except OSError as e:
494
577
  reports_logger.warning(
495
578
  "Compilation report write to file '%s' failed due to: %s."
@@ -514,25 +597,6 @@ def writeCompilationReportFromTemplate(
514
597
  extensions=("jinja2.ext.do",),
515
598
  )
516
599
 
517
- def get_distribution_license(distribution):
518
- license_name = distribution.metadata["License"]
519
-
520
- if not license_name or license_name == "UNKNOWN":
521
- for classifier in (
522
- value
523
- for (key, value) in distribution.metadata.items()
524
- if "Classifier" in key
525
- ):
526
- parts = [part.strip() for part in classifier.split("::")]
527
- if not parts:
528
- continue
529
-
530
- if parts[0] == "License":
531
- license_name = parts[-1]
532
- break
533
-
534
- return license_name
535
-
536
600
  def quoted(value):
537
601
  if isinstance(value, str):
538
602
  return "'%s'" % value
@@ -541,7 +605,11 @@ def writeCompilationReportFromTemplate(
541
605
 
542
606
  report_text = template.render(
543
607
  # Get the license text.
544
- get_distribution_license=get_distribution_license,
608
+ get_distribution_license=getDistributionLicense,
609
+ # get the distribution_name
610
+ get_distribution_name=getDistributionName,
611
+ # get the distribution version
612
+ get_distribution_version=getDistributionVersion,
545
613
  # Quote a list of strings.
546
614
  quoted=quoted,
547
615
  # For checking length of lists.
@@ -563,15 +631,20 @@ def writeCompilationReportFromTemplate(
563
631
 
564
632
 
565
633
  _crash_report_filename = "nuitka-crash-report.xml"
634
+ _crash_report_bug_message = True
566
635
 
567
636
 
568
637
  def _informAboutCrashReport():
569
638
  if _crash_report_filename is not None:
639
+ message = (
640
+ "Compilation crash report written to file '%s'." % _crash_report_filename
641
+ )
642
+
643
+ if _crash_report_bug_message:
644
+ message += " Please include it in your bug report."
645
+
570
646
  reports_logger.info(
571
- """\
572
- Compilation crash report written to file '%s'. Please include it in \
573
- your bug report."""
574
- % _crash_report_filename,
647
+ message,
575
648
  style="red",
576
649
  )
577
650
 
@@ -588,6 +661,15 @@ def writeCompilationReports(aborted):
588
661
  ):
589
662
  report_filename = _crash_report_filename
590
663
 
664
+ # Inform user about bug reporting of a bug only, if this is not some sort
665
+ # of reporting exit, these do not constitute definitive bugs of Nuitka but
666
+ # are often usage errors only.
667
+
668
+ # Using global here, as this is really a singleton
669
+ # pylint: disable=global-statement
670
+ global _crash_report_bug_message
671
+ _crash_report_bug_message = sys.exc_info()[0] is not ReportingSystemExit
672
+
591
673
  atexit.register(_informAboutCrashReport)
592
674
 
593
675
  if report_filename or template_specs:
@@ -174,3 +174,9 @@ ctypes_cdll_before_38_spec = BuiltinParameterSpec(
174
174
  ),
175
175
  default_count=4,
176
176
  )
177
+
178
+ builtins_open_since_3_spec = BuiltinParameterSpec(
179
+ "builtins.open",
180
+ ("file", "mode", "buffering", "encoding", "errors", "newline", "closefd", "opener"),
181
+ default_count=7,
182
+ )
@@ -46,6 +46,24 @@ from nuitka.Tracing import data_composer_logger
46
46
  from nuitka.utils.FileOperations import getFileSize, listDir, syncFileOutput
47
47
  from nuitka.utils.Json import writeJsonToFilename
48
48
 
49
+ _max_uint64_t_value = 2**64 - 1
50
+
51
+
52
+ def _encodeVariableLength(value):
53
+ """Get the variable length size encoding of a uint64_t value."""
54
+
55
+ assert 0 <= value <= _max_uint64_t_value
56
+
57
+ result = b""
58
+
59
+ while value >= 128:
60
+ # Need to take the last seven bits as a byte value
61
+ result += to_byte((value & 255) | 128)
62
+ value >>= 7
63
+
64
+ # Last byte or whole value small enough.
65
+ return result + to_byte(value)
66
+
49
67
 
50
68
  def scanConstFiles(build_dir):
51
69
  result = []
@@ -90,27 +108,24 @@ def _writeConstantValue(output, constant_value):
90
108
  elif constant_value is False:
91
109
  output.write(b"F")
92
110
  elif constant_type is tuple:
93
- # TODO: Optimize for size of tuple to be < 256 with dedicated value
94
- output.write(b"T" + struct.pack("i", len(constant_value)))
111
+ output.write(b"T" + _encodeVariableLength(len(constant_value)))
95
112
 
96
113
  _last_written = None
97
114
 
98
115
  for element in constant_value:
99
116
  _writeConstantValue(output, element)
100
117
  elif constant_type is list:
101
- # TODO: Optimize for size of list to be < 256 with dedicated value
102
- output.write(b"L" + struct.pack("i", len(constant_value)))
118
+ output.write(b"L" + _encodeVariableLength(len(constant_value)))
103
119
 
104
120
  _last_written = None
105
121
 
106
122
  for element in constant_value:
107
123
  _writeConstantValue(output, element)
108
124
  elif constant_type is dict:
109
- # TODO: Optimize for size of dict to be < 256 with dedicated value
110
- output.write(b"D" + struct.pack("i", len(constant_value)))
125
+ output.write(b"D" + _encodeVariableLength(len(constant_value)))
111
126
 
112
127
  # Write keys first, and values second, such that we allow for the
113
- # last_writte to have an impact.
128
+ # last_written to have an impact.
114
129
  items = constant_value.items()
115
130
 
116
131
  _last_written = None
@@ -121,15 +136,13 @@ def _writeConstantValue(output, constant_value):
121
136
  for key, value in items:
122
137
  _writeConstantValue(output, value)
123
138
  elif constant_type is set:
124
- # TODO: Optimize for size of set to be < 256 with dedicated value
125
- output.write(b"S" + struct.pack("i", len(constant_value)))
139
+ output.write(b"S" + _encodeVariableLength(len(constant_value)))
126
140
 
127
141
  _last_written = None
128
142
  for element in constant_value:
129
143
  _writeConstantValue(output, element)
130
144
  elif constant_type is frozenset:
131
- # TODO: Optimize for size of set to be < 256 with dedicated value
132
- output.write(b"P" + struct.pack("i", len(constant_value)))
145
+ output.write(b"P" + _encodeVariableLength(len(constant_value)))
133
146
 
134
147
  _last_written = None
135
148
  for element in constant_value:
@@ -191,7 +204,7 @@ def _writeConstantValue(output, constant_value):
191
204
  output.write(b"w" + encoded)
192
205
  # Zero termination if possible.
193
206
  elif b"\0" in encoded:
194
- output.write(b"v" + struct.pack("i", len(encoded)))
207
+ output.write(b"v" + _encodeVariableLength(len(encoded)))
195
208
  output.write(encoded)
196
209
  else:
197
210
  if str is not bytes and _isAttributeName(constant_value):
@@ -205,7 +218,7 @@ def _writeConstantValue(output, constant_value):
205
218
  output.write(b"d" + constant_value)
206
219
  # Zero termination if possible.
207
220
  elif b"\0" in constant_value:
208
- output.write(b"b" + struct.pack("i", len(constant_value)))
221
+ output.write(b"b" + _encodeVariableLength(len(constant_value)))
209
222
  output.write(constant_value)
210
223
  else:
211
224
  if str is bytes and _isAttributeName(constant_value):
@@ -262,7 +275,7 @@ def _writeConstantValue(output, constant_value):
262
275
  output.write(struct.pack("dd", constant_value.real, constant_value.imag))
263
276
 
264
277
  elif constant_type is bytearray:
265
- output.write(b"B" + struct.pack("i", len(constant_value)))
278
+ output.write(b"B" + _encodeVariableLength(len(constant_value)))
266
279
 
267
280
  if python_version < 0x270:
268
281
  constant_value = constant_value.decode("latin1")
@@ -296,7 +309,7 @@ def _writeConstantValue(output, constant_value):
296
309
  output.write(constant_value.__name__.encode("utf8"))
297
310
  output.write(b"\0")
298
311
  else:
299
- assert False, constant_value
312
+ assert False, (type(constant_value), constant_value)
300
313
 
301
314
  _last_written = constant_value
302
315
 
@@ -422,8 +435,7 @@ def main():
422
435
  )
423
436
 
424
437
  if str is not bytes:
425
- # Encoding needs to match generated source code output.
426
- encoded_name = name.encode("latin1")
438
+ encoded_name = name.encode("utf8")
427
439
  else:
428
440
  encoded_name = name
429
441