Skip to content

Commit 324044d

Browse files
committed
Corrige la régression post-rebase (code intrus)
Cause: après rebase/rollback, des fragments de code intrus et mal indentés se sont retrouvés dans plusieurs __init__.py d'engines et dans le SDK (imports legacy utils.*), provoquant SyntaxError/IndentationError/ModuleNotFoundError au démarrage. Actions: réécriture des bootstrap engines (cx_freeze/nuitka/pyinstaller), correction des imports engine_sdk vers les modules actuels, ajustement du fallback de logs dans EngineLoader.registry, et nettoyage du .ui IDE invalide (propriétés splitter sizes non supportées). Résultat: chargement des engines rétabli, pycompiler_ark démarre, tests dynamiques/GUI smoke passent.
1 parent 3b397af commit 324044d

8 files changed

Lines changed: 55 additions & 1103 deletions

File tree

ENGINES/cx_freeze/__init__.py

Lines changed: 22 additions & 429 deletions
Large diffs are not rendered by default.

ENGINES/nuitka/__init__.py

Lines changed: 6 additions & 344 deletions
Original file line numberDiff line numberDiff line change
@@ -1,375 +1,37 @@
11
# SPDX-License-Identifier: GPL-3.0-only
2-
# Nuitka engine package - auto-import all submodules
3-
4-
# Copyright (C) 2025 Samuel Amen Ague
5-
# Author: Samuel Amen Ague
2+
# Nuitka engine package bootstrap
63
from __future__ import annotations
74

85
import importlib
96
import pkgutil
107

118
__all__: list[str] = []
129

13-
# Explicit registration to ensure the engine is available even if auto-import misses it
1410
try:
1511
from engine_sdk import registry as _registry # type: ignore
16-
17-
from .engine import NuitkaEngine as _NuitkaEngine
12+
from .engine import NuitkaEngine
1813

1914
if _registry:
20-
_registry.register(_NuitkaEngine)
15+
_registry.register(NuitkaEngine)
16+
__all__.append("NuitkaEngine")
2117
except Exception:
2218
pass
2319

2420

2521
def _auto_import_all() -> None:
26-
"""
27-
Import all Python modules and subpackages contained in this package.
28-
This ensures any engine definitions or side-effects are loaded on import.
29-
"""
22+
"""Import all nested modules to keep plugin side-effects available."""
3023
try:
3124
pkg_name = __name__
32-
# __path__ is defined for packages; walk through all nested modules/packages
3325
for _finder, name, _ispkg in pkgutil.walk_packages(__path__, prefix=f"{pkg_name}."):
3426
try:
3527
importlib.import_module(name)
36-
# Optionally track short module names in __all__
3728
short = name.rsplit(".", 1)[-1]
3829
if short not in __all__:
3930
__all__.append(short)
4031
except Exception:
41-
# Avoid breaking package import if some submodule import fails
4232
pass
4333
except Exception:
44-
# Be resilient to environments where __path__ is unusual
4534
pass
4635

4736

48-
return cmd
49-
50-
except Exception as e:
51-
try:
52-
if hasattr(gui, "log"):
53-
log_with_level(
54-
gui, "error", f"Erreur construction commande Nuitka: {e}"
55-
)
56-
except Exception:
57-
pass
58-
return []
59-
60-
def program_and_args(self, gui, file: str) -> Optional[tuple[str, list[str]]]:
61-
"""Return the program and args for QProcess."""
62-
cmd = self.build_command(gui, file)
63-
if not cmd:
64-
return None
65-
return cmd[0], cmd[1:]
66-
67-
def environment(self) -> Optional[dict[str, str]]:
68-
"""Return environment variables for the compilation process."""
69-
try:
70-
env = {}
71-
72-
# Set PYTHONIOENCODING for proper output handling
73-
env["PYTHONIOENCODING"] = "utf-8"
74-
75-
# Disable PYTHONUTF8 mode to avoid conflicts
76-
env["PYTHONUTF8"] = "0"
77-
78-
# Set LC_ALL for consistent output
79-
env["LC_ALL"] = "C"
80-
81-
return env if env else None
82-
except Exception:
83-
return None
84-
85-
def on_success(self, gui, file: str) -> None:
86-
"""Handle successful compilation."""
87-
try:
88-
# Log success message with output location
89-
if (
90-
hasattr(self, "_nuitka_output_dir")
91-
and self._nuitka_output_dir.text().strip()
92-
):
93-
try:
94-
if hasattr(gui, "log"):
95-
log_with_level(
96-
gui,
97-
"success",
98-
f"Compilation Nuitka terminée. Sortie dans: {self._nuitka_output_dir.text().strip()}",
99-
)
100-
except Exception:
101-
pass
102-
except Exception:
103-
pass
104-
105-
def create_tab(self, gui):
106-
"""
107-
Create the Nuitka tab widget with all options.
108-
Returns (widget, label) tuple or None if tab creation fails.
109-
"""
110-
try:
111-
from PySide6.QtWidgets import (
112-
QCheckBox,
113-
QFormLayout,
114-
QLabel,
115-
QGroupBox,
116-
QSizePolicy,
117-
QVBoxLayout,
118-
QWidget,
119-
)
120-
121-
# Create the tab widget
122-
tab = QWidget()
123-
tab.setObjectName("tab_nuitka_dynamic")
124-
125-
# Create main layout
126-
layout = QVBoxLayout(tab)
127-
layout.setSpacing(8)
128-
layout.setContentsMargins(8, 8, 8, 8)
129-
130-
build_group = QGroupBox("Build", tab)
131-
build_layout = QFormLayout()
132-
build_layout.setSpacing(6)
133-
134-
# Onefile option
135-
self._nuitka_onefile = QCheckBox("Onefile (--onefile)")
136-
self._nuitka_onefile.setObjectName("nuitka_onefile_dynamic")
137-
build_layout.addRow("Mode:", self._nuitka_onefile)
138-
139-
# Standalone option
140-
self._nuitka_standalone = QCheckBox("Standalone (--standalone)")
141-
self._nuitka_standalone.setObjectName("nuitka_standalone_dynamic")
142-
build_layout.addRow("Type:", self._nuitka_standalone)
143-
144-
# Disable console option
145-
self._nuitka_disable_console = QCheckBox("Disable console")
146-
self._nuitka_disable_console.setObjectName("nuitka_disable_console_dynamic")
147-
self._nuitka_disable_console.setToolTip(
148-
"Disable console window for Windows builds."
149-
)
150-
build_layout.addRow("Console:", self._nuitka_disable_console)
151-
build_group.setLayout(build_layout)
152-
153-
output_group = QGroupBox("Output", tab)
154-
output_layout = QVBoxLayout()
155-
output_layout.setSpacing(6)
156-
157-
# Output directory
158-
self._nuitka_output_dir = add_output_dir(
159-
output_layout,
160-
"Dossier de sortie (--output-dir)",
161-
"nuitka_output_dir_dynamic",
162-
)
163-
output_group.setLayout(output_layout)
164-
165-
assets_group = QGroupBox("Assets", tab)
166-
assets_layout = QVBoxLayout()
167-
assets_layout.setSpacing(6)
168-
169-
# Icon button + path input
170-
self._btn_nuitka_icon, self._nuitka_icon_path_input = add_icon_selector(
171-
assets_layout,
172-
"🎨 Choisir une icône (.ico) Nuitka",
173-
self.select_icon,
174-
"btn_nuitka_icon_dynamic",
175-
"nuitka_icon_path_input_dynamic",
176-
)
177-
if self._nuitka_icon_path_input is not None:
178-
self._nuitka_icon_path_input.textChanged.connect(
179-
self._on_icon_path_changed
180-
)
181-
assets_group.setLayout(assets_layout)
182-
183-
hint = QLabel(
184-
"Tip: combine standalone or onefile modes carefully, then tune console visibility for desktop apps.",
185-
tab,
186-
)
187-
hint.setStyleSheet("color: #888; font-size: 11px;")
188-
hint.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
189-
190-
layout.addWidget(build_group)
191-
layout.addWidget(output_group)
192-
layout.addWidget(assets_group)
193-
layout.addWidget(hint)
194-
layout.addStretch()
195-
196-
# Store references in the engine instance for build_command access
197-
self._gui = gui
198-
199-
return tab, "Nuitka"
200-
201-
except Exception as e:
202-
try:
203-
if hasattr(gui, "log"):
204-
log_with_level(gui, "error", f"Erreur création onglet Nuitka: {e}")
205-
except Exception:
206-
pass
207-
return None
208-
209-
def get_config(self, gui) -> dict:
210-
"""Return a JSON-serializable snapshot of current Nuitka UI options."""
211-
try:
212-
cfg = {}
213-
if hasattr(self, "_nuitka_onefile") and self._nuitka_onefile is not None:
214-
cfg["onefile"] = bool(self._nuitka_onefile.isChecked())
215-
if (
216-
hasattr(self, "_nuitka_standalone")
217-
and self._nuitka_standalone is not None
218-
):
219-
cfg["standalone"] = bool(self._nuitka_standalone.isChecked())
220-
if (
221-
hasattr(self, "_nuitka_disable_console")
222-
and self._nuitka_disable_console is not None
223-
):
224-
cfg["disable_console"] = bool(self._nuitka_disable_console.isChecked())
225-
if (
226-
hasattr(self, "_nuitka_output_dir")
227-
and self._nuitka_output_dir is not None
228-
):
229-
cfg["output_dir"] = self._nuitka_output_dir.text().strip()
230-
icon_path = ""
231-
if (
232-
hasattr(self, "_nuitka_icon_path_input")
233-
and self._nuitka_icon_path_input is not None
234-
):
235-
icon_path = self._nuitka_icon_path_input.text().strip()
236-
if (
237-
not icon_path
238-
and hasattr(self, "_nuitka_selected_icon")
239-
and self._nuitka_selected_icon
240-
):
241-
icon_path = str(self._nuitka_selected_icon).strip()
242-
if (
243-
not icon_path
244-
and hasattr(self, "_selected_icon")
245-
and self._selected_icon
246-
):
247-
icon_path = str(self._selected_icon).strip()
248-
if icon_path:
249-
self._nuitka_selected_icon = icon_path
250-
self._selected_icon = icon_path
251-
cfg["selected_icon"] = icon_path
252-
return cfg
253-
except Exception:
254-
return {}
255-
256-
def set_config(self, gui, cfg: dict) -> None:
257-
"""Apply a config dict to Nuitka UI widgets."""
258-
if not isinstance(cfg, dict):
259-
return
260-
try:
261-
if (
262-
hasattr(self, "_nuitka_onefile")
263-
and self._nuitka_onefile is not None
264-
and "onefile" in cfg
265-
):
266-
self._nuitka_onefile.setChecked(bool(cfg.get("onefile")))
267-
if (
268-
hasattr(self, "_nuitka_standalone")
269-
and self._nuitka_standalone is not None
270-
and "standalone" in cfg
271-
):
272-
self._nuitka_standalone.setChecked(bool(cfg.get("standalone")))
273-
if (
274-
hasattr(self, "_nuitka_disable_console")
275-
and self._nuitka_disable_console is not None
276-
and "disable_console" in cfg
277-
):
278-
self._nuitka_disable_console.setChecked(
279-
bool(cfg.get("disable_console"))
280-
)
281-
if (
282-
hasattr(self, "_nuitka_output_dir")
283-
and self._nuitka_output_dir is not None
284-
and "output_dir" in cfg
285-
):
286-
val = cfg.get("output_dir") or ""
287-
self._nuitka_output_dir.setText(str(val))
288-
if "selected_icon" in cfg:
289-
icon = cfg.get("selected_icon") or ""
290-
self._nuitka_selected_icon = icon or None
291-
self._selected_icon = icon or None
292-
if (
293-
hasattr(self, "_nuitka_icon_path_input")
294-
and self._nuitka_icon_path_input is not None
295-
):
296-
self._nuitka_icon_path_input.setText(str(icon))
297-
except Exception:
298-
pass
299-
300-
def _get_btn(self, name: str):
301-
"""Get button widget from engine instance or GUI."""
302-
if hasattr(self, f"_btn_{name}"):
303-
return getattr(self, f"_btn_{name}")
304-
return getattr(self._gui, name, None) if hasattr(self, "_gui") else None
305-
306-
def get_log_prefix(self, file_basename: str) -> str:
307-
return f"Nuitka ({self.version})"
308-
309-
def apply_i18n(self, gui, tr: dict) -> None:
310-
"""Apply internationalization translations to the engine UI."""
311-
try:
312-
# Apply translations to UI elements if they exist
313-
if hasattr(self, "_nuitka_onefile"):
314-
self._nuitka_onefile.setText(
315-
self.engine_translate("onefile_checkbox", "Onefile")
316-
)
317-
if hasattr(self, "_nuitka_standalone"):
318-
self._nuitka_standalone.setText(
319-
self.engine_translate("standalone_checkbox", "Standalone")
320-
)
321-
if hasattr(self, "_nuitka_disable_console"):
322-
self._nuitka_disable_console.setText(
323-
self.engine_translate(
324-
"disable_console_checkbox", "Disable console"
325-
)
326-
)
327-
if hasattr(self, "_nuitka_disable_console"):
328-
self._nuitka_disable_console.setToolTip(
329-
self.engine_translate("tt_disable_console", "")
330-
)
331-
if hasattr(self, "_nuitka_output_dir"):
332-
self._nuitka_output_dir.setPlaceholderText(
333-
self.engine_translate("output_placeholder", "Output directory")
334-
)
335-
if hasattr(self, "_btn_nuitka_icon"):
336-
self._btn_nuitka_icon.setText(
337-
self.engine_translate("icon_button", "Select icon")
338-
)
339-
except Exception:
340-
pass
341-
342-
def _on_icon_path_changed(self, text: str) -> None:
343-
"""Keep the selected icon path in sync with manual edits."""
344-
icon = text.strip()
345-
self._nuitka_selected_icon = icon or None
346-
self._selected_icon = icon or None
347-
348-
def select_icon(self) -> None:
349-
"""Select an icon file for the executable."""
350-
try:
351-
from PySide6.QtWidgets import QFileDialog
352-
353-
file_path, _ = QFileDialog.getOpenFileName(
354-
self._gui,
355-
"Sélectionner une icône",
356-
"",
357-
"Fichiers icône (*.ico);;Tous les fichiers (*)",
358-
)
359-
if file_path:
360-
self._selected_icon = file_path
361-
self._nuitka_selected_icon = file_path
362-
if (
363-
hasattr(self, "_nuitka_icon_path_input")
364-
and self._nuitka_icon_path_input is not None
365-
):
366-
self._nuitka_icon_path_input.setText(file_path)
367-
if hasattr(self._gui, "log"):
368-
self._gui.log.append(
369-
f"Icône sélectionnée pour Nuitka : {file_path}"
370-
)
371-
except Exception as e:
372-
if hasattr(self._gui, "log"):
373-
log_with_level(
374-
self._gui, "error", f"Erreur lors de la sélection de l'icône : {e}"
375-
)
37+
_auto_import_all()

ENGINES/nuitka/engine.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
pip_show,
1616
resolve_project_venv,
1717
)
18-
from utils.auto_plugins import _tr
18+
from Core.Auto_Command_Builder import _tr
1919

2020

2121
class NuitkaEngine(CompilerEngine):

0 commit comments

Comments
 (0)