Nuitka-winsvc 2.3.9__cp311-cp311-win_amd64.whl → 2.4.1__cp311-cp311-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.

Potentially problematic release.


This version of Nuitka-winsvc might be problematic. Click here for more details.

Files changed (213) hide show
  1. Nuitka_winsvc-2.3.9.data/scripts/nuitka-run.bat → Nuitka_winsvc-2.4.1.data/scripts/nuitka-run.cmd +1 -1
  2. {Nuitka_winsvc-2.3.9.dist-info → Nuitka_winsvc-2.4.1.dist-info}/METADATA +1 -1
  3. {Nuitka_winsvc-2.3.9.dist-info → Nuitka_winsvc-2.4.1.dist-info}/RECORD +213 -210
  4. {Nuitka_winsvc-2.3.9.dist-info → Nuitka_winsvc-2.4.1.dist-info}/WHEEL +1 -1
  5. nuitka/CacheCleanup.py +6 -1
  6. nuitka/HardImportRegistry.py +29 -2
  7. nuitka/MainControl.py +62 -35
  8. nuitka/ModuleRegistry.py +11 -3
  9. nuitka/OptionParsing.py +78 -39
  10. nuitka/Options.py +142 -35
  11. nuitka/OutputDirectories.py +5 -0
  12. nuitka/PostProcessing.py +23 -14
  13. nuitka/PythonFlavors.py +22 -4
  14. nuitka/PythonVersions.py +18 -0
  15. nuitka/Tracing.py +26 -23
  16. nuitka/TreeXML.py +6 -3
  17. nuitka/Version.py +1 -1
  18. nuitka/__main__.py +55 -10
  19. nuitka/build/Backend.scons +6 -1
  20. nuitka/build/CCompilerVersion.scons +1 -0
  21. nuitka/build/Onefile.scons +4 -0
  22. nuitka/build/SconsCaching.py +1 -0
  23. nuitka/build/SconsCompilerSettings.py +1 -0
  24. nuitka/build/SconsHacks.py +5 -1
  25. nuitka/build/SconsInterface.py +2 -0
  26. nuitka/build/SconsUtils.py +5 -2
  27. nuitka/build/include/nuitka/allocator.h +27 -5
  28. nuitka/build/include/nuitka/calling.h +1 -1
  29. nuitka/build/include/nuitka/compiled_frame.h +23 -23
  30. nuitka/build/include/nuitka/compiled_method.h +1 -1
  31. nuitka/build/include/nuitka/exception_groups.h +0 -2
  32. nuitka/build/include/nuitka/helper/attributes.h +7 -1
  33. nuitka/build/include/nuitka/helper/subscripts.h +1 -1
  34. nuitka/build/include/nuitka/helpers.h +7 -4
  35. nuitka/build/include/nuitka/prelude.h +6 -10
  36. nuitka/build/include/nuitka/printing.h +2 -0
  37. nuitka/build/include/nuitka/unfreezing.h +5 -5
  38. nuitka/build/inline_copy/tqdm/tqdm/_monitor.py +4 -1
  39. nuitka/build/static_src/CompiledAsyncgenType.c +2 -4
  40. nuitka/build/static_src/CompiledCellType.c +7 -7
  41. nuitka/build/static_src/CompiledCodeHelpers.c +51 -36
  42. nuitka/build/static_src/CompiledCoroutineType.c +2 -4
  43. nuitka/build/static_src/CompiledFrameType.c +109 -82
  44. nuitka/build/static_src/CompiledFunctionType.c +36 -9
  45. nuitka/build/static_src/CompiledGeneratorType.c +12 -10
  46. nuitka/build/static_src/CompiledGeneratorTypeUncompiledIntegration.c +2 -2
  47. nuitka/build/static_src/CompiledMethodType.c +14 -13
  48. nuitka/build/static_src/HelpersAttributes.c +13 -15
  49. nuitka/build/static_src/HelpersBuiltin.c +18 -9
  50. nuitka/build/static_src/HelpersCalling.c +13 -13
  51. nuitka/build/static_src/HelpersCallingGenerated.c +22 -22
  52. nuitka/build/static_src/HelpersComparisonEq.c +110 -110
  53. nuitka/build/static_src/HelpersComparisonEqUtils.c +1 -1
  54. nuitka/build/static_src/HelpersComparisonGe.c +110 -110
  55. nuitka/build/static_src/HelpersComparisonGt.c +110 -110
  56. nuitka/build/static_src/HelpersComparisonLe.c +110 -110
  57. nuitka/build/static_src/HelpersComparisonLt.c +110 -110
  58. nuitka/build/static_src/HelpersComparisonNe.c +110 -110
  59. nuitka/build/static_src/HelpersConstantsBlob.c +480 -481
  60. nuitka/build/static_src/HelpersDictionaries.c +9 -0
  61. nuitka/build/static_src/HelpersFiles.c +2 -2
  62. nuitka/build/static_src/HelpersFilesystemPaths.c +28 -13
  63. nuitka/build/static_src/HelpersHeapStorage.c +4 -0
  64. nuitka/build/static_src/HelpersImport.c +1 -1
  65. nuitka/build/static_src/HelpersLists.c +5 -1
  66. nuitka/build/static_src/HelpersMatching.c +95 -35
  67. nuitka/build/static_src/HelpersOperationInplaceAdd.c +23 -23
  68. nuitka/build/static_src/HelpersOperationInplaceAddUtils.c +1 -0
  69. nuitka/build/static_src/HelpersOperationInplaceBitand.c +11 -11
  70. nuitka/build/static_src/HelpersOperationInplaceBitor.c +11 -11
  71. nuitka/build/static_src/HelpersOperationInplaceBitxor.c +11 -11
  72. nuitka/build/static_src/HelpersOperationInplaceFloordiv.c +17 -17
  73. nuitka/build/static_src/HelpersOperationInplaceLshift.c +9 -9
  74. nuitka/build/static_src/HelpersOperationInplaceMatmult.c +10 -10
  75. nuitka/build/static_src/HelpersOperationInplaceMod.c +47 -47
  76. nuitka/build/static_src/HelpersOperationInplaceMult.c +28 -28
  77. nuitka/build/static_src/HelpersOperationInplaceOlddiv.c +17 -17
  78. nuitka/build/static_src/HelpersOperationInplacePow.c +17 -17
  79. nuitka/build/static_src/HelpersOperationInplaceRshift.c +9 -9
  80. nuitka/build/static_src/HelpersOperationInplaceSub.c +17 -17
  81. nuitka/build/static_src/HelpersOperationInplaceTruediv.c +17 -17
  82. nuitka/build/static_src/HelpersSequences.c +1 -1
  83. nuitka/build/static_src/HelpersTypes.c +8 -4
  84. nuitka/build/static_src/MainProgram.c +28 -9
  85. nuitka/build/static_src/MetaPathBasedLoader.c +126 -110
  86. nuitka/build/static_src/MetaPathBasedLoaderImportlibMetadataDistribution.c +13 -4
  87. nuitka/build/static_src/MetaPathBasedLoaderResourceReaderFiles.c +30 -1
  88. nuitka/build/static_src/OnefileBootstrap.c +34 -6
  89. nuitka/code_generation/AttributeCodes.py +12 -10
  90. nuitka/code_generation/CodeGeneration.py +6 -7
  91. nuitka/code_generation/ConstantCodes.py +53 -10
  92. nuitka/code_generation/GlobalConstants.py +6 -6
  93. nuitka/code_generation/Indentation.py +3 -4
  94. nuitka/code_generation/LoaderCodes.py +3 -0
  95. nuitka/code_generation/LocalsDictCodes.py +36 -14
  96. nuitka/code_generation/MatchCodes.py +23 -4
  97. nuitka/code_generation/ModuleCodes.py +0 -7
  98. nuitka/code_generation/Namify.py +2 -0
  99. nuitka/code_generation/PackageResourceCodes.py +5 -1
  100. nuitka/code_generation/templates/CodeTemplatesConstants.py +6 -4
  101. nuitka/code_generation/templates/CodeTemplatesLoader.py +1 -1
  102. nuitka/code_generation/templates/CodeTemplatesModules.py +3 -3
  103. nuitka/code_generation/templates/CodeTemplatesVariables.py +16 -2
  104. nuitka/code_generation/templates_c/CodeTemplateCallsMethodPositional.c.j2 +2 -2
  105. nuitka/code_generation/templates_c/HelperOperationBinary.c.j2 +1 -1
  106. nuitka/code_generation/templates_c/HelperOperationInplace.c.j2 +1 -1
  107. nuitka/code_generation/templates_c/HelperSlotsBinary.c.j2 +7 -7
  108. nuitka/freezer/DependsExe.py +3 -1
  109. nuitka/freezer/DllDependenciesMacOS.py +28 -14
  110. nuitka/freezer/IncludedDataFiles.py +12 -3
  111. nuitka/freezer/IncludedEntryPoints.py +8 -2
  112. nuitka/freezer/Onefile.py +6 -1
  113. nuitka/freezer/Standalone.py +9 -2
  114. nuitka/importing/Importing.py +14 -5
  115. nuitka/importing/Recursion.py +3 -0
  116. nuitka/nodes/AttributeNodesGenerated.py +21 -12
  117. nuitka/nodes/BuiltinOpenNodes.py +5 -0
  118. nuitka/nodes/BuiltinOperationNodeBasesGenerated.py +11 -11
  119. nuitka/nodes/BuiltinRefNodes.py +41 -1
  120. nuitka/nodes/ChildrenHavingMixins.py +143 -355
  121. nuitka/nodes/ClassNodes.py +30 -12
  122. nuitka/nodes/CodeObjectSpecs.py +9 -0
  123. nuitka/nodes/ExpressionBasesGenerated.py +11 -11
  124. nuitka/nodes/FunctionNodes.py +11 -12
  125. nuitka/nodes/FutureSpecs.py +16 -3
  126. nuitka/nodes/GeneratorNodes.py +2 -2
  127. nuitka/nodes/HardImportNodesGenerated.py +11 -134
  128. nuitka/nodes/LocalsScopes.py +19 -23
  129. nuitka/nodes/MatchNodes.py +18 -7
  130. nuitka/nodes/ModuleAttributeNodes.py +1 -20
  131. nuitka/nodes/ModuleNodes.py +23 -6
  132. nuitka/nodes/NodeBases.py +13 -11
  133. nuitka/nodes/NodeMetaClasses.py +26 -10
  134. nuitka/nodes/ReturnNodes.py +1 -1
  135. nuitka/nodes/StatementBasesGenerated.py +11 -11
  136. nuitka/nodes/SubscriptNodes.py +4 -4
  137. nuitka/nodes/VariableAssignNodes.py +1 -1
  138. nuitka/nodes/VariableRefNodes.py +28 -2
  139. nuitka/nodes/shapes/BuiltinTypeShapes.py +21 -1
  140. nuitka/optimizations/FunctionInlining.py +3 -6
  141. nuitka/optimizations/Optimization.py +13 -12
  142. nuitka/optimizations/TraceCollections.py +19 -4
  143. nuitka/plugins/PluginBase.py +121 -133
  144. nuitka/plugins/Plugins.py +91 -3
  145. nuitka/plugins/YamlPluginBase.py +121 -0
  146. nuitka/plugins/standard/AntiBloatPlugin.py +87 -28
  147. nuitka/plugins/standard/DataFilesPlugin.py +15 -6
  148. nuitka/plugins/standard/DelvewheelPlugin.py +7 -3
  149. nuitka/plugins/standard/DllFilesPlugin.py +5 -3
  150. nuitka/plugins/standard/ImplicitImports.py +34 -20
  151. nuitka/plugins/standard/MatplotlibPlugin.py +3 -1
  152. nuitka/plugins/standard/MultiprocessingPlugin.py +2 -2
  153. nuitka/plugins/standard/OptionsNannyPlugin.py +1 -1
  154. nuitka/plugins/standard/PySidePyQtPlugin.py +11 -12
  155. nuitka/plugins/standard/SpacyPlugin.py +136 -0
  156. nuitka/plugins/standard/standard.nuitka-package.config.yml +491 -186
  157. nuitka/plugins/standard/stdlib3.nuitka-package.config.yml +17 -0
  158. nuitka/reports/Reports.py +53 -5
  159. nuitka/specs/BuiltinParameterSpecs.py +1 -1
  160. nuitka/specs/HardImportSpecs.py +0 -6
  161. nuitka/tools/data_composer/DataComposer.py +29 -27
  162. nuitka/tools/environments/CreateEnvironment.py +1 -0
  163. nuitka/tools/environments/Virtualenv.py +25 -11
  164. nuitka/tools/general/find_module/FindModuleCode.py +13 -3
  165. nuitka/tools/onefile_compressor/OnefileCompressor.py +21 -4
  166. nuitka/tools/scanning/DisplayPackageDLLs.py +17 -3
  167. nuitka/tools/specialize/CTypeDescriptions.py +13 -7
  168. nuitka/tools/specialize/SpecializePython.py +18 -1
  169. nuitka/tools/testing/Common.py +19 -6
  170. nuitka/tools/testing/check_reference_counts/__main__.py +1 -1
  171. nuitka/tools/testing/run_nuitka_tests/__main__.py +0 -20
  172. nuitka/tools/watch/AutoStage.py +144 -0
  173. nuitka/tools/watch/__main__.py +79 -32
  174. nuitka/tree/Building.py +105 -104
  175. nuitka/tree/ComplexCallHelperFunctions.py +16 -26
  176. nuitka/tree/InternalModule.py +9 -1
  177. nuitka/tree/ReformulationAssignmentStatements.py +29 -59
  178. nuitka/tree/ReformulationClasses.py +10 -17
  179. nuitka/tree/ReformulationClasses3.py +69 -43
  180. nuitka/tree/ReformulationComparisonExpressions.py +6 -16
  181. nuitka/tree/ReformulationContractionExpressions.py +14 -23
  182. nuitka/tree/ReformulationDictionaryCreation.py +6 -10
  183. nuitka/tree/ReformulationExecStatements.py +10 -10
  184. nuitka/tree/ReformulationForLoopStatements.py +6 -12
  185. nuitka/tree/ReformulationFunctionStatements.py +22 -28
  186. nuitka/tree/ReformulationImportStatements.py +8 -10
  187. nuitka/tree/ReformulationLambdaExpressions.py +3 -6
  188. nuitka/tree/ReformulationMatchStatements.py +166 -60
  189. nuitka/tree/ReformulationMultidist.py +3 -1
  190. nuitka/tree/ReformulationNamespacePackages.py +1 -1
  191. nuitka/tree/ReformulationPrintStatements.py +3 -6
  192. nuitka/tree/ReformulationSequenceCreation.py +13 -26
  193. nuitka/tree/ReformulationTryFinallyStatements.py +15 -0
  194. nuitka/tree/ReformulationWithStatements.py +12 -16
  195. nuitka/tree/SourceHandling.py +13 -8
  196. nuitka/tree/VariableClosure.py +5 -21
  197. nuitka/utils/Distributions.py +80 -11
  198. nuitka/utils/Download.py +38 -31
  199. nuitka/utils/Execution.py +21 -9
  200. nuitka/utils/FileOperations.py +55 -28
  201. nuitka/utils/Images.py +6 -1
  202. nuitka/utils/Importing.py +1 -1
  203. nuitka/utils/ModuleNames.py +11 -5
  204. nuitka/utils/ReExecute.py +17 -13
  205. nuitka/utils/SharedLibraries.py +69 -41
  206. nuitka/utils/Signing.py +3 -1
  207. nuitka/utils/StaticLibraries.py +51 -41
  208. nuitka/utils/Timing.py +1 -1
  209. nuitka/utils/Utils.py +29 -7
  210. /Nuitka_winsvc-2.3.9.data/scripts/nuitka.bat → /Nuitka_winsvc-2.4.1.data/scripts/nuitka.cmd +0 -0
  211. {Nuitka_winsvc-2.3.9.dist-info → Nuitka_winsvc-2.4.1.dist-info}/LICENSE.txt +0 -0
  212. {Nuitka_winsvc-2.3.9.dist-info → Nuitka_winsvc-2.4.1.dist-info}/entry_points.txt +0 -0
  213. {Nuitka_winsvc-2.3.9.dist-info → Nuitka_winsvc-2.4.1.dist-info}/top_level.txt +0 -0
@@ -574,6 +574,15 @@ int DICT_HAS_ITEM(PyThreadState *tstate, PyObject *dict, PyObject *key) {
574
574
 
575
575
  return 0;
576
576
  }
577
+
578
+ #if PYTHON_VERSION < 0x370 || PYTHON_VERSION >= 0x3b0
579
+ assert(value_addr != NULL);
580
+ PyObject *result = *value_addr;
581
+ #endif
582
+
583
+ if (unlikely(result == NULL)) {
584
+ return 0;
585
+ }
577
586
  #endif
578
587
  return 1;
579
588
  #endif
@@ -10,7 +10,7 @@
10
10
 
11
11
  // Small helper to open files with few arguments.
12
12
  PyObject *BUILTIN_OPEN_SIMPLE(PyThreadState *tstate, PyObject *filename, char const *mode, bool buffering,
13
- PyObject *encoding) {
13
+ PyObject *encoding, bool close_fd) {
14
14
  PyObject *mode_obj = Nuitka_String_FromString(mode);
15
15
  PyObject *buffering_obj = buffering ? const_int_pos_1 : const_int_0;
16
16
 
@@ -38,7 +38,7 @@ PyObject *BUILTIN_OPEN_SIMPLE(PyThreadState *tstate, PyObject *filename, char co
38
38
  PyObject *mode_obj2 = PyUnicode_FromString("wb");
39
39
 
40
40
  PyObject *binary_stream =
41
- BUILTIN_OPEN(tstate, filename, mode_obj2, buffering_obj, NULL, NULL, NULL, NULL, NULL);
41
+ BUILTIN_OPEN(tstate, filename, mode_obj2, buffering_obj, NULL, NULL, NULL, BOOL_FROM(close_fd), NULL);
42
42
 
43
43
  Py_DECREF(mode_obj2);
44
44
 
@@ -18,7 +18,9 @@
18
18
  #include <dlfcn.h>
19
19
  #include <fcntl.h>
20
20
  #include <libgen.h>
21
+ #if !defined(__wasi__)
21
22
  #include <pwd.h>
23
+ #endif
22
24
  #include <stdlib.h>
23
25
  #include <strings.h>
24
26
  #include <sys/mman.h>
@@ -35,7 +37,7 @@
35
37
  #include "nuitka/safe_string_ops.h"
36
38
 
37
39
  #if defined(__OpenBSD__)
38
- void _getBinaryPath2(char *epath) {
40
+ void _getBinaryPath2(char *binary_filename) {
39
41
  int mib[4];
40
42
  mib[0] = CTL_KERN;
41
43
  mib[1] = KERN_PROC_ARGS;
@@ -60,7 +62,7 @@ void _getBinaryPath2(char *epath) {
60
62
  const char *comm = argv[0];
61
63
 
62
64
  if (*comm == '/' || *comm == '.') {
63
- if (realpath(comm, epath) == NULL) {
65
+ if (realpath(comm, binary_filename) == NULL) {
64
66
  abort();
65
67
  }
66
68
  } else {
@@ -74,9 +76,9 @@ void _getBinaryPath2(char *epath) {
74
76
  }
75
77
 
76
78
  while (path) {
77
- snprintf(epath, PATH_MAX, "%s/%s", path, comm);
79
+ snprintf(binary_filename, PATH_MAX, "%s/%s", path, comm);
78
80
 
79
- if (!stat(epath, &st) && (st.st_mode & S_IXUSR)) {
81
+ if (!stat(binary_filename, &st) && (st.st_mode & S_IXUSR)) {
80
82
  break;
81
83
  }
82
84
 
@@ -225,7 +227,7 @@ int64_t getFileSize(FILE_HANDLE file_handle) {
225
227
  #if defined(__APPLE__)
226
228
  #include <copyfile.h>
227
229
  #else
228
- #if defined(__MSYS__) || defined(__HAIKU__) || defined(__OpenBSD__)
230
+ #if defined(__MSYS__) || defined(__HAIKU__) || defined(__OpenBSD__) || defined(__wasi__)
229
231
  static bool sendfile(int output_file, int input_file, off_t *bytesCopied, size_t count) {
230
232
  char buffer[32768];
231
233
 
@@ -435,6 +437,7 @@ static struct MapFileToMemoryInfo mapFileToMemory(filename_char_t const *filenam
435
437
  result.error = true;
436
438
  result.error_code = errno;
437
439
  result.erroring_function = "open";
440
+ result.file_size = -1;
438
441
  return result;
439
442
  }
440
443
 
@@ -573,6 +576,9 @@ static void resolveFileSymbolicLink(wchar_t *resolved_filename, wchar_t const *f
573
576
 
574
577
  static void resolveFileSymbolicLink(char *resolved_filename, char const *filename, size_t resolved_filename_size,
575
578
  bool resolve_symlinks) {
579
+ #ifdef __wasi__
580
+ copyStringSafe(resolved_filename, filename, resolved_filename_size);
581
+ #else
576
582
  if (resolve_symlinks) {
577
583
  // At least on macOS, realpath cannot allocate a buffer, itself, so lets
578
584
  // use a local one, only on Linux we could use NULL argument and have a
@@ -589,24 +595,27 @@ static void resolveFileSymbolicLink(char *resolved_filename, char const *filenam
589
595
  } else {
590
596
  copyStringSafe(resolved_filename, filename, resolved_filename_size);
591
597
  }
598
+ #endif
592
599
  }
593
600
  #endif
594
601
 
595
602
  #ifdef _WIN32
596
603
  wchar_t const *getBinaryFilenameWideChars(bool resolve_symlinks) {
597
- static wchar_t binary_filename[MAXPATHLEN + 1];
598
- static bool init_done = false;
604
+ static wchar_t binary_filename[MAXPATHLEN + 1] = {0};
605
+ static wchar_t binary_filename_resolved[MAXPATHLEN + 1] = {0};
599
606
 
600
- if (init_done == false) {
601
- DWORD res = GetModuleFileNameW(NULL, binary_filename, sizeof(binary_filename) / sizeof(wchar_t));
607
+ wchar_t *buffer = resolve_symlinks ? binary_filename : binary_filename_resolved;
608
+ assert(sizeof(binary_filename) == sizeof(binary_filename_resolved));
609
+
610
+ if (buffer[0] == 0) {
611
+ DWORD res = GetModuleFileNameW(NULL, buffer, sizeof(binary_filename) / sizeof(wchar_t));
602
612
  assert(res != 0);
603
613
 
604
614
  // Resolve any symlinks we were invoked via
605
- resolveFileSymbolicLink(binary_filename, binary_filename, sizeof(binary_filename) / sizeof(wchar_t),
606
- resolve_symlinks);
615
+ resolveFileSymbolicLink(buffer, buffer, sizeof(binary_filename) / sizeof(wchar_t), resolve_symlinks);
607
616
  }
608
617
 
609
- return binary_filename;
618
+ return buffer;
610
619
  }
611
620
  #endif
612
621
 
@@ -675,6 +684,9 @@ char const *getBinaryFilenameHostEncoded(bool resolve_symlinks) {
675
684
 
676
685
  // Resolve any symlinks we were invoked via
677
686
  resolveFileSymbolicLink(binary_filename_target, binary_filename_target, buffer_size, resolve_symlinks);
687
+ #elif defined(__wasi__)
688
+ const char *wasi_filename = "program.wasm";
689
+ strncpy(binary_filename_resolved, wasi_filename, MAXPATHLEN);
678
690
  #elif defined(__OpenBSD__)
679
691
  _getBinaryPath2(binary_filename_target);
680
692
  resolveFileSymbolicLink(binary_filename_target, binary_filename_target, buffer_size, resolve_symlinks);
@@ -949,8 +961,10 @@ bool expandTemplatePath(char *target, char const *source, size_t buffer_size) {
949
961
  appendStringSafe(target, pid_buffer, buffer_size);
950
962
  } else if (strcasecmp(var_name, "HOME") == 0) {
951
963
  char const *home_path = getenv("HOME");
952
-
953
964
  if (home_path == NULL) {
965
+ #ifdef __wasi__
966
+ return false;
967
+ #else
954
968
  struct passwd *pw_data = getpwuid(getuid());
955
969
 
956
970
  if (unlikely(pw_data == NULL)) {
@@ -958,6 +972,7 @@ bool expandTemplatePath(char *target, char const *source, size_t buffer_size) {
958
972
  }
959
973
 
960
974
  home_path = pw_data->pw_dir;
975
+ #endif
961
976
  }
962
977
 
963
978
  appendStringSafe(target, home_path, buffer_size);
@@ -28,6 +28,8 @@ void Nuitka_PreserveHeap(void *dest, ...) {
28
28
  memcpy(w, source, size);
29
29
  w += size;
30
30
  }
31
+
32
+ va_end(ap);
31
33
  }
32
34
 
33
35
  void Nuitka_RestoreHeap(void *source, ...) {
@@ -46,6 +48,8 @@ void Nuitka_RestoreHeap(void *source, ...) {
46
48
  memcpy(dest, w, size);
47
49
  w += size;
48
50
  }
51
+
52
+ va_end(ap);
49
53
  }
50
54
 
51
55
  // Part of "Nuitka", an optimizing Python compiler that is compatible and
@@ -236,7 +236,7 @@ PyObject *IMPORT_NAME_FROM_MODULE(PyThreadState *tstate, PyObject *module, PyObj
236
236
  Py_DECREF(filename);
237
237
  Py_DECREF(name);
238
238
 
239
- #elif PYTHON_VERSION >= 0x340 || !defined(_NUITKA_FULL_COMPAT)
239
+ #elif PYTHON_VERSION >= 0x300 || !defined(_NUITKA_FULL_COMPAT)
240
240
  PyErr_Format(PyExc_ImportError, "cannot import name '%s'", Nuitka_String_AsString(import_name));
241
241
  #else
242
242
  PyErr_Format(PyExc_ImportError, "cannot import name %s", Nuitka_String_AsString(import_name));
@@ -227,7 +227,7 @@ bool LIST_EXTEND_FROM_ITERABLE(PyThreadState *tstate, PyObject *target, PyObject
227
227
 
228
228
  Py_ssize_t cur_size = PyList_GET_SIZE(list);
229
229
 
230
- #if PYTHON_VERSION >= 0x340
230
+ #if PYTHON_VERSION >= 0x300
231
231
  // Guess a iterator size if possible
232
232
  src_size = PyObject_LengthHint(other, 8);
233
233
 
@@ -757,6 +757,8 @@ PyObject *MAKE_LIST(PyThreadState *tstate, PyObject *iterable) {
757
757
  return list;
758
758
  }
759
759
  #else
760
+ Py_INCREF(iterable);
761
+
760
762
  #if PYTHON_VERSION >= 0x340
761
763
  if (Nuitka_PyObject_HasLen(iterable)) {
762
764
  Py_ssize_t iter_len = Nuitka_PyObject_Size(iterable);
@@ -779,6 +781,8 @@ PyObject *MAKE_LIST(PyThreadState *tstate, PyObject *iterable) {
779
781
 
780
782
  bool res = LIST_EXTEND_FROM_ITERABLE(tstate, list, iterable);
781
783
 
784
+ Py_DECREF(iterable);
785
+
782
786
  if (unlikely(res == false)) {
783
787
  Py_DECREF(list);
784
788
  return NULL;
@@ -18,46 +18,59 @@ static void FORMAT_MATCH_MISMATCH_ERROR(PyTypeObject *type, Py_ssize_t max_allow
18
18
  ((PyTypeObject *)type)->tp_name, max_allowed, plural_form, actual);
19
19
  }
20
20
 
21
- PyObject *MATCH_CLASS_ARGS(PyThreadState *tstate, PyObject *matched, Py_ssize_t max_allowed) {
21
+ PyObject *MATCH_CLASS_ARGS(PyThreadState *tstate, PyObject *matched, PyObject *matched_type,
22
+ Py_ssize_t positional_count, PyObject **keywords, Py_ssize_t keywords_count) {
22
23
  PyObject *match_args = NULL;
23
- PyTypeObject *type = Py_TYPE(matched);
24
+ PyTypeObject *type = (PyTypeObject *)matched_type;
24
25
 
25
- // First, the positional sub-patterns:
26
- match_args = LOOKUP_ATTRIBUTE(tstate, (PyObject *)type, const_str_plain___match_args__);
27
- Py_ssize_t actual;
26
+ PyObject *seen = NULL;
27
+ bool needs_check = positional_count + keywords_count > 1;
28
+ if (needs_check) {
29
+ seen = PySet_New(NULL);
30
+ }
28
31
 
29
- if (match_args) {
30
- if (unlikely(!PyTuple_CheckExact(match_args))) {
31
- PyErr_Format(PyExc_TypeError, "%s.__match_args__ must be a tuple (got %s)", type->tp_name,
32
- Py_TYPE(match_args)->tp_name);
33
- Py_DECREF(match_args);
34
- return NULL;
35
- }
32
+ assert(positional_count + keywords_count > 0);
33
+
34
+ // First, the positional sub-patterns if any.
35
+ if (positional_count > 0) {
36
+ match_args = LOOKUP_ATTRIBUTE(tstate, (PyObject *)type, const_str_plain___match_args__);
37
+ Py_ssize_t actual;
36
38
 
37
- actual = PyTuple_GET_SIZE(match_args);
38
- } else if (CHECK_AND_CLEAR_ATTRIBUTE_ERROR_OCCURRED(tstate)) {
39
- if (PyType_HasFeature(type, _Py_TPFLAGS_MATCH_SELF)) {
40
- if (max_allowed > 1) {
41
- FORMAT_MATCH_MISMATCH_ERROR(type, max_allowed, 1);
39
+ if (match_args) {
40
+ if (unlikely(!PyTuple_CheckExact(match_args))) {
41
+ PyErr_Format(PyExc_TypeError, "%s.__match_args__ must be a tuple (got %s)", type->tp_name,
42
+ Py_TYPE(match_args)->tp_name);
43
+ Py_DECREF(match_args);
42
44
  return NULL;
43
45
  }
44
46
 
45
- return MAKE_TUPLE1(tstate, matched);
46
- }
47
+ actual = PyTuple_GET_SIZE(match_args);
48
+ } else if (CHECK_AND_CLEAR_ATTRIBUTE_ERROR_OCCURRED(tstate)) {
49
+ if (PyType_HasFeature(type, _Py_TPFLAGS_MATCH_SELF)) {
50
+ if (positional_count > 1) {
51
+ FORMAT_MATCH_MISMATCH_ERROR(type, positional_count, 1);
52
+ return NULL;
53
+ }
47
54
 
48
- actual = 0;
49
- } else {
50
- return NULL;
51
- }
55
+ assert(keywords_count == 0);
56
+
57
+ return MAKE_TUPLE1(tstate, matched);
58
+ }
59
+
60
+ actual = 0;
61
+ } else {
62
+ return NULL;
63
+ }
52
64
 
53
- if (max_allowed > actual) {
54
- FORMAT_MATCH_MISMATCH_ERROR(type, max_allowed, actual);
55
- return NULL;
65
+ if (positional_count > actual) {
66
+ FORMAT_MATCH_MISMATCH_ERROR(type, positional_count, actual);
67
+ return NULL;
68
+ }
56
69
  }
57
70
 
58
- PyObject *result = MAKE_TUPLE_EMPTY_VAR(tstate, actual);
71
+ PyObject *result = MAKE_TUPLE_EMPTY_VAR(tstate, positional_count + keywords_count);
59
72
 
60
- for (Py_ssize_t i = 0; i < max_allowed; i++) {
73
+ for (Py_ssize_t i = 0; i < positional_count; i++) {
61
74
  PyObject *arg_name = PyTuple_GET_ITEM(match_args, i);
62
75
 
63
76
  if (unlikely(!PyUnicode_CheckExact(arg_name))) {
@@ -72,27 +85,74 @@ PyObject *MATCH_CLASS_ARGS(PyThreadState *tstate, PyObject *matched, Py_ssize_t
72
85
  return NULL;
73
86
  }
74
87
 
88
+ if (needs_check) {
89
+ if (i != 0 && PySet_Contains(seen, arg_name)) {
90
+ _PyErr_Format(tstate, PyExc_TypeError, "%s() got multiple sub-patterns for attribute %R",
91
+ ((PyTypeObject *)type)->tp_name, arg_name);
92
+
93
+ return NULL;
94
+ }
95
+
96
+ PySet_Add(seen, arg_name);
97
+ }
98
+
75
99
  PyObject *arg_value = LOOKUP_ATTRIBUTE(tstate, matched, arg_name);
76
100
  if (unlikely(arg_value == NULL)) {
101
+ DROP_ERROR_OCCURRED(tstate);
102
+
77
103
  Py_DECREF(match_args);
78
104
  Py_DECREF(result);
79
105
 
80
- return NULL;
106
+ Py_INCREF_IMMORTAL(Py_None);
107
+ return Py_None;
81
108
  }
82
109
 
83
110
  PyTuple_SET_ITEM(result, i, arg_value);
84
111
  }
85
112
 
86
- Py_DECREF(match_args);
113
+ for (Py_ssize_t i = 0; i < keywords_count; i++) {
114
+ PyObject *arg_name = keywords[i];
115
+ CHECK_OBJECT(arg_name);
116
+ assert(PyUnicode_CheckExact(arg_name));
117
+
118
+ if (needs_check) {
119
+ if (PySet_Contains(seen, arg_name)) {
120
+ _PyErr_Format(tstate, PyExc_TypeError, "%s() got multiple sub-patterns for attribute %R",
121
+ ((PyTypeObject *)type)->tp_name, arg_name);
122
+
123
+ return NULL;
124
+ }
125
+
126
+ PySet_Add(seen, arg_name);
127
+ }
128
+
129
+ PyObject *arg_value = LOOKUP_ATTRIBUTE(tstate, matched, arg_name);
130
+ if (unlikely(arg_value == NULL)) {
131
+ DROP_ERROR_OCCURRED(tstate);
132
+
133
+ Py_DECREF(match_args);
134
+ Py_DECREF(result);
135
+
136
+ Py_INCREF_IMMORTAL(Py_None);
137
+ return Py_None;
138
+ }
139
+
140
+ PyTuple_SET_ITEM(result, positional_count + i, arg_value);
141
+ }
142
+
143
+ Py_XDECREF(match_args);
87
144
  return result;
88
145
  }
89
146
 
90
- int MATCH_MAPPING_KEY(PyThreadState *tstate, PyObject *map, PyObject *key) {
147
+ bool MATCH_MAPPING_KEY(PyThreadState *tstate, PyObject *map, PyObject *key) {
91
148
  // Need to use get_method with default value, so "defaultdict" do not
92
149
  // mutate. TODO: Use a cached value across the "match".
150
+ // spell-checker: ignore defaultdict
93
151
  PyObject *get_method = LOOKUP_ATTRIBUTE(tstate, map, const_str_plain_get);
94
152
  if (unlikely(get_method == NULL)) {
95
- return -1;
153
+ // TODO: Maybe only drop AttributeError?
154
+ DROP_ERROR_OCCURRED(tstate);
155
+ return false;
96
156
  }
97
157
 
98
158
  PyObject *args[] = {key, Nuitka_sentinel_value};
@@ -102,18 +162,18 @@ int MATCH_MAPPING_KEY(PyThreadState *tstate, PyObject *map, PyObject *key) {
102
162
  Py_XDECREF(get_method);
103
163
 
104
164
  if (unlikely(value == NULL)) {
105
- return -1;
165
+ return false;
106
166
  }
107
167
 
108
168
  if (value == Nuitka_sentinel_value) {
109
169
  Py_DECREF_IMMORTAL(value);
110
170
 
111
- return 0;
171
+ return false;
112
172
  }
113
173
 
114
174
  Py_DECREF(value);
115
175
 
116
- return 1;
176
+ return true;
117
177
  }
118
178
 
119
179
  // Part of "Nuitka", an optimizing Python compiler that is compatible and
@@ -245,7 +245,7 @@ static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_ADD_OBJECT_INT(PyObject **op
245
245
  }
246
246
  }
247
247
 
248
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'int'", type1->tp_name);
248
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: '%s' and 'int'", type1->tp_name);
249
249
  goto exit_inplace_exception;
250
250
  }
251
251
 
@@ -497,7 +497,7 @@ static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_ADD_INT_OBJECT(PyObject **op
497
497
  // No inplace sequence repeat slot sq_inplace_concat available for this type.
498
498
  }
499
499
 
500
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'int' and '%s'", type2->tp_name);
500
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: 'int' and '%s'", type2->tp_name);
501
501
  goto exit_inplace_exception;
502
502
  }
503
503
 
@@ -881,9 +881,9 @@ static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_ADD_OBJECT_LONG(PyObject **o
881
881
  }
882
882
 
883
883
  #if PYTHON_VERSION < 0x300
884
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'long'", type1->tp_name);
884
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: '%s' and 'long'", type1->tp_name);
885
885
  #else
886
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'int'", type1->tp_name);
886
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: '%s' and 'int'", type1->tp_name);
887
887
  #endif
888
888
  goto exit_inplace_exception;
889
889
  }
@@ -1180,9 +1180,9 @@ static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_ADD_LONG_OBJECT(PyObject **o
1180
1180
  }
1181
1181
 
1182
1182
  #if PYTHON_VERSION < 0x300
1183
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'long' and '%s'", type2->tp_name);
1183
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: 'long' and '%s'", type2->tp_name);
1184
1184
  #else
1185
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'int' and '%s'", type2->tp_name);
1185
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: 'int' and '%s'", type2->tp_name);
1186
1186
  #endif
1187
1187
  goto exit_inplace_exception;
1188
1188
  }
@@ -1540,7 +1540,7 @@ static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_ADD_OBJECT_FLOAT(PyObject **
1540
1540
  }
1541
1541
  }
1542
1542
 
1543
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'float'", type1->tp_name);
1543
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: '%s' and 'float'", type1->tp_name);
1544
1544
  goto exit_inplace_exception;
1545
1545
  }
1546
1546
 
@@ -1765,7 +1765,7 @@ static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_ADD_FLOAT_OBJECT(PyObject **
1765
1765
  // No inplace sequence repeat slot sq_inplace_concat available for this type.
1766
1766
  }
1767
1767
 
1768
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'float' and '%s'", type2->tp_name);
1768
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: 'float' and '%s'", type2->tp_name);
1769
1769
  goto exit_inplace_exception;
1770
1770
  }
1771
1771
 
@@ -1889,9 +1889,9 @@ static inline bool _INPLACE_OPERATION_ADD_FLOAT_LONG(PyObject **operand1, PyObje
1889
1889
  }
1890
1890
 
1891
1891
  #if PYTHON_VERSION < 0x300
1892
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'float' and 'long'");
1892
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: 'float' and 'long'");
1893
1893
  #else
1894
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'float' and 'int'");
1894
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: 'float' and 'int'");
1895
1895
  #endif
1896
1896
  goto exit_inplace_exception;
1897
1897
  }
@@ -1968,9 +1968,9 @@ static inline bool _INPLACE_OPERATION_ADD_LONG_FLOAT(PyObject **operand1, PyObje
1968
1968
  }
1969
1969
 
1970
1970
  #if PYTHON_VERSION < 0x300
1971
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'long' and 'float'");
1971
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: 'long' and 'float'");
1972
1972
  #else
1973
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'int' and 'float'");
1973
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: 'int' and 'float'");
1974
1974
  #endif
1975
1975
  goto exit_inplace_exception;
1976
1976
  }
@@ -2041,7 +2041,7 @@ static inline bool _INPLACE_OPERATION_ADD_FLOAT_INT(PyObject **operand1, PyObjec
2041
2041
  // No inplace sequence repeat slot sq_inplace_concat available for this type.
2042
2042
  }
2043
2043
 
2044
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'float' and 'int'");
2044
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: 'float' and 'int'");
2045
2045
  goto exit_inplace_exception;
2046
2046
  }
2047
2047
 
@@ -2118,7 +2118,7 @@ static inline bool _INPLACE_OPERATION_ADD_INT_FLOAT(PyObject **operand1, PyObjec
2118
2118
  // No inplace sequence repeat slot sq_inplace_concat available for this type.
2119
2119
  }
2120
2120
 
2121
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'int' and 'float'");
2121
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: 'int' and 'float'");
2122
2122
  goto exit_inplace_exception;
2123
2123
  }
2124
2124
 
@@ -2189,7 +2189,7 @@ static inline bool _INPLACE_OPERATION_ADD_LONG_INT(PyObject **operand1, PyObject
2189
2189
  // No inplace sequence repeat slot sq_inplace_concat available for this type.
2190
2190
  }
2191
2191
 
2192
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'long' and 'int'");
2192
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: 'long' and 'int'");
2193
2193
  goto exit_inplace_exception;
2194
2194
  }
2195
2195
 
@@ -2266,7 +2266,7 @@ static inline bool _INPLACE_OPERATION_ADD_INT_LONG(PyObject **operand1, PyObject
2266
2266
  // No inplace sequence repeat slot sq_inplace_concat available for this type.
2267
2267
  }
2268
2268
 
2269
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'int' and 'long'");
2269
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: 'int' and 'long'");
2270
2270
  goto exit_inplace_exception;
2271
2271
  }
2272
2272
 
@@ -2703,7 +2703,7 @@ static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_ADD_OBJECT_STR(PyObject **op
2703
2703
  }
2704
2704
  }
2705
2705
 
2706
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'str'", type1->tp_name);
2706
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: '%s' and 'str'", type1->tp_name);
2707
2707
  goto exit_inplace_exception;
2708
2708
  }
2709
2709
 
@@ -3096,9 +3096,9 @@ static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_ADD_OBJECT_UNICODE(PyObject
3096
3096
  }
3097
3097
 
3098
3098
  #if PYTHON_VERSION < 0x300
3099
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'unicode'", type1->tp_name);
3099
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: '%s' and 'unicode'", type1->tp_name);
3100
3100
  #else
3101
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'str'", type1->tp_name);
3101
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: '%s' and 'str'", type1->tp_name);
3102
3102
  #endif
3103
3103
  goto exit_inplace_exception;
3104
3104
  }
@@ -3497,7 +3497,7 @@ static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_ADD_OBJECT_BYTES(PyObject **
3497
3497
  }
3498
3498
  }
3499
3499
 
3500
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'bytes'", type1->tp_name);
3500
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: '%s' and 'bytes'", type1->tp_name);
3501
3501
  goto exit_inplace_exception;
3502
3502
  }
3503
3503
 
@@ -3890,7 +3890,7 @@ static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_ADD_OBJECT_TUPLE(PyObject **
3890
3890
  }
3891
3891
  }
3892
3892
 
3893
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'tuple'", type1->tp_name);
3893
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: '%s' and 'tuple'", type1->tp_name);
3894
3894
  goto exit_inplace_exception;
3895
3895
  }
3896
3896
 
@@ -4282,7 +4282,7 @@ static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_ADD_OBJECT_LIST(PyObject **o
4282
4282
  }
4283
4283
  }
4284
4284
 
4285
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'list'", type1->tp_name);
4285
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: '%s' and 'list'", type1->tp_name);
4286
4286
  goto exit_inplace_exception;
4287
4287
  }
4288
4288
 
@@ -4945,7 +4945,7 @@ static inline bool _INPLACE_OPERATION_ADD_OBJECT_OBJECT(PyObject **operand1, PyO
4945
4945
  }
4946
4946
  }
4947
4947
 
4948
- PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and '%s'", type1->tp_name,
4948
+ PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +=: '%s' and '%s'", type1->tp_name,
4949
4949
  type2->tp_name);
4950
4950
  goto exit_inplace_exception;
4951
4951
  }
@@ -75,6 +75,7 @@ NUITKA_MAY_BE_UNUSED static bool BYTES_ADD_INCREMENTAL(PyObject **operand1, PyOb
75
75
  // Has to work.
76
76
  assert(res == 0);
77
77
  }
78
+ assert(wb.len >= 0);
78
79
 
79
80
  Py_ssize_t oldsize = PyBytes_GET_SIZE(*operand1);
80
81