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
@@ -30,15 +30,16 @@ import glob
30
30
  import os
31
31
  import shutil
32
32
  import stat
33
+ import sys
33
34
  import tempfile
34
35
  import time
35
36
  from contextlib import contextmanager
36
37
 
37
38
  from nuitka.__past__ import ( # pylint: disable=redefined-builtin
38
39
  PermissionError,
39
- WindowsError,
40
40
  basestring,
41
41
  raw_input,
42
+ unicode,
42
43
  )
43
44
  from nuitka.PythonVersions import python_version
44
45
  from nuitka.Tracing import (
@@ -51,7 +52,13 @@ from nuitka.Tracing import (
51
52
 
52
53
  from .Importing import importFromInlineCopy
53
54
  from .ThreadedExecutor import RLock, getThreadIdent
54
- from .Utils import isLinux, isMacOS, isWin32OrPosixWindows, isWin32Windows
55
+ from .Utils import (
56
+ isLinux,
57
+ isMacOS,
58
+ isWin32OrPosixWindows,
59
+ isWin32Windows,
60
+ raiseWindowsError,
61
+ )
55
62
 
56
63
  # Locking seems to be only required for Windows mostly, but we can keep
57
64
  # it for all.
@@ -259,7 +266,9 @@ def getDirectoryRealPath(path):
259
266
  path with symlinks resolved
260
267
 
261
268
  Notes:
262
- Workaround for Windows symlink is applied.
269
+ Workaround for Windows symlink is applied. This function is not recursive
270
+ at all with older Python, i.e. only the last part, the directory itself
271
+ is being resolved there.
263
272
 
264
273
  """
265
274
  path = os.path.realpath(path)
@@ -272,6 +281,45 @@ def getDirectoryRealPath(path):
272
281
  return path
273
282
 
274
283
 
284
+ def getFilenameRealPath(path):
285
+ """Get os.path.realpath with Python2 and Windows symlink workaround applied.
286
+
287
+ Args:
288
+ path: path to get realpath of
289
+
290
+ Returns:
291
+ path with symlinks resolved
292
+
293
+ Notes:
294
+ Workaround for Windows symlinks are applied, this works recursive and
295
+ assumes that the path given itself is a file and not a directory, and
296
+ doesn't handle file symlinks at the end on older Python currently, but
297
+ we shouldn't deal with those.
298
+ """
299
+ path = os.path.realpath(path)
300
+
301
+ # Attempt to resolve Windows symlinks older Python
302
+ if os.name == "nt":
303
+ path = path.strip(os.path.sep)
304
+
305
+ if os.path.sep in path:
306
+ dirname = os.path.dirname(path)
307
+ filename = os.path.basename(path)
308
+
309
+ if dirname:
310
+ dirname = getDirectoryRealPath(dirname)
311
+
312
+ # Drive letters do not get slashes from "os.path.join", so
313
+ # we inject this here and normalize the path afterwards to
314
+ # remove any duplication added.
315
+ if os.path.sep not in dirname:
316
+ dirname = dirname + os.path.sep
317
+
318
+ return os.path.normpath(os.path.join(dirname, filename))
319
+
320
+ return path
321
+
322
+
275
323
  def listDir(path):
276
324
  """Give a sorted listing of a path.
277
325
 
@@ -293,8 +341,28 @@ def listDir(path):
293
341
  """
294
342
  real_path = getDirectoryRealPath(path)
295
343
 
344
+ # The "os.listdir" output needs to be unicode paths, or else it can be unusable
345
+ # for Python2 on Windows at least. We try to go back on the result.
346
+ if str is bytes and type(real_path) is str:
347
+ real_path = unicode(real_path)
348
+
349
+ def _tryDecodeToStr(value):
350
+ if str is bytes:
351
+ if type(value) is unicode:
352
+ # File system paths, that should be usable for names of modules,
353
+ # as Python2 code objects will e.g. hate unicode values.
354
+
355
+ # spell-checker: ignore getfilesystemencoding
356
+ try:
357
+ return value.decode(sys.getfilesystemencoding())
358
+ except UnicodeDecodeError:
359
+ return value
360
+ else:
361
+ return value
362
+
296
363
  return sorted(
297
- [(os.path.join(path, filename), filename) for filename in os.listdir(real_path)]
364
+ (_tryDecodeToStr(os.path.join(path, filename)), _tryDecodeToStr(filename))
365
+ for filename in os.listdir(real_path)
298
366
  )
299
367
 
300
368
 
@@ -577,11 +645,19 @@ def deleteFile(path, must_exist):
577
645
  raise OSError("Does not exist", path)
578
646
 
579
647
 
580
- def splitPath(path):
581
- """Split path, skipping empty elements."""
582
- return tuple(
583
- element for element in os.path.split(path.rstrip(os.path.sep)) if element
584
- )
648
+ def searchPrefixPath(path, element):
649
+ """Search element and return prefix in path, if any."""
650
+
651
+ while path:
652
+ if os.path.normcase(os.path.basename(path)) == os.path.normcase(element):
653
+ return path
654
+
655
+ new_path = os.path.dirname(path)
656
+ if new_path == path:
657
+ break
658
+ path = new_path
659
+
660
+ return None
585
661
 
586
662
 
587
663
  def getFilenameExtension(path):
@@ -977,6 +1053,10 @@ def isFilenameBelowPath(path, filename, consider_short=True):
977
1053
  filename = getExternalUsePath(filename)
978
1054
  path = getExternalUsePath(path)
979
1055
 
1056
+ if isWin32Windows():
1057
+ if getWindowsDrive(path) != getWindowsDrive(filename):
1058
+ return False
1059
+
980
1060
  result = os.path.relpath(filename, path).split(os.path.sep)[0] != ".."
981
1061
 
982
1062
  return result
@@ -1021,10 +1101,7 @@ def getWindowsShortPathName(filename):
1021
1101
  if ctypes.GetLastError() == 5:
1022
1102
  return filename
1023
1103
 
1024
- raise WindowsError(
1025
- ctypes.GetLastError(), ctypes.FormatError(ctypes.GetLastError())
1026
- )
1027
-
1104
+ raiseWindowsError("getWindowsShortPathName for %s" % filename)
1028
1105
  if output_buf_size >= needed:
1029
1106
  # Short paths should be ASCII. Don't return unicode without a need,
1030
1107
  # as e.g. Scons hates that in environment variables.
@@ -1068,10 +1145,7 @@ def getWindowsLongPathName(filename):
1068
1145
  if ctypes.GetLastError() == 5:
1069
1146
  return filename
1070
1147
 
1071
- raise WindowsError(
1072
- ctypes.GetLastError(), ctypes.FormatError(ctypes.GetLastError())
1073
- )
1074
-
1148
+ raiseWindowsError("getWindowsLongPathName for %s" % filename)
1075
1149
  if output_buf_size >= needed:
1076
1150
  return output_buf.value
1077
1151
  else:
@@ -1097,6 +1171,8 @@ def getExternalUsePath(filename, only_dirname=False):
1097
1171
 
1098
1172
  if os.name == "nt":
1099
1173
  if filename not in _external_use_path_cache:
1174
+ filename = getFilenameRealPath(filename)
1175
+
1100
1176
  asked_filename = filename
1101
1177
 
1102
1178
  if only_dirname:
@@ -1202,6 +1278,10 @@ def getLinkTarget(filename):
1202
1278
  return is_link, filename
1203
1279
 
1204
1280
 
1281
+ # Late import and optional to be there.
1282
+ atomicwrites = None
1283
+
1284
+
1205
1285
  def replaceFileAtomic(source_path, dest_path):
1206
1286
  """
1207
1287
  Move ``src`` to ``dst``. If ``dst`` exists, it will be silently
@@ -1216,9 +1296,12 @@ def replaceFileAtomic(source_path, dest_path):
1216
1296
  if python_version >= 0x300:
1217
1297
  os.replace(source_path, dest_path)
1218
1298
  else:
1219
- importFromInlineCopy("atomicwrites", must_exist=True).replace_atomic(
1220
- source_path, dest_path
1221
- )
1299
+ global atomicwrites # singleton, pylint: disable=global-statement
1300
+
1301
+ if atomicwrites is None:
1302
+ atomicwrites = importFromInlineCopy("atomicwrites", must_exist=True)
1303
+
1304
+ atomicwrites.replace_atomic(source_path, dest_path)
1222
1305
 
1223
1306
 
1224
1307
  def resolveShellPatternToFilenames(pattern):
nuitka/utils/Hashing.py CHANGED
@@ -21,10 +21,9 @@ Offers support for hashing incrementally and files esp. without having
21
21
  to read their contents.
22
22
  """
23
23
 
24
- import hashlib
25
24
  from binascii import crc32
26
25
 
27
- from nuitka.__past__ import unicode
26
+ from nuitka.__past__ import md5, unicode
28
27
 
29
28
  from .FileOperations import openTextFile
30
29
 
@@ -64,7 +63,7 @@ class HashBase(object):
64
63
 
65
64
  class Hash(HashBase):
66
65
  def __init__(self):
67
- self.hash = hashlib.md5()
66
+ self.hash = md5()
68
67
 
69
68
  def updateFromBytes(self, value):
70
69
  self.hash.update(value)
nuitka/utils/Importing.py CHANGED
@@ -26,6 +26,7 @@ import sys
26
26
  from nuitka.PythonVersions import python_version
27
27
  from nuitka.Tracing import general
28
28
 
29
+ from .ModuleNames import ModuleName
29
30
  from .Utils import withNoDeprecationWarning
30
31
 
31
32
 
@@ -163,7 +164,7 @@ def _importFromFolder(logger, module_name, path, must_exist, message):
163
164
  del sys.path[0]
164
165
 
165
166
 
166
- def importFromInlineCopy(module_name, must_exist):
167
+ def importFromInlineCopy(module_name, must_exist, delete_module=False):
167
168
  """Import a module from the inline copy stage."""
168
169
 
169
170
  folder_name = os.path.normpath(
@@ -181,7 +182,7 @@ def importFromInlineCopy(module_name, must_exist):
181
182
  elif python_version < 0x360 and os.path.exists(candidate_35):
182
183
  folder_name = candidate_35
183
184
 
184
- return _importFromFolder(
185
+ module = _importFromFolder(
185
186
  module_name=module_name,
186
187
  path=folder_name,
187
188
  must_exist=must_exist,
@@ -189,6 +190,11 @@ def importFromInlineCopy(module_name, must_exist):
189
190
  logger=general,
190
191
  )
191
192
 
193
+ if delete_module and module_name in sys.modules:
194
+ del sys.modules[module_name]
195
+
196
+ return module
197
+
192
198
 
193
199
  _compile_time_modules = {}
194
200
 
@@ -224,7 +230,30 @@ def isBuiltinModuleName(module_name):
224
230
  else:
225
231
  import _imp
226
232
 
227
- return _imp.is_builtin(module_name)
233
+ result = _imp.is_builtin(module_name) or _imp.is_frozen(module_name)
234
+
235
+ # Some frozen modules are not actually in that list, e.g.
236
+ # "importlib._bootstrap_external" on Python3.10 doesn't report to
237
+ # "_imp.is_frozen()" above, so we check if it's already loaded and from the
238
+ # "FrozenImporter" by name.
239
+ if result is False and module_name in sys.modules:
240
+ module = sys.modules[module_name]
241
+
242
+ if hasattr(module, "__loader__"):
243
+ loader = module.__loader__
244
+
245
+ try:
246
+ result = loader.__name__ == "FrozenImporter"
247
+ except AttributeError:
248
+ pass
249
+
250
+ return result
251
+
252
+
253
+ # Have a set for quicker lookups, and we cannot have "__main__" in there.
254
+ builtin_module_names = set(
255
+ module_name for module_name in sys.builtin_module_names if module_name != "__main__"
256
+ )
228
257
 
229
258
 
230
259
  def getModuleFilenameSuffixes():
@@ -251,3 +280,31 @@ def getModuleFilenameSuffixes():
251
280
  yield suffix, "PY_SOURCE"
252
281
  for suffix in importlib.machinery.BYTECODE_SUFFIXES:
253
282
  yield suffix, "PY_COMPILED"
283
+
284
+
285
+ def getModuleNameAndKindFromFilenameSuffix(module_filename):
286
+ """Given a filename, decide the module name and kind.
287
+
288
+ Args:
289
+ module_name - file path of the module
290
+ Returns:
291
+ Tuple with the name of the module basename, and the kind of the
292
+ module derived from the file suffix. Can be None, None if is is not a
293
+ known file suffix.
294
+ Notes:
295
+ This doesn't handle packages at all.
296
+ """
297
+ if module_filename.endswith(".py"):
298
+ return ModuleName(os.path.basename(module_filename)[:-3]), "py"
299
+
300
+ if module_filename.endswith(".pyc"):
301
+ return ModuleName(os.path.basename(module_filename)[:-4]), "pyc"
302
+
303
+ for suffix in getSharedLibrarySuffixes():
304
+ if module_filename.endswith(suffix):
305
+ return (
306
+ ModuleName(os.path.basename(module_filename)[: -len(suffix)]),
307
+ "extension",
308
+ )
309
+
310
+ return None, None
@@ -20,9 +20,12 @@
20
20
  import os
21
21
  import sys
22
22
 
23
- from nuitka.__past__ import WindowsError # pylint: disable=I0021,redefined-builtin
24
23
  from nuitka.containers.OrderedSets import OrderedSet
25
- from nuitka.PythonVersions import python_version_str
24
+ from nuitka.PythonFlavors import isAnacondaPython, isMSYS2MingwPython
25
+ from nuitka.PythonVersions import (
26
+ getInstalledPythonRegistryPaths,
27
+ python_version_str,
28
+ )
26
29
 
27
30
  from .Execution import (
28
31
  NuitkaCalledProcessError,
@@ -55,11 +58,34 @@ class InstalledPython(object):
55
58
  return int(major) * 256 + int(minor) * 16
56
59
 
57
60
  def isAnacondaPython(self):
58
- # TODO: This may not yet going to work really
61
+ if self.python_exe == sys.executable:
62
+ return isAnacondaPython()
63
+
64
+ # TODO: May not yet work really.
59
65
  return os.path.exists(
60
66
  os.path.join(os.path.dirname(self.python_exe), "..", "conda-meta")
61
67
  )
62
68
 
69
+ def isMSYS2MingwPython(self):
70
+ if self.python_exe == sys.executable:
71
+ return isMSYS2MingwPython()
72
+
73
+ # TODO: May not yet work really.
74
+ return (
75
+ os.path.exists(
76
+ os.path.join(os.path.dirname(self.python_exe), "..", "..", "msys2.ini")
77
+ )
78
+ and os.path.basename(os.path.dirname(self.python_exe)) == "mingw64"
79
+ )
80
+
81
+ def getPreferredPackageType(self):
82
+ if self.isAnacondaPython():
83
+ return "conda"
84
+ elif self.isMSYS2MingwPython():
85
+ return "pacman"
86
+ else:
87
+ return "pip"
88
+
63
89
  # Necessary for Python 2.7, otherwise SyntaxError is given on exec.
64
90
  @staticmethod
65
91
  def _exec(code, context):
@@ -124,38 +150,6 @@ class InstalledPython(object):
124
150
  _installed_pythons = {}
125
151
 
126
152
 
127
- def getInstalledPythonRegistryPaths(python_version):
128
- """Yield all Pythons as found in the Windows registry."""
129
- # Windows only code, pylint: disable=I0021,import-error,undefined-variable
130
- if str is bytes:
131
- import _winreg as winreg # pylint: disable=I0021,import-error,no-name-in-module
132
- else:
133
- import winreg # pylint: disable=I0021,import-error,no-name-in-module
134
-
135
- for hkey_branch in (winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CURRENT_USER):
136
- for arch_key in (0, winreg.KEY_WOW64_32KEY, winreg.KEY_WOW64_64KEY):
137
- for suffix in "", "-32", "-arm64":
138
- try:
139
- key = winreg.OpenKey(
140
- hkey_branch,
141
- r"SOFTWARE\Python\PythonCore\%s%s\InstallPath"
142
- % (python_version, suffix),
143
- 0,
144
- winreg.KEY_READ | arch_key,
145
- )
146
-
147
- install_dir = os.path.normpath(winreg.QueryValue(key, ""))
148
- except WindowsError:
149
- pass
150
- else:
151
- candidate = os.path.normpath(
152
- os.path.join(install_dir, "python.exe")
153
- )
154
-
155
- if os.path.exists(candidate):
156
- yield candidate
157
-
158
-
159
153
  def _getPythonInstallPathsWindows(python_version):
160
154
  """Find Python installation on Windows.
161
155
 
@@ -181,7 +175,7 @@ def _getPythonInstallPathsWindows(python_version):
181
175
 
182
176
  seen.add(candidate)
183
177
 
184
- for candidate in getInstalledPythonRegistryPaths(python_version=python_version):
178
+ for candidate in getInstalledPythonRegistryPaths(python_version):
185
179
  if candidate not in seen:
186
180
  seen.add(candidate)
187
181
  yield candidate
@@ -211,6 +205,7 @@ def findPythons(python_version):
211
205
  result.add(InstalledPython(python_exe=candidate, python_version=python_version))
212
206
 
213
207
  _installed_pythons[python_version] = result
208
+
214
209
  return result
215
210
 
216
211
 
nuitka/utils/Jinja2.py CHANGED
@@ -43,6 +43,7 @@ def unlikely_or_likely_from(value):
43
43
 
44
44
 
45
45
  _jinja2 = None
46
+ _markupsafe = None
46
47
 
47
48
  # For pkg resources, we need to keep a reference, after we delete it from
48
49
  # "sys.modules" again.
@@ -51,20 +52,25 @@ _loaded_pkg_resources = None
51
52
 
52
53
 
53
54
  def getJinja2Package():
54
- global _jinja2, _loaded_pkg_resources # singleton package using a cache, pylint: disable=global-statement
55
+ global _jinja2, _markupsafe, _loaded_pkg_resources # singleton package using a cache, pylint: disable=global-statement
55
56
 
56
57
  # Import dependencies, sadly we get to manage this ourselves.
57
- importFromInlineCopy("markupsafe", must_exist=True)
58
+ if _markupsafe is None:
59
+ _markupsafe = importFromInlineCopy("markupsafe", must_exist=True)
58
60
 
59
61
  # Newer Jinja2 may not use it, but we load it and remove it, so it
60
62
  # does not interfere with anything else.
61
63
  if "pkg_resources" not in sys.modules:
62
- _loaded_pkg_resources = importFromInlineCopy("pkg_resources", must_exist=False)
64
+ if _loaded_pkg_resources is None:
65
+ _loaded_pkg_resources = importFromInlineCopy(
66
+ "pkg_resources", must_exist=False
67
+ )
63
68
 
64
- _jinja2 = importFromInlineCopy("jinja2", must_exist=True)
69
+ if _jinja2 is None:
70
+ _jinja2 = importFromInlineCopy("jinja2", must_exist=True)
65
71
 
66
72
  # Unload if it was us loading it, as the inline copy is incomplete.
67
- if _loaded_pkg_resources is not None:
73
+ if _loaded_pkg_resources is not None and "pkg_resources" in sys.modules:
68
74
  del sys.modules["pkg_resources"]
69
75
 
70
76
  return _jinja2
@@ -86,7 +86,7 @@ class ModuleName(str):
86
86
  return ModuleName(module_name)
87
87
 
88
88
  def __repr__(self):
89
- return "<ModuleName %s>" % str(self)
89
+ return "<ModuleName '%s'>" % str(self)
90
90
 
91
91
  def asString(self):
92
92
  """Get a simply str value.
@@ -225,6 +225,13 @@ class ModuleName(str):
225
225
  else:
226
226
  return ModuleName(parent_new)
227
227
 
228
+ def getChildNameFromPackage(self, package_name):
229
+ """Get child a module name part for a name in the package."""
230
+ assert self.hasNamespace(package_name)
231
+
232
+ submodule_name_str = str(self)[len(str(package_name)) + 1 :]
233
+ return ModuleName(submodule_name_str)
234
+
228
235
  def matchesToShellPattern(self, pattern):
229
236
  """Match a module name to a list of patterns
230
237
 
@@ -290,9 +297,10 @@ Do not use %(func_name)s on ModuleName objects, use e.g.
290
297
  .hasNamespace(),
291
298
  .getBasename(),
292
299
  .getTopLevelPackageName()
293
- .hasOneOfNamespaces
300
+ .hasOneOfNamespaces()
294
301
 
295
- Check API documentation of nuitka.utils.ModuleNames.ModuleName
302
+ Check API documentation of nuitka.utils.ModuleNames.ModuleName for more
303
+ variations.
296
304
  ''')
297
305
  """ % {
298
306
  "func_name": _func_name
nuitka/utils/ReExecute.py CHANGED
@@ -73,6 +73,9 @@ def reExecuteNuitka(pgo_filename):
73
73
  if sys.version_info >= (3, 7) and sys.flags.utf8_mode:
74
74
  args += ["-X", "utf8"]
75
75
 
76
+ if sys.version_info >= (3, 11):
77
+ args += ["-X", "frozen_modules=off"]
78
+
76
79
  if "nuitka.__main__" in sys.modules:
77
80
  our_filename = sys.modules["nuitka.__main__"].__file__
78
81
  else:
@@ -110,6 +113,10 @@ def reExecuteNuitka(pgo_filename):
110
113
  # Note: As side effect, this might modify the "sys.path" too.
111
114
  os.environ["NUITKA_PTH_IMPORTED"] = repr(detectPthImportedPackages())
112
115
 
116
+ user_site = getattr(sys.modules["site"], "USER_SITE")
117
+ if user_site is not None:
118
+ os.environ["NUITKA_USER_SITE"] = repr(user_site)
119
+
113
120
  os.environ["NUITKA_PYTHONPATH"] = repr(sys.path)
114
121
 
115
122
  # In some environments, initial "sys.path" does not contain enough to load
@@ -44,7 +44,13 @@ from .FileOperations import (
44
44
  makeContainingPath,
45
45
  withMadeWritableFileMode,
46
46
  )
47
- from .Utils import isAlpineLinux, isLinux, isMacOS, isWin32Windows
47
+ from .Utils import (
48
+ isAlpineLinux,
49
+ isLinux,
50
+ isMacOS,
51
+ isWin32Windows,
52
+ raiseWindowsError,
53
+ )
48
54
  from .WindowsResources import (
49
55
  RT_MANIFEST,
50
56
  VsFixedFileInfoStructure,
@@ -115,6 +121,8 @@ def locateDLL(dll_name):
115
121
  left = left[: left.rfind(b" (")]
116
122
 
117
123
  if python_version >= 0x300:
124
+ # spell-checker: ignore getfilesystemencoding
125
+
118
126
  left = left.decode(sys.getfilesystemencoding())
119
127
  right = right.decode(sys.getfilesystemencoding())
120
128
 
@@ -147,7 +155,7 @@ def _removeSxsFromDLL(filename):
147
155
  filename: Filename to remove SxS manifests from
148
156
  """
149
157
  # There may be more files that need this treatment, these are from scans
150
- # with the "find_sxs_modules" tool.
158
+ # with the "find_sxs_modules" tool. spell-checker: ignore winxpgui
151
159
  if os.path.normcase(os.path.basename(filename)) not in (
152
160
  "sip.pyd",
153
161
  "win32ui.pyd",
@@ -207,7 +215,7 @@ def _getDLLVersionWindows(filename):
207
215
  # This cannot really fail anymore.
208
216
  assert success
209
217
 
210
- # Look for codepages
218
+ # Look for code pages
211
219
  VerQueryValueA = ctypes.windll.version.VerQueryValueA
212
220
  VerQueryValueA.argtypes = (
213
221
  ctypes.wintypes.LPCVOID,
@@ -233,6 +241,7 @@ def _getDLLVersionWindows(filename):
233
241
  return (ms >> 16) & 0xFFFF, ms & 0xFFFF, (ls >> 16) & 0xFFFF, ls & 0xFFFF
234
242
 
235
243
 
244
+ # spell-checker: ignore readelf
236
245
  _readelf_usage = "The 'readelf' is used to analyse dependencies on ELF using systems and required to be found."
237
246
 
238
247
 
@@ -244,6 +253,7 @@ def _getSharedLibraryRPATHElf(filename):
244
253
  )
245
254
 
246
255
  for line in output.split(b"\n"):
256
+ # spell-checker: ignore RUNPATH
247
257
  if b"RPATH" in line or b"RUNPATH" in line:
248
258
  result = line[line.find(b"[") + 1 : line.rfind(b"]")]
249
259
 
@@ -258,10 +268,19 @@ def _getSharedLibraryRPATHElf(filename):
258
268
  _otool_output_cache = {}
259
269
 
260
270
 
271
+ def _getMacOSArchOption():
272
+ macos_target_arch = getMacOSTargetArch()
273
+
274
+ if macos_target_arch != "universal":
275
+ return ("-arch", macos_target_arch)
276
+ else:
277
+ return ()
278
+
279
+
261
280
  def _getOToolCommandOutput(otool_option, filename):
262
281
  filename = os.path.abspath(filename)
263
282
 
264
- command = ("otool", otool_option, filename)
283
+ command = ("otool",) + _getMacOSArchOption() + (otool_option, filename)
265
284
 
266
285
  if otool_option == "-L":
267
286
  cache_key = command, os.environ.get("DYLD_LIBRARY_PATH")
@@ -474,6 +493,7 @@ def getPyWin32Dir():
474
493
  Notes:
475
494
  This is needed for standalone mode only.
476
495
  """
496
+ # spell-checker: ignore pywin32
477
497
 
478
498
  for path_element in sys.path:
479
499
  if not path_element:
@@ -653,6 +673,8 @@ def copyDllFile(source_path, dist_dir, dest_path, executable):
653
673
  )
654
674
 
655
675
  if isMacOS():
676
+ # spell-checker: ignore xattr
677
+
656
678
  executeToolChecked(
657
679
  logger=postprocessing_logger,
658
680
  command=("xattr", "-c", target_filename),
@@ -689,10 +711,7 @@ def getWindowsRunningProcessModuleFilename(handle):
689
711
 
690
712
  res = GetModuleFileName(handle, buf, MAX_PATH)
691
713
  if res == 0:
692
- # Windows only code, pylint: disable=I0021,undefined-variable
693
- raise WindowsError(
694
- ctypes.GetLastError(), ctypes.FormatError(ctypes.GetLastError())
695
- )
714
+ raiseWindowsError("getWindowsRunningProcessModuleFilename")
696
715
 
697
716
  return os.path.normcase(buf.value)
698
717
 
@@ -726,10 +745,7 @@ def _getWindowsRunningProcessModuleHandles():
726
745
  )
727
746
 
728
747
  if not res:
729
- # Windows only code, pylint: disable=I0021,undefined-variable
730
- raise WindowsError(
731
- ctypes.GetLastError(), ctypes.FormatError(ctypes.GetLastError())
732
- )
748
+ raiseWindowsError("getWindowsRunningProcessModuleHandles")
733
749
 
734
750
  return tuple(handle for handle in handles if handle is not None)
735
751
 
@@ -782,10 +798,18 @@ Error, needs 'nm' on your system, to detect exported DLL symbols."""
782
798
 
783
799
 
784
800
  def getDllExportedSymbols(logger, filename):
785
- if isLinux():
801
+ if isLinux or isMacOS():
802
+ if isLinux():
803
+ command = ("nm", "-D", filename)
804
+ elif isMacOS():
805
+ command = ("nm", "-gU", filename) + _getMacOSArchOption()
806
+ else:
807
+ # Need to add e.g. FreeBSD here.
808
+ assert False
809
+
786
810
  output = executeToolChecked(
787
811
  logger=logger,
788
- command=("nm", "-D", filename),
812
+ command=command,
789
813
  absence_message=_nm_usage,
790
814
  )
791
815