|
4 | 4 | the same :class:`Step` model + JSON action schema, so a script |
5 | 5 | authored in one view loads cleanly in the other. |
6 | 6 |
|
7 | | -Public surface:: |
8 | | -
|
9 | | - from je_auto_control.gui.flow_editor import ( |
10 | | - FlowEditorTab, FlowGraphScene, layout_steps, |
11 | | - ) |
12 | | -
|
13 | | -The ``layout`` module is Qt-free and eager so headless tests can import |
14 | | -it without instantiating PySide6. ``scene`` and ``tab`` are loaded |
15 | | -lazily via :func:`__getattr__` because they pull in Qt. |
| 7 | +The ``layout`` module is Qt-free and eager so headless tests can |
| 8 | +import it without instantiating PySide6. The Qt-dependent names |
| 9 | +(``FlowGraphScene``, ``FlowEditorTab`` …) load lazily via |
| 10 | +:func:`__getattr__`; they are intentionally absent from ``__all__`` |
| 11 | +because Pylint's E0603 refuses to certify names that ``import *`` can |
| 12 | +not resolve at module-load time. ``from je_auto_control.gui.flow_editor |
| 13 | +import FlowEditorTab`` still works — Python falls through to |
| 14 | +``__getattr__`` when the attribute is not pre-bound. |
16 | 15 | """ |
17 | 16 | from je_auto_control.gui.flow_editor.layout import ( |
18 | 17 | FlowEdge, FlowLayout, FlowNodePosition, layout_steps, |
|
27 | 26 |
|
28 | 27 |
|
29 | 28 | def __getattr__(name): |
30 | | - if name in _LAZY_SUBMODULES: |
31 | | - import importlib |
32 | | - module = importlib.import_module(_LAZY_SUBMODULES[name]) |
33 | | - return getattr(module, name) |
34 | | - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") |
| 29 | + target = _LAZY_SUBMODULES.get(name) |
| 30 | + if target is None: |
| 31 | + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") |
| 32 | + import importlib |
| 33 | + # Argument is looked up from a hard-coded dict above, never user |
| 34 | + # input — safe to import dynamically. |
| 35 | + module = importlib.import_module(target) # nosemgrep |
| 36 | + return getattr(module, name) |
35 | 37 |
|
36 | 38 |
|
37 | 39 | __all__ = [ |
38 | | - "FlowEdge", "FlowEditorTab", "FlowEdgeItem", "FlowGraphScene", |
39 | | - "FlowLayout", "FlowNodeItem", "FlowNodePosition", "layout_steps", |
| 40 | + "FlowEdge", "FlowLayout", "FlowNodePosition", "layout_steps", |
40 | 41 | ] |
0 commit comments