The session db fixture now disposes the engine before deleting the file, since a module under a no-op db (tests/sdk, tests/flow) may have connected first; the sdk import tests forget the study packages they import; the supervision tests keep the real quarantine length so it cannot expire mid-assertion. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GAeg4Jo6xjZzjwy9QDWMQ
112 lines
3.2 KiB
Python
112 lines
3.2 KiB
Python
"""What a node's code reaches — the narrow answer a cache key is keyed on."""
|
|
|
|
import sys
|
|
import textwrap
|
|
|
|
import pytest
|
|
|
|
from fluksio.sdk.imports import digest_of, reached
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _forget_studies():
|
|
"""The packages below are temporary files under names other tests use too."""
|
|
yield
|
|
for name in [n for n in sys.modules if n.split(".")[0] in ("study", "arm")]:
|
|
del sys.modules[name]
|
|
|
|
|
|
def _write(root, name, body):
|
|
path = root / f"{name}.py"
|
|
path.write_text(textwrap.dedent(body).lstrip())
|
|
return path
|
|
|
|
|
|
def _study(tmp_path):
|
|
"""A package whose node function delegates to a helper beside it."""
|
|
root = tmp_path / "study"
|
|
root.mkdir()
|
|
(root / "__init__.py").write_text("VERSION = 1\n")
|
|
_write(
|
|
root,
|
|
"train",
|
|
"""
|
|
import json
|
|
|
|
from study.helpers import curve
|
|
|
|
|
|
def fit(lr):
|
|
return json.dumps(curve(lr))
|
|
""",
|
|
)
|
|
_write(root, "helpers", "def curve(lr):\n return [lr]\n")
|
|
_write(root, "unused", "def nothing():\n return 0\n")
|
|
return root
|
|
|
|
|
|
def test_the_walk_follows_a_helper_and_stops_at_installed_code(tmp_path, monkeypatch):
|
|
"""The shim says nothing about this, and the repository says too much."""
|
|
_study(tmp_path)
|
|
monkeypatch.syspath_prepend(str(tmp_path))
|
|
for name in [n for n in sys.modules if n == "study" or n.startswith("study.")]:
|
|
del sys.modules[name]
|
|
|
|
from study.train import fit
|
|
|
|
files = reached(fit)
|
|
|
|
# The module, the helper it calls into, and the package whose `__init__`
|
|
# runs on the way in. Not the sibling nobody imports, and not `json`.
|
|
assert set(files) == {"study", "study.train", "study.helpers"}
|
|
assert all(path.endswith(".py") for path in files.values())
|
|
|
|
|
|
def test_the_digest_moves_with_the_helper_and_not_with_the_neighbour(
|
|
tmp_path, monkeypatch
|
|
):
|
|
"""The whole point: it is neither necessary nor sufficient otherwise."""
|
|
root = _study(tmp_path)
|
|
monkeypatch.syspath_prepend(str(tmp_path))
|
|
for name in [n for n in sys.modules if n == "study" or n.startswith("study.")]:
|
|
del sys.modules[name]
|
|
|
|
from study.train import fit
|
|
|
|
files = reached(fit)
|
|
before = digest_of(files)
|
|
|
|
_write(root, "unused", "def nothing():\n return 1\n")
|
|
assert digest_of(files) == before
|
|
|
|
_write(root, "helpers", "def curve(lr):\n return [lr, lr]\n")
|
|
assert digest_of(files) != before
|
|
|
|
# A file this engine cannot see is not half an answer.
|
|
assert digest_of({**files, "study.gone": str(root / "gone.py")}) == ""
|
|
|
|
|
|
def test_the_tool_itself_is_not_the_projects_code(tmp_path, monkeypatch):
|
|
"""Every node imports the authoring API, and from a checkout that is source."""
|
|
root = tmp_path / "arm"
|
|
root.mkdir()
|
|
(root / "__init__.py").write_text("")
|
|
_write(
|
|
root,
|
|
"work",
|
|
"""
|
|
from fluksio import node
|
|
|
|
|
|
def fit(lr):
|
|
return lr
|
|
""",
|
|
)
|
|
monkeypatch.syspath_prepend(str(tmp_path))
|
|
for name in [n for n in sys.modules if n == "arm" or n.startswith("arm.")]:
|
|
del sys.modules[name]
|
|
|
|
from arm.work import fit
|
|
|
|
assert set(reached(fit)) == {"arm", "arm.work"}
|