mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-10-26 13:16:24 +00:00
`workspace_changes/api.py` imports `deerflow.runtime.user_context` for the AUTO sentinel (#6282). Importing that submodule runs the runtime package init, which imports `.runs` -> `worker` -> `deerflow.workspace_changes` back for `capture_workspace_snapshot` and friends, so importing `.api` as the package's first statement failed with ImportError while those names were still unbound. Resolve the re-export lazily via a module-level `__getattr__`, the pattern `deerflow/subagents/__init__.py` already uses.
This commit is contained in:
parent
35f6a98cd9
commit
65a186187d
@ -1,4 +1,3 @@
|
||||
from .api import get_workspace_changes_response
|
||||
from .diff import compare_snapshots, get_changed_output_paths, get_changed_paths
|
||||
from .recorder import capture_workspace_snapshot, record_workspace_changes
|
||||
from .scanner import scan_workspace_roots
|
||||
@ -32,3 +31,17 @@ __all__ = [
|
||||
"record_workspace_changes",
|
||||
"scan_workspace_roots",
|
||||
]
|
||||
|
||||
|
||||
def __getattr__(name: str):
|
||||
# `.api` reads `deerflow.runtime.user_context` for the AUTO sentinel, and
|
||||
# importing that package runs `deerflow.runtime`'s init, which imports
|
||||
# `.runs` -> `worker` -> this package. Resolving it lazily keeps this
|
||||
# package importable as a process's first import instead of failing with
|
||||
# ImportError while its own names are still unbound.
|
||||
if name == "get_workspace_changes_response":
|
||||
from .api import get_workspace_changes_response
|
||||
|
||||
globals()[name] = get_workspace_changes_response
|
||||
return get_workspace_changes_response
|
||||
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
||||
|
||||
@ -72,3 +72,27 @@ def test_subagent_package_public_executor_exports_are_lazy_importable() -> None:
|
||||
)
|
||||
assert result.returncode == 0, result.stderr
|
||||
assert "SubagentExecutor SubagentResult" in result.stdout
|
||||
|
||||
|
||||
def test_workspace_changes_package_imports_standalone() -> None:
|
||||
"""The workspace-changes package must import as the process's first import.
|
||||
|
||||
``workspace_changes.api`` reads ``deerflow.runtime.user_context`` for the
|
||||
``AUTO`` sentinel, which runs ``deerflow.runtime``'s package init and imports
|
||||
``.runs`` -> ``worker`` -> ``deerflow.workspace_changes`` again. Importing
|
||||
``.api`` before this package bound its own names made that re-entrant import
|
||||
fail with ImportError whenever ``deerflow.runtime`` had not been imported
|
||||
yet.
|
||||
"""
|
||||
result = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
"-c",
|
||||
"import deerflow.workspace_changes as w; print(w.scan_workspace_roots.__name__, w.get_workspace_changes_response.__name__)",
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
env=_gateway_import_env(),
|
||||
)
|
||||
assert result.returncode == 0, result.stderr
|
||||
assert "scan_workspace_roots get_workspace_changes_response" in result.stdout
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user