more organization
This commit is contained in:
+49
-50
@@ -1,6 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import importlib
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
@@ -9,62 +11,59 @@ from typing import Any
|
||||
|
||||
@dataclass
|
||||
class HotModule:
|
||||
name: str
|
||||
file_path: str
|
||||
state_keys: list[str] = field(default_factory=list)
|
||||
delegation_targets: list[str] = field(default_factory=list)
|
||||
name: str
|
||||
file_path: str
|
||||
state_keys: list[str] = field(default_factory=list)
|
||||
delegation_targets: list[str] = field(default_factory=list)
|
||||
|
||||
class HotReloader:
|
||||
HOT_MODULES: dict[str, HotModule] = {}
|
||||
last_error: str | None = None
|
||||
is_error_state: bool = False
|
||||
HOT_MODULES: dict[str, HotModule] = {}
|
||||
last_error: str | None = None
|
||||
is_error_state: bool = False
|
||||
|
||||
@classmethod
|
||||
def register(cls, module: HotModule) -> None:
|
||||
if module.name in cls.HOT_MODULES:
|
||||
raise ValueError(f"Module {module.name} already registered")
|
||||
cls.HOT_MODULES[module.name] = module
|
||||
@classmethod
|
||||
def register(cls, module: HotModule) -> None:
|
||||
if module.name in cls.HOT_MODULES:
|
||||
raise ValueError(f"Module {module.name} already registered")
|
||||
cls.HOT_MODULES[module.name] = module
|
||||
|
||||
@classmethod
|
||||
def capture_state(cls, app: Any, state_keys: list[str]) -> dict[str, Any]:
|
||||
return {key: copy.deepcopy(getattr(app, key, None)) for key in state_keys if hasattr(app, key)}
|
||||
@classmethod
|
||||
def capture_state(cls, app: Any, state_keys: list[str]) -> dict[str, Any]:
|
||||
return {key: copy.deepcopy(getattr(app, key, None)) for key in state_keys if hasattr(app, key)}
|
||||
|
||||
@classmethod
|
||||
def restore_state(cls, app: Any, state: dict[str, Any]) -> None:
|
||||
for key, value in state.items():
|
||||
setattr(app, key, value)
|
||||
@classmethod
|
||||
def restore_state(cls, app: Any, state: dict[str, Any]) -> None:
|
||||
for key, value in state.items():
|
||||
setattr(app, key, value)
|
||||
|
||||
@classmethod
|
||||
def reload(cls, module_name: str, app: Any) -> bool:
|
||||
if module_name not in cls.HOT_MODULES:
|
||||
cls.last_error = f"Module {module_name} not registered"
|
||||
cls.is_error_state = True
|
||||
return False
|
||||
@classmethod
|
||||
def reload(cls, module_name: str, app: Any) -> bool:
|
||||
if module_name not in cls.HOT_MODULES:
|
||||
cls.last_error = f"Module {module_name} not registered"
|
||||
cls.is_error_state = True
|
||||
return False
|
||||
|
||||
hm = cls.HOT_MODULES[module_name]
|
||||
state = cls.capture_state(app, hm.state_keys)
|
||||
hm = cls.HOT_MODULES[module_name]
|
||||
state = cls.capture_state(app, hm.state_keys)
|
||||
|
||||
try:
|
||||
import importlib
|
||||
import sys
|
||||
if module_name in sys.modules:
|
||||
old_module = sys.modules[module_name]
|
||||
importlib.reload(old_module)
|
||||
else:
|
||||
importlib.import_module(module_name)
|
||||
cls.last_error = None
|
||||
cls.is_error_state = False
|
||||
return True
|
||||
except Exception:
|
||||
cls.restore_state(app, state)
|
||||
cls.last_error = traceback.format_exc()
|
||||
cls.is_error_state = True
|
||||
return False
|
||||
try:
|
||||
if module_name in sys.modules:
|
||||
old_module = sys.modules[module_name]
|
||||
importlib.reload(old_module)
|
||||
else:
|
||||
importlib.import_module(module_name)
|
||||
cls.last_error = None
|
||||
cls.is_error_state = False
|
||||
return True
|
||||
except Exception:
|
||||
cls.restore_state(app, state)
|
||||
cls.last_error = traceback.format_exc()
|
||||
cls.is_error_state = True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def reload_all(cls, app: Any) -> bool:
|
||||
success = True
|
||||
for name in cls.HOT_MODULES:
|
||||
if not cls.reload(name, app):
|
||||
success = False
|
||||
return success
|
||||
@classmethod
|
||||
def reload_all(cls, app: Any) -> bool:
|
||||
success = True
|
||||
for name in cls.HOT_MODULES:
|
||||
if not cls.reload(name, app): success = False
|
||||
return success
|
||||
|
||||
Reference in New Issue
Block a user