Skip to content

isolated_filesystem contextmanager issues #609

@Karrenbelt

Description

@Karrenbelt

auto_dev/auto_dev/utils.py

Lines 191 to 211 in 18db783

@contextmanager
def isolated_filesystem(copy_cwd: bool = False):
"""Context manager to create an isolated file system.
And to navigate to it and then to clean it up.
"""
original_path = Path.cwd()
with tempfile.TemporaryDirectory(dir=tempfile.gettempdir()) as temp_dir:
temp_dir_path = Path(temp_dir).resolve()
os.chdir(temp_dir_path)
if copy_cwd:
# we copy the content of the original directory into the temporary one
for file_name in os.listdir(original_path):
if file_name == "__pycache__":
continue
file_path = Path(original_path, file_name)
if file_path.is_file():
shutil.copy(file_path, temp_dir_path)
elif file_path.is_dir():
shutil.copytree(file_path, Path(temp_dir, file_name))
yield str(Path(temp_dir_path))
os.chdir(original_path)

The design of this context manager is problematic in more ways than one:

  • copying is slow
  • sys.path not modified
  • cached imports; cannot import newly scaffolded modules for testing
  • changing directory, but not restoring properly (no finally clause)
  • and many more!

And if all of that is not enough, let me show you something I have witnessed before and again now. When i use this fixture (or rather a derivative) and place a breakpoint in the test to debug (here after first assert result)

def test_scaffold_protocol(cli_runner, dummy_agent_tim):
"""Test scaffold protocol."""
path = Path.cwd() / ".." / "tests" / "data" / "dummy_protocol.yaml"
command = ["adev", "scaffold", "protocol", str(path)]
runner = cli_runner(command)
result = runner.execute()
assert result, runner.output
assert runner.return_code == 0, result.output
assert "New protocol scaffolded" in runner.output
protocol = read_protocol(str(path))
original_content = path.read_text(encoding=DEFAULT_ENCODING)
readme_path = dummy_agent_tim / "protocols" / protocol.metadata["name"] / "README.md"
assert original_content in readme_path.read_text(encoding=DEFAULT_ENCODING)

and check where the hell i am since i seem unable to access local variables, I get

(Pdb) __file__
'/home/zarathustra/.cache/pypoetry/virtualenvs/autonomy-dev-IM6WInhx-py3.11/lib/python3.11/site-packages/_pytest/logging.py'

amazing!

Turns out test was just updated to pass again. So I go in, place breakpoint and check where i end up now!

(Pdb) __file__
'/home/zarathustra/Projects/auto_dev/auto_dev/cli_executor.py'

that is amazing! I wonder where we'll end up next time we make some changes...

Alright enough sarcasm. It is time to replace the isolated_filesystem with something better. I have gone over various designs for this and found all of them to be faulty to a degree, I will share some implementations i tried below

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions