Skip to content

FileTree & VirtualFileTree

The filetree and virtual modules provide a flexible, Pythonic API for representing, manipulating, and writing file and directory trees in memory or on disk. They support both real and virtual filesystems, making them ideal for code generation, testing, and complex file operations.


Why?

Managing complex directory structures and file operations in Python often leads to repetitive, error-prone code. The FileTree and VirtualFileTree classes abstract these patterns, allowing you to build, merge, and validate file trees with ease—without touching the disk until you want to.

from escudeiro.ds.filetree import FileTree

with FileTree("/tmp/myproject") as tree:
    tree.virtual.create_py_file("main", content="print('Hello')")
    tree.virtual.create_dir("subdir")
    tree.virtual.create_text_file("README.md", content="# My Project")
# Files are written to disk on exit

Features

  • In-memory virtual file trees (VirtualFileTree)
  • Disk-backed file trees (FileTree)
  • Easy file and directory creation (including Python files, text files, and __init__.py)
  • Context manager support for atomic writes
  • Merging and composition of trees
  • Validation for permissions and conflicts
  • Type-safe and dataclass-friendly

Usage

Creating a Virtual File Tree

from escudeiro.ds.filetree.virtual import VirtualFileTree

vt = VirtualFileTree.from_basename("myproject")
vt.create_py_file("main", content="print('Hello')")
vt.create_dir("subdir")
vt.create_text_file("README.md", content="# My Project")

Writing to Disk with FileTree

from escudeiro.ds.filetree import FileTree

with FileTree("/tmp/myproject") as tree:
    tree.merge(vt)  # Merge a VirtualFileTree
    # Or create files directly:
    tree.virtual.create_init_file("subdir")
# Files are written to disk on exit

Using Context Managers

with FileTree("/tmp/demo") as tree:
    with tree.virtual.virtual_context("nested") as vt:
        vt.create_text_file("file.txt", content="data")
    # Changes are merged automatically

Merging Trees

tree1 = VirtualFileTree.from_basename("pkg1")
tree1.create_py_file("a")

tree2 = VirtualFileTree.from_basename("pkg2")
tree2.create_py_file("b")

tree1.merge(tree2)  # pkg2 becomes a subfolder of pkg1

API Reference

FileTree

class FileTree:
    def __init__(self, base_dir: Path)
    def merge(self, tree: FileTree | VirtualFileTree, *path: str) -> None
    def write(self) -> None
    def validate(self) -> None
    def __enter__(self) -> Self
    def __exit__(self, *exc_info)
    @property
    def virtual(self) -> VirtualFileTree
  • Description: Represents a file tree rooted at a real directory. Supports merging, validation, and atomic writes.

VirtualFileTree

class VirtualFileTree:
    def __init__(self, root: FsNode)
    @classmethod
    def from_basename(cls, name: str) -> Self
    def create_py_file(self, filename, *path, private=False, dunder=False, content="", append=False)
    def create_text_file(self, filename, *path, content="", encoding="utf-8", append=False)
    def create_init_file(self, *path, content="", append=False)
    def create_dir(self, dirname, *path)
    def merge(self, vt: VirtualFileTree, *path: str) -> None
    def virtual_context(self, dirname: str, *path: str)
    def get_path(self, pathname: str, *path: str) -> FsNode
    def __parse_dict__(self, by_alias: bool) -> dict
  • Description: Represents an in-memory file tree. Supports file and directory creation, merging, and context management.

Utilities

  • merge(tree, *path): Merge another tree at the given path.
  • virtual_context(dirname, *path): Context manager for isolated modifications.
  • validate(): Checks for permission and path conflicts before writing.
  • __parse_dict__(): Returns a nested dictionary representation of the tree.

Notes

  • Use VirtualFileTree for in-memory operations and composition.
  • Use FileTree to write to disk, with context manager support for atomicity.
  • Merging trees will raise on conflicts (e.g., file/folder name clashes).
  • All file and directory creation methods accept arbitrary subpaths.

See Also