fix(update): the purge keeps hermes_constants; it is refreshed in place instead
hermes_constants owns the _HERMES_HOME_OVERRIDE ContextVar. Evicting it hands later imports a fresh var: a reset token taken through the old module raises, and an override set before the purge silently disappears. _reload_updated_runtime_modules already re-executes it in place before every purge, so new symbols still arrive. Caught by tests/hermes_cli/test_update_config_reload_tools_config.py on the stack.
This commit is contained in:
@@ -27,10 +27,12 @@ _UPDATE_RUNTIME_RELOAD_MODULES = "hermes_constants", "tools.environments.local",
|
||||
|
||||
#: Modules EXECUTING the update survive the purge: evicting them buys nothing (running frames
|
||||
#: keep them alive) and reloading them mid-flight is the one genuinely unsafe move.
|
||||
#: ``hermes_logging`` is protected for a different reason: its queue listener, handler list and
|
||||
#: ``_logging_initialized`` flag are module globals, so a fresh copy starts a SECOND
|
||||
#: QueueListener over the same log files while the first one keeps running.
|
||||
_STALE_PURGE_PROTECTED = frozenset({"hermes_cli", "hermes_cli.main", "hermes_logging"})
|
||||
#: Two root modules carry process-wide identity state and are refreshed in place by
|
||||
#: ``_reload_updated_runtime_modules`` instead: ``hermes_logging`` (a fresh copy starts a SECOND
|
||||
#: QueueListener over the same log files while the first keeps running) and ``hermes_constants``
|
||||
#: (its ``_HERMES_HOME_OVERRIDE`` ContextVar — a token taken through the old module cannot reset a
|
||||
#: fresh module's var, and an override set before the purge would silently vanish).
|
||||
_STALE_PURGE_PROTECTED = frozenset({"hermes_cli", "hermes_cli.main", "hermes_logging", "hermes_constants"})
|
||||
|
||||
#: The updater's own module family (``update_cmd*``, ``update_receipt``, ``update_inventory``,
|
||||
#: ``update_lock``, ...) is protected as a prefix: these hold per-run state — the open receipt
|
||||
|
||||
@@ -70,9 +70,9 @@ def test_update_migration_survives_stale_module_missing_call_time_symbol(tmp_pat
|
||||
|
||||
|
||||
def test_update_migration_import_failure_after_purge_prints_fallback(tmp_path, monkeypatch, capsys):
|
||||
"""The purge evicts ``hermes_cli.*`` but not root modules (``hermes_constants``, ...), so the
|
||||
post-purge ``from hermes_cli.config import ...`` re-executes NEW config.py against OLD root
|
||||
modules and can raise ImportError. That must print the 'run hermes config migrate' fallback and
|
||||
"""The purge protects ``hermes_constants`` (identity-bearing ContextVar state), so the
|
||||
post-purge ``from hermes_cli.config import ...`` re-executes NEW config.py against that OLD
|
||||
root module and can raise ImportError. That must print the 'run hermes config migrate' fallback and
|
||||
return — not escape and abort the rest of post-update maintenance (fleet restart)."""
|
||||
home = tmp_path / "flat-home"
|
||||
home.mkdir()
|
||||
|
||||
Reference in New Issue
Block a user