Nuitka-winsvc 2.1.6__cp311-cp311-win_amd64.whl → 2.2.2__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 (234) hide show
  1. {Nuitka_winsvc-2.1.6.dist-info → Nuitka_winsvc-2.2.2.dist-info}/METADATA +1 -1
  2. {Nuitka_winsvc-2.1.6.dist-info → Nuitka_winsvc-2.2.2.dist-info}/RECORD +234 -225
  3. nuitka/Errors.py +4 -0
  4. nuitka/HardImportRegistry.py +18 -1
  5. nuitka/MainControl.py +27 -30
  6. nuitka/OptionParsing.py +32 -30
  7. nuitka/Options.py +26 -13
  8. nuitka/OutputDirectories.py +7 -4
  9. nuitka/PostProcessing.py +9 -7
  10. nuitka/Progress.py +3 -3
  11. nuitka/PythonVersions.py +2 -2
  12. nuitka/TreeXML.py +1 -1
  13. nuitka/Version.py +1 -1
  14. nuitka/build/Backend.scons +2 -1
  15. nuitka/build/DataComposerInterface.py +1 -0
  16. nuitka/build/Onefile.scons +2 -1
  17. nuitka/build/SconsCaching.py +64 -46
  18. nuitka/build/SconsCompilerSettings.py +19 -6
  19. nuitka/build/SconsHacks.py +0 -1
  20. nuitka/build/SconsInterface.py +84 -5
  21. nuitka/build/SconsProgress.py +0 -1
  22. nuitka/build/SconsUtils.py +8 -4
  23. nuitka/build/include/nuitka/allocator.h +8 -3
  24. nuitka/build/include/nuitka/compiled_cell.h +8 -0
  25. nuitka/build/include/nuitka/exceptions.h +554 -179
  26. nuitka/build/include/nuitka/helper/dictionaries.h +1 -1
  27. nuitka/build/include/nuitka/helper/import_hard.h +3 -0
  28. nuitka/build/include/nuitka/helper/ints.h +15 -2
  29. nuitka/build/include/nuitka/helper/lists.h +4 -1
  30. nuitka/build/include/nuitka/helper/raising.h +12 -0
  31. nuitka/build/include/nuitka/helper/tuples.h +5 -1
  32. nuitka/build/include/nuitka/helpers.h +4 -0
  33. nuitka/build/include/nuitka/importing.h +3 -4
  34. nuitka/build/include/nuitka/jit_sources.h +25 -0
  35. nuitka/build/include/nuitka/prelude.h +38 -11
  36. nuitka/build/include/nuitka/printing.h +3 -0
  37. nuitka/build/include/nuitka/threading.h +2 -6
  38. nuitka/build/include/nuitka/type_aliases.h +27 -0
  39. nuitka/build/inline_copy/pkg_resources/pkg_resources/__init__.py +0 -3
  40. nuitka/build/inline_copy/tqdm/tqdm/version.py +1 -4
  41. nuitka/build/static_src/CompiledAsyncgenType.c +99 -114
  42. nuitka/build/static_src/CompiledCodeHelpers.c +23 -14
  43. nuitka/build/static_src/CompiledCoroutineType.c +96 -114
  44. nuitka/build/static_src/CompiledFrameType.c +14 -11
  45. nuitka/build/static_src/CompiledFunctionType.c +34 -7
  46. nuitka/build/static_src/CompiledGeneratorType.c +248 -142
  47. nuitka/build/static_src/CompiledGeneratorTypeUncompiledIntegration.c +60 -70
  48. nuitka/build/static_src/CompiledMethodType.c +8 -7
  49. nuitka/build/static_src/HelpersAttributes.c +2 -19
  50. nuitka/build/static_src/HelpersBuiltin.c +2 -1
  51. nuitka/build/static_src/HelpersComparisonEq.c +32 -18
  52. nuitka/build/static_src/HelpersComparisonGe.c +50 -36
  53. nuitka/build/static_src/HelpersComparisonGt.c +50 -36
  54. nuitka/build/static_src/HelpersComparisonLe.c +50 -36
  55. nuitka/build/static_src/HelpersComparisonLt.c +50 -36
  56. nuitka/build/static_src/HelpersComparisonNe.c +32 -18
  57. nuitka/build/static_src/HelpersDeepcopy.c +6 -8
  58. nuitka/build/static_src/HelpersDictionaries.c +8 -3
  59. nuitka/build/static_src/HelpersExceptions.c +42 -28
  60. nuitka/build/static_src/HelpersFilesystemPaths.c +7 -7
  61. nuitka/build/static_src/HelpersImportHard.c +15 -0
  62. nuitka/build/static_src/HelpersJitSources.c +46 -0
  63. nuitka/build/static_src/HelpersLists.c +40 -0
  64. nuitka/build/static_src/HelpersOperationBinaryAdd.c +66 -66
  65. nuitka/build/static_src/HelpersOperationBinaryAddUtils.c +80 -33
  66. nuitka/build/static_src/HelpersOperationBinaryMultUtils.c +16 -13
  67. nuitka/build/static_src/HelpersOperationBinarySub.c +39 -39
  68. nuitka/build/static_src/HelpersOperationInplaceAdd.c +54 -54
  69. nuitka/build/static_src/HelpersOperationInplaceAddUtils.c +1 -1
  70. nuitka/build/static_src/HelpersOperationInplaceSub.c +50 -50
  71. nuitka/build/static_src/HelpersProfiling.c +3 -4
  72. nuitka/build/static_src/HelpersRaising.c +62 -1
  73. nuitka/build/static_src/HelpersStrings.c +203 -8
  74. nuitka/build/static_src/HelpersTypes.c +42 -0
  75. nuitka/build/static_src/MainProgram.c +1 -1
  76. nuitka/build/static_src/MetaPathBasedLoader.c +2 -1
  77. nuitka/build/static_src/OnefileBootstrap.c +3 -3
  78. nuitka/code_generation/BinaryOperationHelperDefinitions.py +5 -3
  79. nuitka/code_generation/BuiltinCodes.py +1 -0
  80. nuitka/code_generation/CodeGeneration.py +11 -0
  81. nuitka/code_generation/CodeHelpers.py +5 -3
  82. nuitka/code_generation/CodeObjectCodes.py +10 -6
  83. nuitka/code_generation/ComparisonCodes.py +19 -3
  84. nuitka/code_generation/ConstantCodes.py +5 -0
  85. nuitka/code_generation/Contexts.py +22 -6
  86. nuitka/code_generation/Emission.py +1 -0
  87. nuitka/code_generation/ErrorCodes.py +8 -16
  88. nuitka/code_generation/EvalCodes.py +5 -3
  89. nuitka/code_generation/ExceptionCodes.py +8 -1
  90. nuitka/code_generation/ExpressionCTypeSelectionHelpers.py +1 -0
  91. nuitka/code_generation/FrameCodes.py +5 -3
  92. nuitka/code_generation/FunctionCodes.py +0 -1
  93. nuitka/code_generation/GeneratorCodes.py +3 -3
  94. nuitka/code_generation/GlobalConstants.py +0 -2
  95. nuitka/code_generation/ImportCodes.py +2 -0
  96. nuitka/code_generation/JitCodes.py +44 -0
  97. nuitka/code_generation/ListCodes.py +11 -17
  98. nuitka/code_generation/MatchCodes.py +0 -1
  99. nuitka/code_generation/ModuleCodes.py +2 -1
  100. nuitka/code_generation/Namify.py +0 -1
  101. nuitka/code_generation/NetworkxCodes.py +51 -0
  102. nuitka/code_generation/OperationCodes.py +8 -6
  103. nuitka/code_generation/PackageResourceCodes.py +7 -5
  104. nuitka/code_generation/TensorflowCodes.py +54 -0
  105. nuitka/code_generation/TypeAliasCodes.py +71 -0
  106. nuitka/code_generation/VariableCodes.py +7 -5
  107. nuitka/code_generation/VariableDeclarations.py +1 -0
  108. nuitka/code_generation/c_types/CTypeCLongs.py +0 -1
  109. nuitka/code_generation/c_types/CTypeNuitkaInts.py +0 -1
  110. nuitka/code_generation/c_types/CTypeVoids.py +1 -0
  111. nuitka/code_generation/templates/CodeTemplatesConstants.py +14 -0
  112. nuitka/code_generation/templates/CodeTemplatesExceptions.py +1 -1
  113. nuitka/code_generation/templates/CodeTemplatesIterators.py +0 -1
  114. nuitka/code_generation/templates/CodeTemplatesLoader.py +0 -1
  115. nuitka/code_generation/templates/CodeTemplatesModules.py +9 -4
  116. nuitka/code_generation/templates/CodeTemplatesVariables.py +8 -8
  117. nuitka/code_generation/templates/TemplateDebugWrapper.py +0 -1
  118. nuitka/code_generation/templates_c/HelperOperationComparisonUnicode.c.j2 +4 -0
  119. nuitka/code_generation/templates_c/HelperSlotsLong.c.j2 +9 -7
  120. nuitka/containers/Namedtuples.py +0 -1
  121. nuitka/finalizations/Finalization.py +1 -0
  122. nuitka/finalizations/FinalizeMarkups.py +0 -1
  123. nuitka/freezer/DllDependenciesMacOS.py +60 -13
  124. nuitka/freezer/DllDependenciesPosix.py +0 -1
  125. nuitka/freezer/DllDependenciesWin32.py +2 -1
  126. nuitka/freezer/IncludedDataFiles.py +46 -15
  127. nuitka/freezer/IncludedEntryPoints.py +5 -3
  128. nuitka/freezer/Standalone.py +6 -1
  129. nuitka/importing/ImportCache.py +2 -2
  130. nuitka/importing/ImportResolving.py +80 -78
  131. nuitka/importing/Importing.py +34 -1
  132. nuitka/nodes/AttributeNodesGenerated.py +21 -6
  133. nuitka/nodes/BuiltinComplexNodes.py +1 -0
  134. nuitka/nodes/BuiltinFormatNodes.py +1 -0
  135. nuitka/nodes/BuiltinIteratorNodes.py +5 -3
  136. nuitka/nodes/BuiltinOperationNodeBasesGenerated.py +21 -6
  137. nuitka/nodes/BuiltinRefNodes.py +8 -1
  138. nuitka/nodes/BuiltinVarsNodes.py +0 -1
  139. nuitka/nodes/ChildrenHavingMixins.py +906 -186
  140. nuitka/nodes/CodeObjectSpecs.py +1 -1
  141. nuitka/nodes/ConditionalNodes.py +2 -6
  142. nuitka/nodes/ConstantRefNodes.py +38 -0
  143. nuitka/nodes/CtypesNodes.py +0 -1
  144. nuitka/nodes/DictionaryNodes.py +0 -1
  145. nuitka/nodes/ExceptionNodes.py +10 -0
  146. nuitka/nodes/ExpressionBases.py +15 -9
  147. nuitka/nodes/ExpressionBasesGenerated.py +32 -15
  148. nuitka/nodes/FunctionNodes.py +50 -5
  149. nuitka/nodes/HardImportNodesGenerated.py +245 -60
  150. nuitka/nodes/ImportHardNodes.py +27 -13
  151. nuitka/nodes/ImportNodes.py +92 -70
  152. nuitka/nodes/InjectCNodes.py +0 -1
  153. nuitka/nodes/ModuleNodes.py +10 -5
  154. nuitka/nodes/NetworkxNodes.py +45 -0
  155. nuitka/nodes/OperatorNodesUnary.py +1 -0
  156. nuitka/nodes/OsSysNodes.py +0 -1
  157. nuitka/nodes/PackageMetadataNodes.py +0 -1
  158. nuitka/nodes/PackageResourceNodes.py +10 -6
  159. nuitka/nodes/StatementBasesGenerated.py +107 -60
  160. nuitka/nodes/StringConcatenationNodes.py +1 -0
  161. nuitka/nodes/TensorflowNodes.py +38 -0
  162. nuitka/nodes/TypeNodes.py +21 -0
  163. nuitka/nodes/VariableRefNodes.py +1 -0
  164. nuitka/nodes/shapes/BuiltinTypeShapes.py +25 -15
  165. nuitka/optimizations/Optimization.py +7 -6
  166. nuitka/optimizations/OptimizeBuiltinCalls.py +11 -9
  167. nuitka/optimizations/Tags.py +0 -1
  168. nuitka/optimizations/TraceCollections.py +6 -55
  169. nuitka/optimizations/ValueTraces.py +49 -1
  170. nuitka/plugins/PluginBase.py +26 -4
  171. nuitka/plugins/Plugins.py +49 -12
  172. nuitka/plugins/standard/AntiBloatPlugin.py +12 -2
  173. nuitka/plugins/standard/ConsiderPyLintAnnotationsPlugin.py +0 -1
  174. nuitka/plugins/standard/DataFilesPlugin.py +2 -6
  175. nuitka/plugins/standard/DillPlugin.py +3 -3
  176. nuitka/plugins/standard/DllFilesPlugin.py +29 -23
  177. nuitka/plugins/standard/GiPlugin.py +1 -0
  178. nuitka/plugins/standard/ImplicitImports.py +8 -7
  179. nuitka/plugins/standard/MatplotlibPlugin.py +1 -0
  180. nuitka/plugins/standard/OptionsNannyPlugin.py +3 -7
  181. nuitka/plugins/standard/PkgResourcesPlugin.py +0 -1
  182. nuitka/plugins/standard/PmwPlugin.py +10 -9
  183. nuitka/plugins/standard/PySidePyQtPlugin.py +0 -28
  184. nuitka/plugins/standard/TensorflowPlugin.py +1 -0
  185. nuitka/plugins/standard/TorchPlugin.py +1 -0
  186. nuitka/plugins/standard/TrioPlugin.py +1 -0
  187. nuitka/plugins/standard/standard.nuitka-package.config.yml +249 -34
  188. nuitka/reports/CompilationReportReader.py +0 -1
  189. nuitka/reports/Reports.py +49 -5
  190. nuitka/specs/BuiltinParameterSpecs.py +10 -2
  191. nuitka/specs/BuiltinStrOperationSpecs.py +1 -1
  192. nuitka/specs/BuiltinTypeOperationSpecs.py +0 -1
  193. nuitka/specs/HardImportSpecs.py +34 -1
  194. nuitka/specs/ParameterSpecs.py +11 -9
  195. nuitka/tools/environments/Virtualenv.py +0 -1
  196. nuitka/tools/specialize/CTypeDescriptions.py +15 -11
  197. nuitka/tools/specialize/SpecializeC.py +11 -9
  198. nuitka/tools/specialize/SpecializePython.py +57 -30
  199. nuitka/tools/testing/Common.py +24 -7
  200. nuitka/tools/testing/OutputComparison.py +4 -0
  201. nuitka/tools/testing/Pythons.py +0 -1
  202. nuitka/tools/testing/compare_with_cpython/__main__.py +0 -4
  203. nuitka/tools/watch/GitHub.py +4 -1
  204. nuitka/tools/watch/__main__.py +22 -1
  205. nuitka/tree/Building.py +3 -0
  206. nuitka/tree/InternalModule.py +0 -1
  207. nuitka/tree/ReformulationAssertStatements.py +1 -0
  208. nuitka/tree/ReformulationAssignmentStatements.py +26 -3
  209. nuitka/tree/ReformulationClasses3.py +23 -26
  210. nuitka/tree/ReformulationContractionExpressions.py +5 -3
  211. nuitka/tree/ReformulationDictionaryCreation.py +6 -5
  212. nuitka/tree/ReformulationExecStatements.py +8 -6
  213. nuitka/tree/ReformulationFunctionStatements.py +10 -6
  214. nuitka/tree/SourceHandling.py +8 -0
  215. nuitka/tree/TreeHelpers.py +6 -3
  216. nuitka/utils/AppDirs.py +6 -2
  217. nuitka/utils/CStrings.py +1 -1
  218. nuitka/utils/CommandLineOptions.py +0 -1
  219. nuitka/utils/Distributions.py +3 -3
  220. nuitka/utils/Download.py +5 -1
  221. nuitka/utils/Execution.py +6 -3
  222. nuitka/utils/FileOperations.py +61 -34
  223. nuitka/utils/Importing.py +4 -4
  224. nuitka/utils/InstanceCounters.py +1 -0
  225. nuitka/utils/MacOSApp.py +1 -0
  226. nuitka/utils/Shebang.py +1 -0
  227. nuitka/utils/Utils.py +39 -1
  228. nuitka/utils/WindowsFileUsage.py +4 -3
  229. {Nuitka_winsvc-2.1.6.data → Nuitka_winsvc-2.2.2.data}/scripts/nuitka-run.bat +0 -0
  230. {Nuitka_winsvc-2.1.6.data → Nuitka_winsvc-2.2.2.data}/scripts/nuitka.bat +0 -0
  231. {Nuitka_winsvc-2.1.6.dist-info → Nuitka_winsvc-2.2.2.dist-info}/LICENSE.txt +0 -0
  232. {Nuitka_winsvc-2.1.6.dist-info → Nuitka_winsvc-2.2.2.dist-info}/WHEEL +0 -0
  233. {Nuitka_winsvc-2.1.6.dist-info → Nuitka_winsvc-2.2.2.dist-info}/entry_points.txt +0 -0
  234. {Nuitka_winsvc-2.1.6.dist-info → Nuitka_winsvc-2.2.2.dist-info}/top_level.txt +0 -0
@@ -151,12 +151,16 @@ static void Nuitka_Generator_release_closure(struct Nuitka_GeneratorObject *gene
151
151
  static PyObject *ERROR_GET_STOP_ITERATION_VALUE(PyThreadState *tstate) {
152
152
  assert(PyErr_ExceptionMatches(PyExc_StopIteration));
153
153
 
154
- PyObject *exception_type, *exception_value;
155
- PyTracebackObject *exception_tb;
156
- FETCH_ERROR_OCCURRED(tstate, &exception_type, &exception_value, &exception_tb);
154
+ struct Nuitka_ExceptionPreservationItem saved_exception_state;
155
+ FETCH_ERROR_OCCURRED_STATE(tstate, &saved_exception_state);
157
156
 
158
- Py_DECREF(exception_type);
159
- Py_XDECREF(exception_tb);
157
+ #if PYTHON_VERSION < 0x3c0
158
+ Py_DECREF(saved_exception_state.exception_type);
159
+ Py_XDECREF(saved_exception_state.exception_tb);
160
+ #endif
161
+
162
+ // We own a reference, and we mean to return it.
163
+ PyObject *exception_value = saved_exception_state.exception_value;
160
164
 
161
165
  PyObject *value = NULL;
162
166
 
@@ -178,20 +182,38 @@ static PyObject *ERROR_GET_STOP_ITERATION_VALUE(PyThreadState *tstate) {
178
182
  return value;
179
183
  }
180
184
 
185
+ static PyObject *Nuitka_CallGeneratorThrowMethod(PyObject *throw_method,
186
+ struct Nuitka_ExceptionPreservationItem *exception_state) {
187
+
188
+ // TODO: Faster call code should be used.
189
+
190
+ #if PYTHON_VERSION < 0x3c0
191
+ PyObject *result =
192
+ PyObject_CallFunctionObjArgs(throw_method, exception_state->exception_type, exception_state->exception_value,
193
+ exception_state->exception_tb, NULL);
194
+
195
+ return result;
196
+ #else
197
+ // For Python 3.12 or higher, we don't create the type and tb args, code was
198
+ // always supposed to handle single argument forms and is now.
199
+ PyObject *result = PyObject_CallFunctionObjArgs(throw_method, exception_state->exception_value, NULL);
200
+
201
+ return result;
202
+ #endif
203
+ }
204
+
181
205
  static PyObject *_Nuitka_Generator_throw2(PyThreadState *tstate, struct Nuitka_GeneratorObject *generator,
182
- PyObject *exception_type, PyObject *exception_value,
183
- PyTracebackObject *exception_tb);
206
+ struct Nuitka_ExceptionPreservationItem *exception_state);
184
207
  #if PYTHON_VERSION >= 0x350
185
208
  static PyObject *_Nuitka_Coroutine_throw2(PyThreadState *tstate, struct Nuitka_CoroutineObject *coroutine, bool closing,
186
- PyObject *exception_type, PyObject *exception_value,
187
- PyTracebackObject *exception_tb);
209
+ struct Nuitka_ExceptionPreservationItem *exception_state);
188
210
  #endif
189
211
 
190
- static PyObject *_Nuitka_YieldFromPassExceptionTo(PyThreadState *tstate, PyObject *value, PyObject *exception_type,
191
- PyObject *exception_value, PyTracebackObject *exception_tb) {
212
+ static PyObject *_Nuitka_YieldFromPassExceptionTo(PyThreadState *tstate, PyObject *value,
213
+ struct Nuitka_ExceptionPreservationItem *exception_state) {
192
214
  // The yielding generator is being closed, but we also are tasked to
193
215
  // immediately close the currently running sub-generator.
194
- if (EXCEPTION_MATCH_BOOL_SINGLE(tstate, exception_type, PyExc_GeneratorExit)) {
216
+ if (EXCEPTION_STATE_MATCH_BOOL_SINGLE(tstate, exception_state, PyExc_GeneratorExit)) {
195
217
  PyObject *close_method = PyObject_GetAttr(value, const_str_plain_close);
196
218
 
197
219
  if (close_method) {
@@ -200,9 +222,7 @@ static PyObject *_Nuitka_YieldFromPassExceptionTo(PyThreadState *tstate, PyObjec
200
222
 
201
223
  if (unlikely(close_value == NULL)) {
202
224
  // Release exception, we are done with it, raising the one from close instead.
203
- Py_DECREF(exception_type);
204
- Py_XDECREF(exception_value);
205
- Py_XDECREF(exception_tb);
225
+ RELEASE_ERROR_OCCURRED_STATE(exception_state);
206
226
 
207
227
  return NULL;
208
228
  }
@@ -217,7 +237,7 @@ static PyObject *_Nuitka_YieldFromPassExceptionTo(PyThreadState *tstate, PyObjec
217
237
  }
218
238
 
219
239
  // Transfer exception ownership to published.
220
- RESTORE_ERROR_OCCURRED(tstate, exception_type, exception_value, exception_tb);
240
+ RESTORE_ERROR_OCCURRED_STATE(tstate, exception_state);
221
241
 
222
242
  return NULL;
223
243
  }
@@ -231,8 +251,7 @@ static PyObject *_Nuitka_YieldFromPassExceptionTo(PyThreadState *tstate, PyObjec
231
251
  PyGenObject *gen = (PyGenObject *)value;
232
252
 
233
253
  // Handing exception ownership over.
234
- PyObject *result =
235
- Nuitka_UncompiledGenerator_throw(tstate, gen, 1, exception_type, exception_value, exception_tb);
254
+ PyObject *result = Nuitka_UncompiledGenerator_throw(tstate, gen, 1, exception_state);
236
255
 
237
256
  return result;
238
257
  }
@@ -241,48 +260,43 @@ static PyObject *_Nuitka_YieldFromPassExceptionTo(PyThreadState *tstate, PyObjec
241
260
  if (Nuitka_Generator_Check(value)) {
242
261
  struct Nuitka_GeneratorObject *gen = ((struct Nuitka_GeneratorObject *)value);
243
262
 
244
- return _Nuitka_Generator_throw2(tstate, gen, exception_type, exception_value, exception_tb);
263
+ return _Nuitka_Generator_throw2(tstate, gen, exception_state);
245
264
  }
246
265
 
247
266
  #if PYTHON_VERSION >= 0x350
248
267
  if (Nuitka_Coroutine_Check(value)) {
249
268
  struct Nuitka_CoroutineObject *coro = ((struct Nuitka_CoroutineObject *)value);
250
269
  // Handing exception ownership over.
251
- return _Nuitka_Coroutine_throw2(tstate, coro, true, exception_type, exception_value, exception_tb);
270
+ return _Nuitka_Coroutine_throw2(tstate, coro, true, exception_state);
252
271
  }
253
272
 
254
273
  if (Nuitka_CoroutineWrapper_Check(value)) {
255
274
  struct Nuitka_CoroutineObject *coro = ((struct Nuitka_CoroutineWrapperObject *)value)->m_coroutine;
256
275
  // Handing exception ownership over.
257
- return _Nuitka_Coroutine_throw2(tstate, coro, true, exception_type, exception_value, exception_tb);
276
+ return _Nuitka_Coroutine_throw2(tstate, coro, true, exception_state);
258
277
  }
259
278
  #endif
260
279
 
261
280
  PyObject *throw_method = PyObject_GetAttr(value, const_str_plain_throw);
262
281
 
263
282
  if (throw_method) {
264
- PyObject *result =
265
- PyObject_CallFunctionObjArgs(throw_method, exception_type, exception_value, exception_tb, NULL);
283
+ PyObject *result = Nuitka_CallGeneratorThrowMethod(throw_method, exception_state);
266
284
  Py_DECREF(throw_method);
267
285
 
268
286
  // Releasing exception we own.
269
- Py_DECREF(exception_type);
270
- Py_XDECREF(exception_value);
271
- Py_XDECREF(exception_tb);
287
+ RELEASE_ERROR_OCCURRED_STATE(exception_state);
272
288
 
273
289
  return result;
274
290
  } else if (EXCEPTION_MATCH_BOOL_SINGLE(tstate, GET_ERROR_OCCURRED(tstate), PyExc_AttributeError)) {
275
291
  // Restoring the exception we own, to be released when handling it.
276
- RESTORE_ERROR_OCCURRED(tstate, exception_type, exception_value, exception_tb);
292
+ RESTORE_ERROR_OCCURRED_STATE(tstate, exception_state);
277
293
 
278
294
  return NULL;
279
295
  } else {
280
296
  assert(HAS_ERROR_OCCURRED(tstate));
281
297
 
282
298
  // Releasing exception we own.
283
- Py_DECREF(exception_type);
284
- Py_XDECREF(exception_value);
285
- Py_XDECREF(exception_tb);
299
+ RELEASE_ERROR_OCCURRED_STATE(exception_state);
286
300
 
287
301
  return NULL;
288
302
  }
@@ -307,14 +321,13 @@ static PyObject *_Nuitka_YieldFromGeneratorCore(PyThreadState *tstate, struct Nu
307
321
  PRINT_NEW_LINE();
308
322
  #endif
309
323
 
310
- PyObject *exception_type, *exception_value;
311
- PyTracebackObject *exception_tb;
312
- FETCH_ERROR_OCCURRED(tstate, &exception_type, &exception_value, &exception_tb);
324
+ struct Nuitka_ExceptionPreservationItem exception_state;
325
+ FETCH_ERROR_OCCURRED_STATE(tstate, &exception_state);
313
326
 
314
327
  // Exception, was thrown into us, need to send that to sub-generator.
315
- if (exception_type != NULL) {
328
+ if (HAS_EXCEPTION_STATE(&exception_state)) {
316
329
  // Passing ownership of exception fetch to it.
317
- retval = _Nuitka_YieldFromPassExceptionTo(tstate, yield_from, exception_type, exception_value, exception_tb);
330
+ retval = _Nuitka_YieldFromPassExceptionTo(tstate, yield_from, &exception_state);
318
331
 
319
332
  // TODO: This wants to look at retval most definitely, send_value is going to be NULL.
320
333
  if (unlikely(send_value == NULL)) {
@@ -449,29 +462,56 @@ static void _Nuitka_GeneratorPopFrame(PyThreadState *tstate, Nuitka_ThreadStateF
449
462
  PRINT_TOP_FRAME("Generator pop exit gives top frame:");
450
463
  }
451
464
 
465
+ #if PYTHON_VERSION >= 0x350
466
+ static void RAISE_RUNTIME_ERROR_RAISED_STOP_ITERATION(PyThreadState *tstate, char const *message) {
467
+
468
+ struct Nuitka_ExceptionPreservationItem saved_exception_state;
469
+ FETCH_ERROR_OCCURRED_STATE(tstate, &saved_exception_state);
470
+
471
+ #if PYTHON_VERSION < 0x3c0
472
+ NORMALIZE_EXCEPTION(tstate, &saved_exception_state.exception_type, &saved_exception_state.exception_value,
473
+ &saved_exception_state.exception_tb);
474
+ #endif
475
+
476
+ struct Nuitka_ExceptionPreservationItem new_exception_state;
477
+ SET_EXCEPTION_PRESERVATION_STATE_FROM_TYPE0_STR(tstate, &new_exception_state, PyExc_RuntimeError, message);
478
+
479
+ #if PYTHON_VERSION < 0x3c0
480
+ NORMALIZE_EXCEPTION(tstate, &new_exception_state.exception_type, &new_exception_state.exception_value,
481
+ &new_exception_state.exception_tb);
482
+ #endif
483
+
484
+ #if PYTHON_VERSION < 0x3c0
485
+ Py_INCREF(saved_exception_state.exception_value);
486
+ RAISE_EXCEPTION_WITH_CAUSE_STATE(tstate, &new_exception_state, saved_exception_state.exception_value);
487
+
488
+ Py_INCREF(saved_exception_state.exception_value);
489
+ PyException_SetContext(new_exception_state.exception_value, saved_exception_state.exception_value);
490
+ #endif
491
+
492
+ RELEASE_ERROR_OCCURRED_STATE_X(&saved_exception_state);
493
+ RESTORE_ERROR_OCCURRED_STATE(tstate, &new_exception_state);
494
+ }
495
+ #endif
496
+
452
497
  static PyObject *_Nuitka_Generator_send(PyThreadState *tstate, struct Nuitka_GeneratorObject *generator,
453
- PyObject *value, PyObject *exception_type, PyObject *exception_value,
454
- PyTracebackObject *exception_tb) {
498
+ PyObject *value, struct Nuitka_ExceptionPreservationItem *exception_state) {
455
499
  CHECK_OBJECT(generator);
456
500
  assert(Nuitka_Generator_Check((PyObject *)generator));
457
- CHECK_OBJECT_X(exception_type);
458
- CHECK_OBJECT_X(exception_value);
459
- CHECK_OBJECT_X(exception_tb);
501
+ CHECK_EXCEPTION_STATE_X(exception_state);
460
502
  CHECK_OBJECT_X(value);
461
503
  assert(PyThreadState_GET() == tstate);
462
504
 
463
505
  #if _DEBUG_GENERATOR
464
506
  PRINT_GENERATOR_STATUS("Enter", generator);
465
507
  PRINT_COROUTINE_VALUE("value", value);
466
- PRINT_EXCEPTION(exception_type, exception_value, exception_tb);
508
+ PRINT_EXCEPTION_STATE(exception_state);
467
509
  PRINT_CURRENT_EXCEPTION();
468
510
  PRINT_NEW_LINE();
469
511
  #endif
470
512
 
471
513
  if (value != NULL) {
472
- assert(exception_type == NULL);
473
- assert(exception_value == NULL);
474
- assert(exception_tb == NULL);
514
+ ASSERT_EMPTY_EXCEPTION_STATE(exception_state);
475
515
  }
476
516
 
477
517
  if (generator->m_status != status_Finished) {
@@ -513,11 +553,11 @@ static PyObject *_Nuitka_Generator_send(PyThreadState *tstate, struct Nuitka_Gen
513
553
  Nuitka_MarkGeneratorAsRunning(generator);
514
554
 
515
555
  // Check for thrown exception, publish it to the generator code.
516
- if (unlikely(exception_type)) {
556
+ if (unlikely(HAS_EXCEPTION_STATE(exception_state))) {
517
557
  assert(value == NULL);
518
558
 
519
559
  // Transfer exception ownership to published.
520
- RESTORE_ERROR_OCCURRED(tstate, exception_type, exception_value, exception_tb);
560
+ RESTORE_ERROR_OCCURRED_STATE(tstate, exception_state);
521
561
  }
522
562
 
523
563
  #if _DEBUG_GENERATOR
@@ -604,30 +644,7 @@ static PyObject *_Nuitka_Generator_send(PyThreadState *tstate, struct Nuitka_Gen
604
644
  generator->m_code_object->co_flags & CO_FUTURE_GENERATOR_STOP &&
605
645
  #endif
606
646
  GET_ERROR_OCCURRED(tstate) == PyExc_StopIteration) {
607
- PyObject *saved_exception_type, *saved_exception_value;
608
- PyTracebackObject *saved_exception_tb;
609
-
610
- // TODO: For Python3.12, this kind of code ought to use tstate methods entirely.
611
- FETCH_ERROR_OCCURRED(tstate, &saved_exception_type, &saved_exception_value, &saved_exception_tb);
612
- NORMALIZE_EXCEPTION(tstate, &saved_exception_type, &saved_exception_value, &saved_exception_tb);
613
-
614
- SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_RuntimeError, "generator raised StopIteration");
615
-
616
- FETCH_ERROR_OCCURRED(tstate, &exception_type, &exception_value, &exception_tb);
617
-
618
- RAISE_EXCEPTION_WITH_CAUSE(tstate, &exception_type, &exception_value, &exception_tb,
619
- saved_exception_value);
620
-
621
- CHECK_OBJECT(exception_value);
622
- CHECK_OBJECT(saved_exception_value);
623
-
624
- Py_INCREF(saved_exception_value);
625
- PyException_SetContext(exception_value, saved_exception_value);
626
-
627
- Py_DECREF(saved_exception_type);
628
- Py_XDECREF(saved_exception_tb);
629
-
630
- RESTORE_ERROR_OCCURRED(tstate, exception_type, exception_value, exception_tb);
647
+ RAISE_RUNTIME_ERROR_RAISED_STOP_ITERATION(tstate, "generator raised StopIteration");
631
648
 
632
649
  return NULL;
633
650
  }
@@ -732,7 +749,11 @@ static PyObject *Nuitka_Generator_send(struct Nuitka_GeneratorObject *generator,
732
749
 
733
750
  // We need to transfer ownership of the sent value.
734
751
  Py_INCREF(value);
735
- PyObject *result = _Nuitka_Generator_send(tstate, generator, value, NULL, NULL, NULL);
752
+
753
+ struct Nuitka_ExceptionPreservationItem exception_state;
754
+ INIT_ERROR_OCCURRED_STATE(&exception_state);
755
+
756
+ PyObject *result = _Nuitka_Generator_send(tstate, generator, value, &exception_state);
736
757
 
737
758
  if (result == NULL) {
738
759
  if (HAS_ERROR_OCCURRED(tstate) == false) {
@@ -747,14 +768,22 @@ static PyObject *Nuitka_Generator_tp_iternext(struct Nuitka_GeneratorObject *gen
747
768
  PyThreadState *tstate = PyThreadState_GET();
748
769
 
749
770
  Py_INCREF(Py_None);
750
- return _Nuitka_Generator_send(tstate, generator, Py_None, NULL, NULL, NULL);
771
+
772
+ struct Nuitka_ExceptionPreservationItem exception_state;
773
+ INIT_ERROR_OCCURRED_STATE(&exception_state);
774
+
775
+ return _Nuitka_Generator_send(tstate, generator, Py_None, &exception_state);
751
776
  }
752
777
 
753
778
  /* Our own qiter interface, which is for quicker simple loop style iteration,
754
779
  that does not send anything in. */
755
780
  PyObject *Nuitka_Generator_qiter(PyThreadState *tstate, struct Nuitka_GeneratorObject *generator, bool *finished) {
756
781
  Py_INCREF(Py_None);
757
- PyObject *result = _Nuitka_Generator_send(tstate, generator, Py_None, NULL, NULL, NULL);
782
+
783
+ struct Nuitka_ExceptionPreservationItem exception_state;
784
+ INIT_ERROR_OCCURRED_STATE(&exception_state);
785
+
786
+ PyObject *result = _Nuitka_Generator_send(tstate, generator, Py_None, &exception_state);
758
787
 
759
788
  if (result == NULL) {
760
789
  if (unlikely(!CHECK_AND_CLEAR_STOP_ITERATION_OCCURRED(tstate))) {
@@ -790,9 +819,10 @@ static bool _Nuitka_Generator_close(PyThreadState *tstate, struct Nuitka_Generat
790
819
  CHECK_OBJECT(generator);
791
820
 
792
821
  if (generator->m_status == status_Running) {
793
- Py_INCREF(PyExc_GeneratorExit);
822
+ struct Nuitka_ExceptionPreservationItem exception_state;
823
+ SET_EXCEPTION_PRESERVATION_STATE_FROM_ARGS(tstate, &exception_state, PyExc_GeneratorExit, NULL, NULL);
794
824
 
795
- PyObject *result = _Nuitka_Generator_send(tstate, generator, NULL, PyExc_GeneratorExit, NULL, NULL);
825
+ PyObject *result = _Nuitka_Generator_send(tstate, generator, NULL, &exception_state);
796
826
 
797
827
  if (unlikely(result)) {
798
828
  Py_DECREF(result);
@@ -828,15 +858,10 @@ static PyObject *Nuitka_Generator_close(struct Nuitka_GeneratorObject *generator
828
858
  }
829
859
  }
830
860
 
831
- // Shared code for checking a thrown exception, coroutines, asyncgen, uncompiled ones do this too.
832
- static bool _Nuitka_Generator_check_throw2(PyThreadState *tstate, PyObject **exception_type, PyObject **exception_value,
833
- PyTracebackObject **exception_tb) {
834
- CHECK_OBJECT(*exception_type);
835
- CHECK_OBJECT_X(*exception_value);
836
- CHECK_OBJECT_X(*exception_tb);
837
-
861
+ #if PYTHON_VERSION >= 0x3c0
862
+ static bool _Nuitka_Generator_check_throw_args(PyThreadState *tstate, PyObject **exception_type,
863
+ PyObject **exception_value, PyTracebackObject **exception_tb) {
838
864
  if (*exception_tb == (PyTracebackObject *)Py_None) {
839
- Py_DECREF(*exception_tb);
840
865
  *exception_tb = NULL;
841
866
  } else if (*exception_tb != NULL && !PyTraceBack_Check(*exception_tb)) {
842
867
  SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError, "throw() third argument must be a traceback object");
@@ -844,7 +869,6 @@ static bool _Nuitka_Generator_check_throw2(PyThreadState *tstate, PyObject **exc
844
869
  }
845
870
 
846
871
  if (PyExceptionClass_Check(*exception_type)) {
847
- // TODO: Must not / need not normalize here?
848
872
  NORMALIZE_EXCEPTION(tstate, exception_type, exception_value, exception_tb);
849
873
  } else if (PyExceptionInstance_Check(*exception_type)) {
850
874
  if (*exception_value != NULL && *exception_value != Py_None) {
@@ -854,10 +878,8 @@ static bool _Nuitka_Generator_check_throw2(PyThreadState *tstate, PyObject **exc
854
878
  }
855
879
 
856
880
  // Release old None value and replace it with the object, then set the exception type
857
- // from the class.
858
- Py_XDECREF(*exception_value);
881
+ // from the class. The "None" is known immortal here and needs no refcount correction.
859
882
  *exception_value = *exception_type;
860
-
861
883
  *exception_type = PyExceptionInstance_Class(*exception_type);
862
884
  Py_INCREF(*exception_type);
863
885
  } else {
@@ -875,10 +897,95 @@ static bool _Nuitka_Generator_check_throw2(PyThreadState *tstate, PyObject **exc
875
897
  return true;
876
898
 
877
899
  failed_throw:
900
+
901
+ return false;
902
+ }
903
+ #endif
904
+
905
+ static bool _Nuitka_Generator_make_throw_exception_state(PyThreadState *tstate,
906
+ struct Nuitka_ExceptionPreservationItem *exception_state,
907
+ PyObject *exception_type, PyObject *exception_value,
908
+ PyTracebackObject *exception_tb) {
909
+
910
+ #if PYTHON_VERSION >= 0x3c0
911
+ Py_INCREF(exception_type);
912
+ Py_XINCREF(exception_value);
913
+ Py_XINCREF(exception_tb);
914
+
915
+ if (_Nuitka_Generator_check_throw_args(tstate, &exception_type, &exception_value, &exception_tb) == false) {
916
+ Py_DECREF(exception_type);
917
+ Py_XDECREF(exception_value);
918
+ Py_XDECREF(exception_tb);
919
+
920
+ return false;
921
+ }
922
+ #endif
923
+
924
+ SET_EXCEPTION_PRESERVATION_STATE_FROM_ARGS(tstate, exception_state, exception_type, exception_value, exception_tb);
925
+
926
+ #if PYTHON_VERSION >= 0x3c0
927
+ Py_DECREF(exception_type);
928
+ Py_XDECREF(exception_value);
929
+ Py_XDECREF(exception_tb);
930
+ #endif
931
+
932
+ return true;
933
+ }
934
+
935
+ // Shared code for checking a thrown exception, coroutines, asyncgen, uncompiled
936
+ // ones do this too. For pre-3.12, the checking needs to be done late, for 3.12
937
+ // early, so it's a separate function.
938
+ static bool _Nuitka_Generator_check_throw(PyThreadState *tstate,
939
+ struct Nuitka_ExceptionPreservationItem *exception_state) {
940
+ CHECK_EXCEPTION_STATE(exception_state);
941
+
942
+ #if PYTHON_VERSION < 0x3c0
943
+ if (exception_state->exception_tb == (PyTracebackObject *)Py_None) {
944
+ Py_DECREF(exception_state->exception_tb);
945
+ exception_state->exception_tb = NULL;
946
+ } else if (exception_state->exception_tb != NULL && !PyTraceBack_Check(exception_state->exception_tb)) {
947
+ SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError, "throw() third argument must be a traceback object");
948
+ goto failed_throw;
949
+ }
950
+
951
+ if (PyExceptionClass_Check(exception_state->exception_type)) {
952
+ // TODO: Must not / need not normalize here?
953
+ NORMALIZE_EXCEPTION(tstate, &exception_state->exception_type, &exception_state->exception_value,
954
+ &exception_state->exception_tb);
955
+ } else if (PyExceptionInstance_Check(exception_state->exception_type)) {
956
+ if (exception_state->exception_value != NULL && exception_state->exception_value != Py_None) {
957
+ SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError,
958
+ "instance exception may not have a separate value");
959
+ goto failed_throw;
960
+ }
961
+
962
+ // Release old None value and replace it with the object, then set the exception type
963
+ // from the class.
964
+ Py_XDECREF(exception_state->exception_value);
965
+ exception_state->exception_value = exception_state->exception_type;
966
+
967
+ exception_state->exception_type = PyExceptionInstance_Class(exception_state->exception_type);
968
+ Py_INCREF(exception_state->exception_type);
969
+ } else {
970
+ #if PYTHON_VERSION < 0x300
971
+ PyErr_Format(PyExc_TypeError, "exceptions must be classes, or instances, not %s",
972
+ Py_TYPE(exception_state->exception_type)->tp_name);
973
+ #else
974
+ PyErr_Format(PyExc_TypeError, "exceptions must be classes or instances deriving from BaseException, not %s",
975
+ Py_TYPE(exception_state->exception_type)->tp_name);
976
+ #endif
977
+
978
+ goto failed_throw;
979
+ }
980
+
981
+ #endif
982
+ return true;
983
+
984
+ #if PYTHON_VERSION < 0x3c0
985
+ failed_throw:
986
+ #endif
878
987
  // Release exception, we are done with it now.
879
- Py_DECREF(*exception_type);
880
- Py_XDECREF(*exception_value);
881
- Py_XDECREF(*exception_tb);
988
+ RELEASE_ERROR_OCCURRED_STATE(exception_state);
882
989
 
883
990
  return false;
884
991
  }
@@ -972,29 +1079,25 @@ static bool Nuitka_gen_close_iter(PyThreadState *tstate, PyObject *yield_from) {
972
1079
  static bool Nuitka_AsyncgenAsend_Check(PyObject *object);
973
1080
  struct Nuitka_AsyncgenAsendObject;
974
1081
  static PyObject *_Nuitka_AsyncgenAsend_throw2(PyThreadState *tstate, struct Nuitka_AsyncgenAsendObject *asyncgen_asend,
975
- PyObject *exception_type, PyObject *exception_value,
976
- PyTracebackObject *exception_tb);
1082
+ struct Nuitka_ExceptionPreservationItem *exception_state);
977
1083
  #endif
978
1084
 
979
1085
  static PyObject *_Nuitka_Generator_throw2(PyThreadState *tstate, struct Nuitka_GeneratorObject *generator,
980
- PyObject *exception_type, PyObject *exception_value,
981
- PyTracebackObject *exception_tb) {
1086
+ struct Nuitka_ExceptionPreservationItem *exception_state) {
982
1087
  #if _DEBUG_GENERATOR
983
1088
  PRINT_GENERATOR_STATUS("Enter", generator);
984
1089
  PRINT_COROUTINE_VALUE("yield_from", generator->m_yield_from);
985
- PRINT_EXCEPTION(exception_type, exception_value, exception_tb);
1090
+ PRINT_EXCEPTION_STATE(exception_state);
986
1091
  PRINT_NEW_LINE();
987
1092
  #endif
988
1093
 
989
1094
  CHECK_OBJECT(generator);
990
1095
  assert(Nuitka_Generator_Check((PyObject *)generator));
991
- CHECK_OBJECT(exception_type);
992
- CHECK_OBJECT_X(exception_value);
993
- CHECK_OBJECT_X(exception_tb);
1096
+ CHECK_EXCEPTION_STATE(exception_state);
994
1097
 
995
1098
  #if PYTHON_VERSION >= 0x300
996
1099
  if (generator->m_yield_from != NULL) {
997
- if (EXCEPTION_MATCH_BOOL_SINGLE(tstate, exception_type, PyExc_GeneratorExit)) {
1100
+ if (EXCEPTION_STATE_MATCH_BOOL_SINGLE(tstate, exception_state, PyExc_GeneratorExit)) {
998
1101
  // Generators need to close the yield_from.
999
1102
  Nuitka_MarkGeneratorAsRunning(generator);
1000
1103
  bool res = Nuitka_gen_close_iter(tstate, generator->m_yield_from);
@@ -1002,15 +1105,13 @@ static PyObject *_Nuitka_Generator_throw2(PyThreadState *tstate, struct Nuitka_G
1002
1105
 
1003
1106
  if (res == false) {
1004
1107
  // Release exception, we are done with it now and pick up the new one.
1005
- Py_DECREF(exception_type);
1006
- Py_XDECREF(exception_value);
1007
- Py_XDECREF(exception_tb);
1108
+ RELEASE_ERROR_OCCURRED_STATE(exception_state);
1008
1109
 
1009
- FETCH_ERROR_OCCURRED(tstate, &exception_type, &exception_value, &exception_tb);
1110
+ FETCH_ERROR_OCCURRED_STATE(tstate, exception_state);
1010
1111
  }
1011
1112
 
1012
1113
  // Transferred exception ownership to "_Nuitka_Generator_send".
1013
- return _Nuitka_Generator_send(tstate, generator, NULL, exception_type, exception_value, exception_tb);
1114
+ return _Nuitka_Generator_send(tstate, generator, NULL, exception_state);
1014
1115
  }
1015
1116
 
1016
1117
  PyObject *ret;
@@ -1025,7 +1126,7 @@ static PyObject *_Nuitka_Generator_throw2(PyThreadState *tstate, struct Nuitka_G
1025
1126
  struct Nuitka_GeneratorObject *gen = ((struct Nuitka_GeneratorObject *)generator->m_yield_from);
1026
1127
  // Transferred exception ownership to "_Nuitka_Generator_throw2".
1027
1128
  Nuitka_MarkGeneratorAsRunning(generator);
1028
- ret = _Nuitka_Generator_throw2(tstate, gen, exception_type, exception_value, exception_tb);
1129
+ ret = _Nuitka_Generator_throw2(tstate, gen, exception_state);
1029
1130
  Nuitka_MarkGeneratorAsNotRunning(generator);
1030
1131
  #if NUITKA_UNCOMPILED_THROW_INTEGRATION
1031
1132
  } else if (PyGen_CheckExact(generator->m_yield_from)) {
@@ -1033,7 +1134,7 @@ static PyObject *_Nuitka_Generator_throw2(PyThreadState *tstate, struct Nuitka_G
1033
1134
 
1034
1135
  // Transferred exception ownership to "Nuitka_UncompiledGenerator_throw".
1035
1136
  Nuitka_MarkGeneratorAsRunning(generator);
1036
- ret = Nuitka_UncompiledGenerator_throw(tstate, gen, 1, exception_type, exception_value, exception_tb);
1137
+ ret = Nuitka_UncompiledGenerator_throw(tstate, gen, 1, exception_state);
1037
1138
  Nuitka_MarkGeneratorAsNotRunning(generator);
1038
1139
  #endif
1039
1140
  #if PYTHON_VERSION >= 0x350
@@ -1041,7 +1142,7 @@ static PyObject *_Nuitka_Generator_throw2(PyThreadState *tstate, struct Nuitka_G
1041
1142
  struct Nuitka_CoroutineObject *coro = ((struct Nuitka_CoroutineObject *)generator->m_yield_from);
1042
1143
  // Transferred exception ownership to "_Nuitka_Coroutine_throw2".
1043
1144
  Nuitka_MarkGeneratorAsRunning(generator);
1044
- ret = _Nuitka_Coroutine_throw2(tstate, coro, true, exception_type, exception_value, exception_tb);
1145
+ ret = _Nuitka_Coroutine_throw2(tstate, coro, true, exception_state);
1045
1146
  Nuitka_MarkGeneratorAsNotRunning(generator);
1046
1147
  } else if (Nuitka_CoroutineWrapper_Check(generator->m_yield_from)) {
1047
1148
  struct Nuitka_CoroutineObject *coro =
@@ -1049,7 +1150,7 @@ static PyObject *_Nuitka_Generator_throw2(PyThreadState *tstate, struct Nuitka_G
1049
1150
 
1050
1151
  // Transferred exception ownership to "_Nuitka_Coroutine_throw2".
1051
1152
  Nuitka_MarkGeneratorAsRunning(generator);
1052
- ret = _Nuitka_Coroutine_throw2(tstate, coro, true, exception_type, exception_value, exception_tb);
1153
+ ret = _Nuitka_Coroutine_throw2(tstate, coro, true, exception_state);
1053
1154
  Nuitka_MarkGeneratorAsNotRunning(generator);
1054
1155
  #if NUITKA_UNCOMPILED_THROW_INTEGRATION
1055
1156
  } else if (PyCoro_CheckExact(generator->m_yield_from)) {
@@ -1057,7 +1158,7 @@ static PyObject *_Nuitka_Generator_throw2(PyThreadState *tstate, struct Nuitka_G
1057
1158
 
1058
1159
  // Transferred exception ownership to "Nuitka_UncompiledGenerator_throw".
1059
1160
  Nuitka_MarkGeneratorAsRunning(generator);
1060
- ret = Nuitka_UncompiledGenerator_throw(tstate, gen, 1, exception_type, exception_value, exception_tb);
1161
+ ret = Nuitka_UncompiledGenerator_throw(tstate, gen, 1, exception_state);
1061
1162
  Nuitka_MarkGeneratorAsNotRunning(generator);
1062
1163
  #endif
1063
1164
  #if PYTHON_VERSION >= 0x360
@@ -1067,7 +1168,7 @@ static PyObject *_Nuitka_Generator_throw2(PyThreadState *tstate, struct Nuitka_G
1067
1168
 
1068
1169
  // Transferred exception ownership to "_Nuitka_AsyncgenAsend_throw2".
1069
1170
  Nuitka_MarkGeneratorAsRunning(generator);
1070
- ret = _Nuitka_AsyncgenAsend_throw2(tstate, asyncgen_asend, exception_type, exception_value, exception_tb);
1171
+ ret = _Nuitka_AsyncgenAsend_throw2(tstate, asyncgen_asend, exception_state);
1071
1172
  Nuitka_MarkGeneratorAsNotRunning(generator);
1072
1173
  #endif
1073
1174
  #endif
@@ -1076,9 +1177,7 @@ static PyObject *_Nuitka_Generator_throw2(PyThreadState *tstate, struct Nuitka_G
1076
1177
  if (unlikely(meth == NULL)) {
1077
1178
  if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
1078
1179
  // Release exception, we are done with it now.
1079
- Py_DECREF(exception_type);
1080
- Py_XDECREF(exception_value);
1081
- Py_XDECREF(exception_tb);
1180
+ RELEASE_ERROR_OCCURRED_STATE(exception_state);
1082
1181
 
1083
1182
  return NULL;
1084
1183
  }
@@ -1089,7 +1188,7 @@ static PyObject *_Nuitka_Generator_throw2(PyThreadState *tstate, struct Nuitka_G
1089
1188
  goto throw_here;
1090
1189
  }
1091
1190
 
1092
- CHECK_OBJECT(exception_type);
1191
+ CHECK_EXCEPTION_STATE(exception_state);
1093
1192
 
1094
1193
  #if 0
1095
1194
  // TODO: Add slow mode traces.
@@ -1097,15 +1196,13 @@ static PyObject *_Nuitka_Generator_throw2(PyThreadState *tstate, struct Nuitka_G
1097
1196
  PRINT_NEW_LINE();
1098
1197
  #endif
1099
1198
  Nuitka_MarkGeneratorAsRunning(generator);
1100
- ret = PyObject_CallFunctionObjArgs(meth, exception_type, exception_value, exception_tb, NULL);
1199
+ ret = Nuitka_CallGeneratorThrowMethod(meth, exception_state);
1101
1200
  Nuitka_MarkGeneratorAsNotRunning(generator);
1102
1201
 
1103
1202
  Py_DECREF(meth);
1104
1203
 
1105
1204
  // Release exception, we are done with it now.
1106
- Py_DECREF(exception_type);
1107
- Py_XDECREF(exception_value);
1108
- Py_XDECREF(exception_tb);
1205
+ RELEASE_ERROR_OCCURRED_STATE(exception_state);
1109
1206
  }
1110
1207
 
1111
1208
  if (unlikely(ret == NULL)) {
@@ -1130,14 +1227,21 @@ static PyObject *_Nuitka_Generator_throw2(PyThreadState *tstate, struct Nuitka_G
1130
1227
  PRINT_NEW_LINE();
1131
1228
  #endif
1132
1229
 
1133
- ret = _Nuitka_Generator_send(tstate, generator, val, NULL, NULL, NULL);
1230
+ struct Nuitka_ExceptionPreservationItem no_exception_state;
1231
+ INIT_ERROR_OCCURRED_STATE(&no_exception_state);
1232
+
1233
+ ret = _Nuitka_Generator_send(tstate, generator, val, &no_exception_state);
1134
1234
  } else {
1135
1235
  #if _DEBUG_GENERATOR
1136
1236
  PRINT_GENERATOR_STATUS("Sending exception value into ourselves", generator);
1137
1237
  PRINT_CURRENT_EXCEPTION();
1138
1238
  PRINT_NEW_LINE();
1139
1239
  #endif
1140
- ret = _Nuitka_Generator_send(tstate, generator, NULL, NULL, NULL, NULL);
1240
+
1241
+ struct Nuitka_ExceptionPreservationItem no_exception_state;
1242
+ INIT_ERROR_OCCURRED_STATE(&no_exception_state);
1243
+
1244
+ ret = _Nuitka_Generator_send(tstate, generator, NULL, &no_exception_state);
1141
1245
  }
1142
1246
 
1143
1247
  #if _DEBUG_GENERATOR
@@ -1163,15 +1267,14 @@ throw_here:
1163
1267
 
1164
1268
  // We continue to have exception ownership here.
1165
1269
 
1166
- if (unlikely(_Nuitka_Generator_check_throw2(tstate, &exception_type, &exception_value, &exception_tb) == false)) {
1167
- // Exception was released by _Nuitka_Generator_check_throw2 already.
1270
+ if (unlikely(_Nuitka_Generator_check_throw(tstate, exception_state) == false)) {
1271
+ // Exception was released by _Nuitka_Generator_check_throw already.
1168
1272
  return NULL;
1169
1273
  }
1170
1274
 
1171
1275
  if (generator->m_status == status_Running) {
1172
1276
  // Passing exception ownership to _Nuitka_Generator_send
1173
- PyObject *result =
1174
- _Nuitka_Generator_send(tstate, generator, NULL, exception_type, exception_value, exception_tb);
1277
+ PyObject *result = _Nuitka_Generator_send(tstate, generator, NULL, exception_state);
1175
1278
 
1176
1279
  if (result == NULL) {
1177
1280
  if (GET_ERROR_OCCURRED(tstate) == NULL) {
@@ -1181,21 +1284,24 @@ throw_here:
1181
1284
 
1182
1285
  return result;
1183
1286
  } else if (generator->m_status == status_Finished) {
1184
- RESTORE_ERROR_OCCURRED(tstate, exception_type, exception_value, exception_tb);
1287
+ RESTORE_ERROR_OCCURRED_STATE(tstate, exception_state);
1185
1288
 
1186
1289
  return NULL;
1187
1290
  } else {
1291
+ PyTracebackObject *exception_tb = GET_EXCEPTION_STATE_TRACEBACK(exception_state);
1292
+
1188
1293
  if (exception_tb == NULL) {
1189
1294
  // TODO: Our compiled objects really need a way to store common
1190
1295
  // stuff in a "shared" part across all instances, and outside of
1191
1296
  // run time, so we could reuse this.
1192
1297
  struct Nuitka_FrameObject *frame =
1193
1298
  MAKE_FUNCTION_FRAME(tstate, generator->m_code_object, generator->m_module, 0);
1194
- exception_tb = MAKE_TRACEBACK(frame, generator->m_code_object->co_firstlineno);
1299
+ SET_EXCEPTION_STATE_TRACEBACK(exception_state,
1300
+ MAKE_TRACEBACK(frame, generator->m_code_object->co_firstlineno));
1195
1301
  Py_DECREF(frame);
1196
1302
  }
1197
1303
 
1198
- RESTORE_ERROR_OCCURRED(tstate, exception_type, exception_value, exception_tb);
1304
+ RESTORE_ERROR_OCCURRED_STATE(tstate, exception_state);
1199
1305
 
1200
1306
  Nuitka_MarkGeneratorAsFinished(generator);
1201
1307
 
@@ -1215,14 +1321,16 @@ static PyObject *Nuitka_Generator_throw(struct Nuitka_GeneratorObject *generator
1215
1321
  return NULL;
1216
1322
  }
1217
1323
 
1218
- // Handing ownership of exception over, we need not release it ourselves
1219
- Py_INCREF(exception_type);
1220
- Py_XINCREF(exception_value);
1221
- Py_XINCREF(exception_tb);
1222
-
1223
1324
  PyThreadState *tstate = PyThreadState_GET();
1224
1325
 
1225
- PyObject *result = _Nuitka_Generator_throw2(tstate, generator, exception_type, exception_value, exception_tb);
1326
+ // Handing ownership of exception over, we need not release it ourselves
1327
+ struct Nuitka_ExceptionPreservationItem exception_state;
1328
+ if (_Nuitka_Generator_make_throw_exception_state(tstate, &exception_state, exception_type, exception_value,
1329
+ exception_tb) == false) {
1330
+ return NULL;
1331
+ }
1332
+
1333
+ PyObject *result = _Nuitka_Generator_throw2(tstate, generator, &exception_state);
1226
1334
 
1227
1335
  if (result == NULL) {
1228
1336
  if (HAS_ERROR_OCCURRED(tstate) == false) {
@@ -1248,9 +1356,8 @@ static void Nuitka_Generator_tp_finalizer(struct Nuitka_GeneratorObject *generat
1248
1356
 
1249
1357
  PyThreadState *tstate = PyThreadState_GET();
1250
1358
 
1251
- PyObject *save_exception_type, *save_exception_value;
1252
- PyTracebackObject *save_exception_tb;
1253
- FETCH_ERROR_OCCURRED(tstate, &save_exception_type, &save_exception_value, &save_exception_tb);
1359
+ struct Nuitka_ExceptionPreservationItem saved_exception_state;
1360
+ FETCH_ERROR_OCCURRED_STATE(tstate, &saved_exception_state);
1254
1361
 
1255
1362
  bool close_result = _Nuitka_Generator_close(tstate, generator);
1256
1363
 
@@ -1258,8 +1365,8 @@ static void Nuitka_Generator_tp_finalizer(struct Nuitka_GeneratorObject *generat
1258
1365
  PyErr_WriteUnraisable((PyObject *)generator);
1259
1366
  }
1260
1367
 
1261
- /* Restore the saved exception if any. */
1262
- RESTORE_ERROR_OCCURRED(tstate, save_exception_type, save_exception_value, save_exception_tb);
1368
+ // Restore the saved exception if any.
1369
+ RESTORE_ERROR_OCCURRED_STATE(tstate, &saved_exception_state);
1263
1370
  }
1264
1371
  #endif
1265
1372
 
@@ -1280,9 +1387,8 @@ static void Nuitka_Generator_tp_dealloc(struct Nuitka_GeneratorObject *generator
1280
1387
  PyThreadState *tstate = PyThreadState_GET();
1281
1388
 
1282
1389
  // Save the current exception, if any, we must preserve it.
1283
- PyObject *save_exception_type, *save_exception_value;
1284
- PyTracebackObject *save_exception_tb;
1285
- FETCH_ERROR_OCCURRED(tstate, &save_exception_type, &save_exception_value, &save_exception_tb);
1390
+ struct Nuitka_ExceptionPreservationItem saved_exception_state;
1391
+ FETCH_ERROR_OCCURRED_STATE(tstate, &saved_exception_state);
1286
1392
 
1287
1393
  if (generator->m_status == status_Running) {
1288
1394
  bool close_result = _Nuitka_Generator_close(tstate, generator);
@@ -1326,7 +1432,7 @@ static void Nuitka_Generator_tp_dealloc(struct Nuitka_GeneratorObject *generator
1326
1432
  /* Put the object into free list or release to GC */
1327
1433
  releaseToFreeList(free_list_generators, generator, MAX_GENERATOR_FREE_LIST_COUNT);
1328
1434
 
1329
- RESTORE_ERROR_OCCURRED(tstate, save_exception_type, save_exception_value, save_exception_tb);
1435
+ RESTORE_ERROR_OCCURRED_STATE(tstate, &saved_exception_state);
1330
1436
  }
1331
1437
 
1332
1438
  static long Nuitka_Generator_tp_hash(struct Nuitka_GeneratorObject *generator) { return generator->m_counter; }