Update app.py
Browse files
app.py
CHANGED
|
@@ -57,36 +57,60 @@ def _patch_relative_imports(project_root: str):
|
|
| 57 |
# --- END ABSOLUTE-IMPORT & ENV HOTFIX ---
|
| 58 |
|
| 59 |
|
| 60 |
-
# --- BEGIN
|
| 61 |
-
# Some modules
|
| 62 |
-
# the
|
| 63 |
-
#
|
|
|
|
|
|
|
|
|
|
| 64 |
import importlib
|
|
|
|
| 65 |
from types import ModuleType
|
| 66 |
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
|
| 91 |
|
| 92 |
# Import the main application from core
|
|
|
|
| 57 |
# --- END ABSOLUTE-IMPORT & ENV HOTFIX ---
|
| 58 |
|
| 59 |
|
| 60 |
+
# --- BEGIN robust compatibility: ensure 'utilities' references the real utils package ----------
|
| 61 |
+
# Some legacy modules import `utilities`. We will ensure sys.modules['utilities'] points
|
| 62 |
+
# to the same module object as 'utils' by:
|
| 63 |
+
# 1) Attempting a normal import of utils; if that works, alias it.
|
| 64 |
+
# 2) If normal import fails or would recurse, fall back to loading utils/__init__.py
|
| 65 |
+
# directly via importlib.util.spec_from_file_location, placing the module object
|
| 66 |
+
# into sys.modules BEFORE executing the module to avoid circular lazy-swaps.
|
| 67 |
import importlib
|
| 68 |
+
import importlib.util
|
| 69 |
from types import ModuleType
|
| 70 |
|
| 71 |
+
def _ensure_utilities_alias(project_root: str):
|
| 72 |
+
# If utilities already exists and isn't obviously broken, leave it alone.
|
| 73 |
+
if "utilities" in sys.modules and getattr(sys.modules["utilities"], "__name__", "").startswith("utils"):
|
| 74 |
+
return
|
| 75 |
+
|
| 76 |
+
# Try normal import first (fast path)
|
| 77 |
+
try:
|
| 78 |
+
_utils = importlib.import_module("utils")
|
| 79 |
+
sys.modules["utilities"] = _utils
|
| 80 |
+
return
|
| 81 |
+
except Exception:
|
| 82 |
+
# proceed to robust file-loader fallback below
|
| 83 |
+
pass
|
| 84 |
+
|
| 85 |
+
# Fallback: load utils package explicitly from filesystem using its __init__.py
|
| 86 |
+
utils_init = os.path.join(project_root, "utils", "__init__.py")
|
| 87 |
+
if not os.path.exists(utils_init):
|
| 88 |
+
# nothing we can do here — leave to normal import to raise error later
|
| 89 |
+
return
|
| 90 |
+
|
| 91 |
+
spec = importlib.util.spec_from_file_location("utils", utils_init)
|
| 92 |
+
if spec is None or spec.loader is None:
|
| 93 |
+
return
|
| 94 |
+
|
| 95 |
+
# Create the module object and put it in sys.modules BEFORE execution.
|
| 96 |
+
# This ensures imports within utils that examine sys.modules won't re-enter a cycle.
|
| 97 |
+
utils_mod = importlib.util.module_from_spec(spec)
|
| 98 |
+
sys.modules["utils"] = utils_mod
|
| 99 |
+
# Also alias utilities -> utils_mod so imports of utilities see the same module object.
|
| 100 |
+
sys.modules["utilities"] = utils_mod
|
| 101 |
+
|
| 102 |
+
# Execute the module (this will run utils/__init__.py)
|
| 103 |
+
try:
|
| 104 |
+
spec.loader.exec_module(utils_mod) # type: ignore[attr-defined]
|
| 105 |
+
except Exception:
|
| 106 |
+
# If execution fails, remove the partially-initialized entries so Python's import machinery can surface a clean error.
|
| 107 |
+
sys.modules.pop("utils", None)
|
| 108 |
+
sys.modules.pop("utilities", None)
|
| 109 |
+
raise
|
| 110 |
+
|
| 111 |
+
# Ensure alias early, before importing core
|
| 112 |
+
_ensure_utilities_alias(PROJECT_ROOT)
|
| 113 |
+
# --- END robust compatibility ------------------------------------------------
|
| 114 |
|
| 115 |
|
| 116 |
# Import the main application from core
|