fix(pfs,cli): the CPT parser imports rex lazily so the stack CLI starts in the api image (no fsspec there) — the nightly Zotero sync and mail poller run inside it (refs #718)
Some checks failed
CI / lint (push) Successful in 33s
CI / notebooks-smoke (push) Successful in 1m26s
Deploy / notebooks (push) Has been skipped
Deploy / zotero (push) Has been skipped
Deploy / docs (push) Has been skipped
Deploy / api (push) Has been skipped
Deploy / llm (push) Has been skipped
Deploy / mc (push) Has been skipped
Infra CI / notebooks (push) Successful in 51s
Infra CI / zotero (push) Successful in 13s
Infra CI / docs (push) Successful in 20s
Infra CI / api (push) Successful in 1m13s
Infra CI / llm (push) Successful in 45s
Infra CI / mc (push) Failing after 13s
Deploy / report (push) Successful in 14s
CI / test (push) Successful in 14m20s

This commit is contained in:
kert
2026-09-11 16:20:23 -04:00
parent 0cf878d4ab
commit f7c31346bb
2 changed files with 37 additions and 1 deletions

View File

@@ -47,7 +47,6 @@ from pfs.cpt_model import (
CptReference,
CptSection,
)
from rex.comments.epub_text import content_root
# One CPT code: 4 digits + a digit/letter (99490, 0202U, 99213F, 0042T, 0001A).
_CODE = re.compile(r"\b\d{4}[0-9A-Z]\b")
@@ -906,6 +905,11 @@ def parse_epub(path: Path, *, year: int | None = None) -> CptEdition:
# Resolved once via container.xml -> the OPF's own path, not
# hard-coded — falls back to "OPS/" (every edition checked so
# far) when container.xml is missing/malformed (F2).
# Lazy: importing rex.comments pulls in the rex package (fsspec),
# which the api image's `cli` extra does not carry — the CLI must
# import without it (tests/cli/test_cli_import_without_optional_deps.py).
from rex.comments.epub_text import content_root
root = content_root(zf)
toc_ranges: dict[str, tuple[str, str]] = {}

View File

@@ -0,0 +1,32 @@
"""The api image installs the ``cli`` extra only (no fsspec/s3fs/obstore —
those belong to the lake/rex extras). ``stack`` must still start there:
the nightly Zotero sync and the mail poller run inside that image. On
2026-09-11 a module-level ``pfs.cpt_load → pfs.cpt_epub → rex`` import
chain made every ``stack`` invocation in the api image die with
``ModuleNotFoundError: fsspec``."""
from __future__ import annotations
import subprocess
import sys
_PROBE = """
import builtins
_real = builtins.__import__
def _fake(name, *a, **k):
if name.split('.')[0] in {'fsspec', 's3fs', 'obstore'}:
raise ModuleNotFoundError(name)
return _real(name, *a, **k)
builtins.__import__ = _fake
import cli # the `stack` entry point package
import cli.pfs, cli.bib, cli.llm
print('cli ok')
"""
def test_stack_cli_imports_without_lake_extras():
r = subprocess.run(
[sys.executable, "-c", _PROBE], capture_output=True, text=True, check=False
)
assert r.returncode == 0, r.stderr[-1200:]
assert "cli ok" in r.stdout