Flexible recursive directory iterator
scantree (version 0.0.4) is a Python library that provides a flexible recursive directory iterator, combining the efficiency of `os.scandir` with the wildcard matching capabilities of `glob.glob("**", recursive=True)`. It offers an in-memory representation of the file-tree, efficient access to `os.DirEntry` properties, and includes features like detection and handling of cyclic symlinks. The library is actively maintained with an infrequent release cadence.
Warnings
- breaking Support for Python 2 was dropped in `scantree` version 0.0.2. Users on Python 2.x environments must upgrade to Python 3.8+ to use current versions of the library.
- gotcha While `scantree` aims for Windows compatibility (with fixes in v0.0.4), known limitations exist, particularly concerning cyclic symlinks. Users heavily relying on complex symlink structures on Windows might encounter unexpected behavior.
- gotcha The `path.relative` property of `DirEntry` objects returned by `scantree` is relative to the *root path provided to the `scantree` function*, not necessarily the current working directory. Be explicit with your scan root to avoid confusion, especially when moving or combining paths.
Install
-
pip install scantree
Imports
- scantree
from scantree import scantree
- RecursionFilter
from scantree import RecursionFilter
Quickstart
import tempfile
import shutil
from pathlib import Path
from scantree import scantree, RecursionFilter
# Create a temporary directory structure for demonstration
temp_dir_path = Path(tempfile.mkdtemp())
try:
# Create subdirectories and files
(temp_dir_path / "dir1").mkdir()
(temp_dir_path / "dir2" / "sub_dir").mkdir(parents=True)
(temp_dir_path / "dir1" / "file1.txt").touch()
(temp_dir_path / "dir1" / "file2.log").touch()
(temp_dir_path / "dir2" / "sub_dir" / "file3.txt").touch()
(temp_dir_path / "root_file.txt").touch()
print(f"Created temporary directory: {temp_dir_path}")
# Scan the directory for all .txt files recursively
# The first argument to scantree is the root path to scan.
# RecursionFilter can specify match patterns, ignore patterns, etc.
tree = scantree(temp_dir_path, RecursionFilter(match=['*.txt']))
print("\nRelative paths of .txt files found:")
for path_obj in tree.filepaths():
print(path_obj.relative) # path.relative is relative to the scan root
# Access metadata of directory entries
print("\nExample: Accessing metadata for a directory entry")
if tree.directories:
first_dir_node = tree.directories[0]
print(f"First directory found (absolute path): {first_dir_node.path.absolute}")
print(f"Is symlink: {first_dir_node.path.is_symlink()}")
finally:
# Clean up the temporary directory
shutil.rmtree(temp_dir_path)
print(f"\nCleaned up temporary directory: {temp_dir_path}")