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
@@ -49,7 +49,7 @@ from nuitka.nodes.StatementNodes import (
49
49
  from nuitka.nodes.VariableAssignNodes import makeStatementAssignmentVariable
50
50
  from nuitka.nodes.VariableRefNodes import ExpressionTempVariableRef
51
51
  from nuitka.nodes.VariableReleaseNodes import makeStatementReleaseVariable
52
- from nuitka.nodes.YieldNodes import ExpressionYieldFromWaitable
52
+ from nuitka.nodes.YieldNodes import ExpressionYieldFromAwaitable
53
53
  from nuitka.PythonVersions import python_version
54
54
 
55
55
  from .ReformulationAssignmentStatements import buildAssignmentStatements
@@ -75,13 +75,13 @@ def _buildWithNode(provider, context_expr, assign_target, body, sync, source_ref
75
75
  temp_scope = provider.allocateTempScope("with")
76
76
 
77
77
  tmp_source_variable = provider.allocateTempVariable(
78
- temp_scope=temp_scope, name="source"
78
+ temp_scope=temp_scope, name="source", temp_type="object"
79
79
  )
80
80
  tmp_exit_variable = provider.allocateTempVariable(
81
- temp_scope=temp_scope, name="exit"
81
+ temp_scope=temp_scope, name="exit", temp_type="object"
82
82
  )
83
83
  tmp_enter_variable = provider.allocateTempVariable(
84
- temp_scope=temp_scope, name="enter"
84
+ temp_scope=temp_scope, name="enter", temp_type="object"
85
85
  )
86
86
 
87
87
  # Indicator variable, will end up with C bool type, and need not be released.
@@ -164,13 +164,13 @@ def _buildWithNode(provider, context_expr, assign_target, body, sync, source_ref
164
164
 
165
165
  # For "async with", await the entered value and exit value must be awaited.
166
166
  if not sync:
167
- exit_value_exception = ExpressionYieldFromWaitable(
167
+ exit_value_exception = ExpressionYieldFromAwaitable(
168
168
  expression=ExpressionAsyncWaitExit(
169
169
  expression=exit_value_exception, source_ref=source_ref
170
170
  ),
171
171
  source_ref=source_ref,
172
172
  )
173
- exit_value_no_exception = ExpressionYieldFromWaitable(
173
+ exit_value_no_exception = ExpressionYieldFromAwaitable(
174
174
  ExpressionAsyncWaitExit(
175
175
  expression=exit_value_no_exception, source_ref=source_ref
176
176
  ),
@@ -186,7 +186,7 @@ def _buildWithNode(provider, context_expr, assign_target, body, sync, source_ref
186
186
 
187
187
  # Before 3.9, __aenter__ is immediately awaited, after we first do __aexit__ lookup.
188
188
  if not sync and python_version < 0x390:
189
- enter_value = ExpressionYieldFromWaitable(
189
+ enter_value = ExpressionYieldFromAwaitable(
190
190
  expression=ExpressionAsyncWaitEnter(
191
191
  expression=enter_value, source_ref=source_ref
192
192
  ),
@@ -217,7 +217,7 @@ def _buildWithNode(provider, context_expr, assign_target, body, sync, source_ref
217
217
  if python_version >= 0x390 and not sync:
218
218
  enter_await_statement = makeStatementAssignmentVariable(
219
219
  variable=tmp_enter_variable,
220
- source=ExpressionYieldFromWaitable(
220
+ source=ExpressionYieldFromAwaitable(
221
221
  expression=ExpressionAsyncWaitEnter(
222
222
  expression=ExpressionTempVariableRef(
223
223
  variable=tmp_enter_variable, source_ref=source_ref
@@ -29,7 +29,7 @@ from nuitka.nodes.CoroutineNodes import ExpressionAsyncWait
29
29
  from nuitka.nodes.YieldNodes import (
30
30
  ExpressionYield,
31
31
  ExpressionYieldFrom,
32
- ExpressionYieldFromWaitable,
32
+ ExpressionYieldFromAwaitable,
33
33
  )
34
34
  from nuitka.PythonVersions import python_version
35
35
 
@@ -104,7 +104,7 @@ def buildYieldFromNode(provider, node, source_ref):
104
104
  def buildAwaitNode(provider, node, source_ref):
105
105
  _checkInsideGenerator("await", provider, node, source_ref)
106
106
 
107
- return ExpressionYieldFromWaitable(
107
+ return ExpressionYieldFromAwaitable(
108
108
  expression=ExpressionAsyncWait(
109
109
  expression=buildNode(provider, node.value, source_ref),
110
110
  source_ref=source_ref,
@@ -174,7 +174,20 @@ def getSourceCodeDiff(source_code, source_code_modified):
174
174
  return list(diff)
175
175
 
176
176
 
177
- def readSourceCodeFromFilenameWithInformation(module_name, source_filename):
177
+ _source_code_cache = {}
178
+
179
+
180
+ def readSourceCodeFromFilenameWithInformation(
181
+ module_name, source_filename, pre_load=False
182
+ ):
183
+ key = (module_name, source_filename)
184
+
185
+ if key in _source_code_cache:
186
+ if pre_load:
187
+ return _source_code_cache[key]
188
+ else:
189
+ return _source_code_cache.pop(key)
190
+
178
191
  if python_version < 0x300:
179
192
  source_code = _readSourceCodeFromFilename2(source_filename)
180
193
  else:
@@ -184,7 +197,9 @@ def readSourceCodeFromFilenameWithInformation(module_name, source_filename):
184
197
  # module and doesn't want any changes from plugins in that case.
185
198
  if module_name is not None:
186
199
  source_code_modified, contributing_plugins = Plugins.onModuleSourceCode(
187
- module_name=module_name, source_code=source_code
200
+ module_name=module_name,
201
+ source_filename=source_filename,
202
+ source_code=source_code,
188
203
  )
189
204
  else:
190
205
  source_code_modified = source_code
@@ -198,12 +213,19 @@ def readSourceCodeFromFilenameWithInformation(module_name, source_filename):
198
213
  for line in source_diff:
199
214
  my_print(line, end="\n" if not line.startswith("---") else "")
200
215
 
201
- return source_code_modified, source_code, contributing_plugins
216
+ result = source_code_modified, source_code, contributing_plugins
217
+
218
+ if pre_load:
219
+ _source_code_cache[key] = result
220
+
221
+ return result
202
222
 
203
223
 
204
- def readSourceCodeFromFilename(module_name, source_filename):
224
+ def readSourceCodeFromFilename(module_name, source_filename, pre_load=False):
205
225
  return readSourceCodeFromFilenameWithInformation(
206
- module_name=module_name, source_filename=source_filename
226
+ module_name=module_name,
227
+ source_filename=source_filename,
228
+ pre_load=pre_load,
207
229
  )[0]
208
230
 
209
231
 
@@ -162,7 +162,7 @@ class VariableClosureLookupVisitorPhase1(VisitorNoopMixin):
162
162
  temp_scope = provider.allocateTempScope("class_inplace")
163
163
 
164
164
  tmp_variable = provider.allocateTempVariable(
165
- temp_scope=temp_scope, name="value"
165
+ temp_scope=temp_scope, name="value", temp_type="object"
166
166
  )
167
167
 
168
168
  statements = mergeStatements(
@@ -471,6 +471,16 @@ can not delete variable '%s' referenced in nested scope"""
471
471
  while node != class_var.getOwner():
472
472
  node = node.getParentVariableProvider()
473
473
  node.getLocalsScope().registerClosureVariable(class_var)
474
+ elif node.isStatementAssignmentVariableGeneric():
475
+ node.parent.replaceChild(
476
+ node,
477
+ makeStatementAssignmentVariable(
478
+ source=node.subnode_source,
479
+ variable=node.variable,
480
+ variable_version=node.variable_version,
481
+ source_ref=node.source_ref,
482
+ ),
483
+ )
474
484
 
475
485
 
476
486
  def completeVariableClosures(tree):
nuitka/utils/AppDirs.py CHANGED
@@ -35,7 +35,7 @@ from nuitka.Tracing import general
35
35
  from .FileOperations import makePath
36
36
  from .Importing import importFromInlineCopy
37
37
 
38
- appdirs = importFromInlineCopy("appdirs", must_exist=False)
38
+ appdirs = importFromInlineCopy("appdirs", must_exist=False, delete_module=True)
39
39
 
40
40
  if appdirs is None:
41
41
  import appdirs # pylint: disable=I0021,import-error
@@ -73,7 +73,7 @@ def getCacheDir():
73
73
  """\
74
74
  Error, failed to create cache directory '%s'. If this is due to a special environment, \
75
75
  please consider making a PR for a general solution that adds support for it, or use \
76
- NUITKA_CACHE_DIR set to a writable directory."""
76
+ 'NUITKA_CACHE_DIR' set to a writable directory."""
77
77
  % _cache_dir
78
78
  )
79
79
 
nuitka/utils/CStrings.py CHANGED
@@ -24,7 +24,7 @@ values.
24
24
  import codecs
25
25
  import re
26
26
 
27
- from nuitka.__past__ import unicode
27
+ from nuitka.__past__ import to_byte, unicode
28
28
 
29
29
 
30
30
  def _identifierEncode(c):
@@ -52,7 +52,7 @@ def _encodePythonStringToC(value):
52
52
  cv = c
53
53
 
54
54
  if c in b'\\\t\r\n"?':
55
- result += r"\%o" % cv
55
+ result += r"\%03o" % cv
56
56
 
57
57
  octal = True
58
58
  elif 32 <= cv <= 127:
@@ -81,7 +81,12 @@ def encodePythonUnicodeToC(value):
81
81
  for c in value:
82
82
  cv = ord(c)
83
83
 
84
- result += r"\%o" % cv
84
+ if c == "\\":
85
+ result += "\\\\"
86
+ elif 34 < cv < 128:
87
+ result += c
88
+ else:
89
+ result += r"\x%04x" % cv
85
90
 
86
91
  return 'L"%s"' % result
87
92
 
@@ -105,6 +110,37 @@ def encodePythonStringToC(value):
105
110
  return result
106
111
 
107
112
 
113
+ def decodeCStringToPython(value):
114
+ assert value.startswith('"')
115
+ value = value[1:-1]
116
+
117
+ result = b""
118
+
119
+ while value:
120
+ if value[0] == "\\":
121
+ value = value[1:]
122
+ if value[0] == "\\":
123
+ result += b"\\"
124
+ continue
125
+
126
+ if value[0].isdigit():
127
+ assert value[1].isdigit(), value
128
+ assert value[2].isdigit(), value
129
+
130
+ octal_number = int(value[2]) + int(value[1]) * 8 + int(value[0]) * 64
131
+ value = value[3:]
132
+
133
+ result += to_byte(octal_number)
134
+ continue
135
+
136
+ assert False, value[0]
137
+
138
+ result += value[0].encode("ascii")
139
+ value = value[1:]
140
+
141
+ return result
142
+
143
+
108
144
  def encodePythonIdentifierToC(value):
109
145
  """Encode an identifier from a given Python string."""
110
146
 
@@ -19,7 +19,13 @@
19
19
 
20
20
 
21
21
  import sys
22
- from optparse import IndentedHelpFormatter, OptionGroup, OptionParser
22
+ from optparse import (
23
+ AmbiguousOptionError,
24
+ BadOptionError,
25
+ IndentedHelpFormatter,
26
+ OptionGroup,
27
+ OptionParser,
28
+ )
23
29
 
24
30
  # For re-export only:
25
31
  from optparse import SUPPRESS_HELP # isort:skip pylint: disable=unused-import
@@ -50,6 +56,41 @@ class OurOptionParser(OptionParser):
50
56
 
51
57
  return OptionParser._process_long_opt(self, rargs, values)
52
58
 
59
+ def _match_long_opt(self, opt):
60
+ """_match_long_opt(opt : string) -> string
61
+
62
+ Determine which long option string 'opt' matches, ie. which one
63
+ it is an unambiguous abbreviation for. Raises BadOptionError if
64
+ 'opt' doesn't unambiguously match any long option string.
65
+
66
+ Nuitka: We overload it, in order avoid issues with conflicting
67
+ options that are really only aliases of the same option.
68
+ """
69
+ matched_options = set()
70
+ possibilities = []
71
+
72
+ # Exact matches are never ambiguous. We sometimes append to option names
73
+ # in order to detail things.
74
+ for option_name in self._long_opt:
75
+ if opt == option_name:
76
+ return opt
77
+
78
+ for option_name, option_obj in self._long_opt.items():
79
+ if option_name.startswith(opt):
80
+ if option_obj not in matched_options:
81
+ matched_options.add(option_obj)
82
+ possibilities.append(option_name)
83
+
84
+ # No exact match, so there had better be just one possibility.
85
+ if len(matched_options) > 1:
86
+ raise AmbiguousOptionError(opt, possibilities)
87
+
88
+ if possibilities:
89
+ assert len(possibilities) == 1, possibilities
90
+ return possibilities[0]
91
+ else:
92
+ raise BadOptionError(opt)
93
+
53
94
  def add_option(self, *args, **kwargs):
54
95
  require_compiling = kwargs.pop("require_compiling", True)
55
96