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
@@ -17,58 +17,141 @@
17
17
  #
18
18
  """ Tools for accessing distributions and resolving package names for them. """
19
19
 
20
+ import os
21
+
22
+ from nuitka.__past__ import unicode
20
23
  from nuitka.containers.OrderedSets import OrderedSet
24
+ from nuitka.Options import isExperimental
21
25
  from nuitka.PythonFlavors import isAnacondaPython
22
26
  from nuitka.PythonVersions import python_version
23
27
 
28
+ from .FileOperations import searchPrefixPath
29
+ from .Importing import getModuleNameAndKindFromFilenameSuffix
24
30
  from .ModuleNames import ModuleName, checkModuleName
31
+ from .Utils import isLinux
25
32
 
26
33
  _package_to_distribution = None
27
34
 
28
35
 
36
+ def getDistributionFiles(distribution):
37
+ if hasattr(distribution, "files"):
38
+ for filename in distribution.files or ():
39
+ filename = filename.as_posix()
40
+
41
+ yield filename
42
+ else:
43
+ record_data = _getDistributionMetadataFileContents(distribution, "RECORD")
44
+
45
+ if record_data is not None:
46
+ for line in record_data.splitlines():
47
+ filename = line.split(",", 1)[0]
48
+
49
+ yield filename
50
+
51
+
52
+ def _getDistributionMetadataFileContents(distribution, filename):
53
+ try:
54
+ if hasattr(distribution, "read_text"):
55
+ result = distribution.read_text(filename)
56
+ else:
57
+ result = "\n".join(distribution.get_metadata_lines(filename))
58
+
59
+ return result
60
+ except (FileNotFoundError, KeyError):
61
+ return None
62
+
63
+
29
64
  def getDistributionTopLevelPackageNames(distribution):
30
65
  """Returns the top level package names for a distribution."""
31
- top_level_txt = distribution.read_text("top_level.txt")
66
+ top_level_txt = _getDistributionMetadataFileContents(distribution, "top_level.txt")
32
67
 
33
- if top_level_txt:
34
- result = top_level_txt.split()
35
- result = [dirname.replace("/", ".") for dirname in result]
68
+ if top_level_txt is not None:
69
+ result = [dirname.replace("/", ".") for dirname in top_level_txt.splitlines()]
36
70
  else:
71
+ # If the file is not present, fall back to scanning all files in the
72
+ # distribution.
37
73
  result = OrderedSet()
38
74
 
39
- for filename in distribution.files or ():
40
- filename = filename.as_posix()
41
-
42
- if not filename.endswith(".py"):
43
- continue
44
-
75
+ for filename in getDistributionFiles(distribution):
45
76
  if filename.startswith("."):
46
77
  continue
47
78
 
48
- filename = filename[:-3]
79
+ first_path_element, _, remainder = filename.partition("/")
49
80
 
50
- result.add(filename.split("/")[0])
81
+ if first_path_element.endswith("dist-info"):
82
+ continue
83
+ if first_path_element == "__pycache__":
84
+ continue
85
+
86
+ if remainder:
87
+ module_name = ModuleName(first_path_element)
88
+ else:
89
+ module_name, _kind = getModuleNameAndKindFromFilenameSuffix(
90
+ first_path_element
91
+ )
92
+
93
+ # Ignore top level files that are not modules.
94
+ if module_name is None:
95
+ continue
96
+
97
+ result.add(module_name)
98
+
99
+ result = OrderedSet(
100
+ package_name.asString()
101
+ for package_name in result
102
+ if not any(
103
+ package_name.isBelowNamespace(other_package_name)
104
+ for other_package_name in result
105
+ )
106
+ )
51
107
 
52
108
  if not result:
53
- result = (distribution.metadata["Name"],)
109
+ result = (getDistributionName(distribution),)
54
110
 
55
111
  return tuple(result)
56
112
 
57
113
 
114
+ def _get_pkg_resource_distributions():
115
+ """Small replacement of distributions() of importlib.metadata that uses pkg_resources"""
116
+
117
+ # Prepare "site" for the "pip" module to find what it wants.
118
+ import site
119
+
120
+ if _user_site_directory is not None:
121
+ site.USER_SITE = _user_site_directory
122
+
123
+ # pip and vendored pkg_resources are optional of course, but of course very
124
+ # omnipresent generally, so we don't handle failure here.
125
+
126
+ # pylint: disable=I0021,no-name-in-module
127
+ from pip._vendor import pkg_resources
128
+
129
+ return lambda: pkg_resources.working_set
130
+
131
+
58
132
  def _initPackageToDistributionName():
59
133
  try:
134
+ if isExperimental("force-pkg-resources-metadata"):
135
+ raise ImportError
136
+
60
137
  try:
61
138
  from importlib.metadata import distributions
62
139
  except ImportError:
63
140
  from importlib_metadata import distributions
64
- except ImportError:
65
- return {}
66
141
 
67
- # Cyclic dependency
142
+ except (ImportError, SyntaxError):
143
+ try:
144
+ distributions = _get_pkg_resource_distributions()
145
+ except ImportError:
146
+ # No pip installed, not very many distributions in that case.
147
+ distributions = lambda: ()
68
148
 
149
+ # Cyclic dependency
69
150
  result = {}
70
151
 
71
152
  for distribution in distributions():
153
+ distribution_name = getDistributionName(distribution)
154
+
72
155
  for package_name in getDistributionTopLevelPackageNames(distribution):
73
156
  # Protect against buggy packages.
74
157
  if not checkModuleName(package_name):
@@ -79,13 +162,23 @@ def _initPackageToDistributionName():
79
162
  if package_name not in result:
80
163
  result[package_name] = set()
81
164
 
165
+ # Skip duplicates, e.g. user package vs. site package installation.
166
+ if any(
167
+ distribution_name == getDistributionName(dist)
168
+ for dist in result[package_name]
169
+ ):
170
+ continue
171
+
82
172
  result[package_name].add(distribution)
83
173
 
84
174
  return result
85
175
 
86
176
 
87
177
  def getDistributionsFromModuleName(module_name):
88
- """Get the distribution name associated with a module name."""
178
+ """Get the distribution names associated with a module name.
179
+
180
+ This can be more than one in case of namespace modules.
181
+ """
89
182
 
90
183
  # Cached result, pylint: disable=global-statement
91
184
 
@@ -93,54 +186,228 @@ def getDistributionsFromModuleName(module_name):
93
186
  if _package_to_distribution is None:
94
187
  _package_to_distribution = _initPackageToDistributionName()
95
188
 
189
+ # Go upwards until we find something, such that contained module names are
190
+ # usable too.
191
+ while (
192
+ module_name not in _package_to_distribution
193
+ and module_name.getPackageName() is not None
194
+ ):
195
+ module_name = module_name.getPackageName()
196
+
96
197
  return tuple(
97
198
  sorted(
98
199
  _package_to_distribution.get(module_name, ()),
99
- key=lambda dist: dist.metadata["Name"],
200
+ key=getDistributionName,
100
201
  )
101
202
  )
102
203
 
103
204
 
205
+ def getDistributionFromModuleName(module_name):
206
+ """Get the distribution name associated with a module name."""
207
+ distributions = getDistributionsFromModuleName(module_name)
208
+
209
+ if not distributions:
210
+ return None
211
+ elif len(distributions) == 1:
212
+ return distributions[0]
213
+ else:
214
+ return min(distributions, key=lambda dist: len(getDistributionName(dist)))
215
+
216
+
104
217
  def getDistribution(distribution_name):
105
218
  """Get a distribution by name."""
219
+ assert isValidDistributionName(distribution_name), distribution_name
220
+
106
221
  try:
222
+ if isExperimental("force-pkg-resources-metadata"):
223
+ raise ImportError
224
+
107
225
  if python_version >= 0x380:
108
226
  from importlib import metadata
109
227
  else:
110
228
  import importlib_metadata as metadata
111
229
  except ImportError:
112
- return None
113
-
114
- try:
115
- return metadata.distribution(distribution_name)
116
- except metadata.PackageNotFoundError:
117
- # If not found, lets assume package name was given, and resolve to
118
- # the distribution.
119
- dists = getDistributionsFromModuleName(distribution_name)
120
-
121
- if len(dists) == 1:
122
- return dists[0]
230
+ from pip._vendor.pkg_resources import (
231
+ DistributionNotFound,
232
+ get_distribution,
233
+ )
123
234
 
124
- return None
235
+ try:
236
+ return get_distribution(distribution_name)
237
+ except DistributionNotFound:
238
+ return None
239
+ else:
240
+ try:
241
+ return metadata.distribution(distribution_name)
242
+ except metadata.PackageNotFoundError:
243
+ return None
125
244
 
126
245
 
127
- _distribution_to_conda_package = {}
246
+ _distribution_to_installer = {}
128
247
 
129
248
 
130
249
  def isDistributionCondaPackage(distribution_name):
131
250
  if not isAnacondaPython():
132
251
  return False
133
252
 
134
- if distribution_name not in _distribution_to_conda_package:
253
+ return getDistributionInstallerName(distribution_name) == "conda"
254
+
255
+
256
+ def isDistributionPipPackage(distribution_name):
257
+ return getDistributionInstallerName(distribution_name) == "pip"
258
+
259
+
260
+ def isDistributionPoetryPackage(distribution_name):
261
+ return getDistributionInstallerName(distribution_name).startswith("poetry")
262
+
263
+
264
+ def isDistributionSystemPackage(distribution_name):
265
+ result = (
266
+ not isDistributionPipPackage(distribution_name)
267
+ and not isDistributionPoetryPackage(distribution_name)
268
+ and not isDistributionCondaPackage(distribution_name)
269
+ )
270
+
271
+ # This should only ever happen on Linux, lets know when it does happen
272
+ # elsewhere, since that is most probably a bug in our installer detection on
273
+ # non-Linux as well.
274
+ if result:
275
+ assert isLinux(), (
276
+ distribution_name,
277
+ getDistributionInstallerName(distribution_name),
278
+ )
279
+
280
+ return result
281
+
282
+
283
+ _pdm_dir_cache = {}
284
+
285
+
286
+ def isPdmPackageInstallation(distribution):
287
+ distribution_path = getattr(distribution, "_path")
288
+ if distribution_path is None:
289
+ return False
290
+
291
+ site_packages_path = searchPrefixPath(str(distribution_path), "site-packages")
292
+ if site_packages_path is None:
293
+ return False
294
+
295
+ candidate = os.path.join(site_packages_path, "..", "..", "pyvenv.cfg")
296
+
297
+ result = _pdm_dir_cache.get(candidate)
298
+ if result is None:
299
+ _pdm_dir_cache[candidate] = os.path.exists(candidate)
300
+
301
+ return _pdm_dir_cache[candidate]
302
+
303
+
304
+ def getDistributionInstallerName(distribution_name):
305
+ """Get the installer name from a distribution object.
306
+
307
+ We might care of pip, anaconda, Debian, or whatever installed a
308
+ package.
309
+ """
310
+ if distribution_name not in _distribution_to_installer:
135
311
  distribution = getDistribution(distribution_name)
136
312
 
137
313
  if distribution is None:
138
- _distribution_to_conda_package[distribution_name] = False
314
+ if distribution_name == "Pip":
315
+ _distribution_to_installer[distribution_name] = "default"
316
+ else:
317
+ _distribution_to_installer[distribution_name] = "not_found"
139
318
  else:
140
- installer_txt = distribution.read_text("INSTALLER") or ""
141
-
142
- _distribution_to_conda_package[distribution_name] = (
143
- installer_txt.upper() == "CONDA"
319
+ installer_name = _getDistributionMetadataFileContents(
320
+ distribution, "INSTALLER"
144
321
  )
145
322
 
146
- return _distribution_to_conda_package[distribution_name]
323
+ if installer_name:
324
+ _distribution_to_installer[
325
+ distribution_name
326
+ ] = installer_name.strip().lower()
327
+ elif isAnacondaPython():
328
+ _distribution_to_installer[distribution_name] = "conda"
329
+ elif isPdmPackageInstallation(distribution):
330
+ return "pip"
331
+ else:
332
+ if hasattr(distribution, "_path"):
333
+ distribution_path_parts = str(getattr(distribution, "_path")).split(
334
+ "/"
335
+ )
336
+
337
+ if (
338
+ "dist-packages" in distribution_path_parts
339
+ and "local" not in distribution_path_parts
340
+ ):
341
+ _distribution_to_installer[distribution_name] = "Debian"
342
+ else:
343
+ _distribution_to_installer[distribution_name] = "Unknown"
344
+ else:
345
+ _distribution_to_installer[distribution_name] = "Unknown"
346
+
347
+ return _distribution_to_installer[distribution_name]
348
+
349
+
350
+ def isValidDistributionName(distribution_name):
351
+ return type(distribution_name) in (str, unicode)
352
+
353
+
354
+ def getDistributionName(distribution):
355
+ """Get the distribution name from a distribution object.
356
+
357
+ We use importlib.metadata and pkg_resources version tuples interchangeable
358
+ and this is to abstract the difference is how to look up the name from
359
+ one.
360
+ """
361
+
362
+ if hasattr(distribution, "metadata"):
363
+ result = distribution.metadata["Name"]
364
+ else:
365
+ result = distribution.project_name
366
+
367
+ assert isValidDistributionName(result), distribution
368
+ return result
369
+
370
+
371
+ def getDistributionVersion(distribution):
372
+ """Get the distribution version string from a distribution object.
373
+
374
+ We use importlib.metadata and pkg_resources version tuples interchangeable
375
+ and this is to abstract the difference is how to look up the version from
376
+ one.
377
+ """
378
+ # Avoiding use of public interface for pkg_resources, pylint: disable=protected-access
379
+ if hasattr(distribution, "metadata"):
380
+ return distribution.metadata["Version"]
381
+ else:
382
+ return distribution._version
383
+
384
+
385
+ def getDistributionLicense(distribution):
386
+ """Get the distribution license from a distribution object."""
387
+
388
+ license_name = distribution.metadata["License"]
389
+
390
+ if not license_name or license_name == "UNKNOWN":
391
+ for classifier in (
392
+ value
393
+ for (key, value) in distribution.metadata.items()
394
+ if "Classifier" in key
395
+ ):
396
+ parts = [part.strip() for part in classifier.split("::")]
397
+ if not parts:
398
+ continue
399
+
400
+ if parts[0] == "License":
401
+ license_name = parts[-1]
402
+ break
403
+
404
+ return license_name
405
+
406
+
407
+ # User site directory if any
408
+ _user_site_directory = None
409
+
410
+
411
+ def setUserSiteDirectory(user_site_directory):
412
+ global _user_site_directory # singleton, pylint: disable=global-statement
413
+ _user_site_directory = user_site_directory
nuitka/utils/Download.py CHANGED
@@ -24,6 +24,7 @@ import os
24
24
 
25
25
  from nuitka import Tracing
26
26
  from nuitka.__past__ import urlretrieve
27
+ from nuitka.Progress import withNuitkaDownloadProgressBar
27
28
 
28
29
  from .AppDirs import getCacheDir
29
30
  from .FileOperations import (
@@ -34,11 +35,23 @@ from .FileOperations import (
34
35
  )
35
36
 
36
37
 
37
- def getDownload(url, download_path):
38
- try:
39
- urlretrieve(url, download_path)
40
- except Exception: # Any kind of error, pylint: disable=broad-except
41
- urlretrieve(url.replace("https://", "http://"), download_path)
38
+ def getDownload(name, url, download_path):
39
+ # requests api, spell-checker: ignore reporthook
40
+
41
+ with withNuitkaDownloadProgressBar(desc="Download %s" % name) as reporthook:
42
+ try:
43
+ try:
44
+ urlretrieve(url, download_path, reporthook=reporthook)
45
+ except Exception: # Any kind of error, pylint: disable=broad-except
46
+ urlretrieve(
47
+ url.replace("https://", "http://"),
48
+ download_path,
49
+ reporthook=reporthook,
50
+ )
51
+ except KeyboardInterrupt:
52
+ deleteFile(download_path, must_exist=False)
53
+
54
+ raise
42
55
 
43
56
 
44
57
  def getDownloadCacheDir():
@@ -46,6 +59,7 @@ def getDownloadCacheDir():
46
59
 
47
60
 
48
61
  def getCachedDownload(
62
+ name,
49
63
  url,
50
64
  binary,
51
65
  flatten,
@@ -99,7 +113,11 @@ Fully automatic, cached. Proceed and download"""
99
113
  Tracing.general.info("Downloading '%s'." % url)
100
114
 
101
115
  try:
102
- getDownload(url=url, download_path=download_path)
116
+ getDownload(
117
+ name=name,
118
+ url=url,
119
+ download_path=download_path,
120
+ )
103
121
  except Exception as e: # Any kind of error, pylint: disable=broad-except
104
122
  Tracing.general.sysexit(
105
123
  "Failed to download '%s' due to '%s'. Contents should manually be copied to '%s'."
@@ -150,10 +168,10 @@ def getCachedDownloadedMinGW64(target_arch, assume_yes_for_downloads):
150
168
  # Large URLs, pylint: disable=line-too-long
151
169
 
152
170
  if target_arch == "x86_64":
153
- url = "https://github.com/brechtsanders/winlibs_mingw/releases/download/11.3.0-14.0.3-10.0.0-msvcrt-r3/winlibs-x86_64-posix-seh-gcc-11.3.0-llvm-14.0.3-mingw-w64msvcrt-10.0.0-r3.zip"
171
+ url = "https://github.com/brechtsanders/winlibs_mingw/releases/download/13.2.0-16.0.6-11.0.1-msvcrt-r1/winlibs-x86_64-posix-seh-gcc-13.2.0-llvm-16.0.6-mingw-w64msvcrt-11.0.1-r1.zip"
154
172
  binary = r"mingw64\bin\gcc.exe"
155
173
  elif target_arch == "x86":
156
- url = "https://github.com/brechtsanders/winlibs_mingw/releases/download/11.3.0-14.0.3-10.0.0-msvcrt-r3/winlibs-i686-posix-dwarf-gcc-11.3.0-llvm-14.0.3-mingw-w64msvcrt-10.0.0-r3.zip"
174
+ url = "https://github.com/brechtsanders/winlibs_mingw/releases/download/13.2.0-16.0.6-11.0.1-msvcrt-r1/winlibs-i686-posix-dwarf-gcc-13.2.0-llvm-16.0.6-mingw-w64msvcrt-11.0.1-r1.zip"
157
175
  binary = r"mingw32\bin\gcc.exe"
158
176
  elif target_arch == "arm64":
159
177
  url = None
@@ -164,6 +182,7 @@ def getCachedDownloadedMinGW64(target_arch, assume_yes_for_downloads):
164
182
  return None
165
183
 
166
184
  gcc_binary = getCachedDownload(
185
+ name="mingw64",
167
186
  url=url,
168
187
  is_arch_specific=target_arch,
169
188
  specificity=url.rsplit("/", 2)[1],