Skip to content

Latest commit

 

History

History
206 lines (161 loc) · 8.59 KB

File metadata and controls

206 lines (161 loc) · 8.59 KB

Development Checklist

Phase 1: Pure Paths — Complete

  • PathRepr struct with lazy parsing
  • PurePath, PurePosixPath, PureWindowsPath PyO3 classes
  • Properties: parts, drive, root, anchor, parent, parents, name, suffix, suffixes, stem
  • joinpath(), with_name(), with_stem(), with_suffix(), with_segments()
  • relative_to() with walk_up kwarg (3.12+)
  • is_relative_to()
  • as_posix(), as_uri(), from_uri()
  • match() and full_match() with case_sensitive kwarg (3.13+)
  • Dunders: __str__, __repr__, __fspath__, __eq__, __hash__, __lt__
  • / operator (__truediv__, __rtruediv__)
  • Pickle / __reduce__ support
  • POSIX and Windows parsing in pure Rust
  • Glob pattern matching (fnmatch-style)
  • Vendored CPython 3.14.6 test suite runner
  • parser class attribute (posixpath / ntpath)
  • Python subclassing support via #[pyclass(subclass)]
  • 36 Rust unit tests
  • 65 Python smoke tests
  • All vendored pure-path CPython tests pass

Phase 2: Filesystem Properties — Complete

  • stat(), lstat() — returns StatResult with all metadata fields
  • exists(), is_dir(), is_file(), is_symlink()
  • is_mount(), is_junction()
  • PathInfo — cached stat result (3.12+)
  • samefile()
  • owner(), group()
  • resolve(), absolute()
  • readlink()
  • expanduser() (POSIX and Windows)
  • GIL release during all I/O syscalls
  • Path classes: Path, PosixPath, WindowsPath (concrete)

Phase 3: Filesystem Mutations & I/O — Complete

Directory Mutations

  • mkdir() with mode, parents, exist_ok
  • rmdir()
  • chmod(), lchmod()

File Mutations

  • touch() with mode, exist_ok
  • unlink() with missing_ok
  • rename(), replace()
  • symlink_to(), hardlink_to()

I/O

  • open() — delegate to Python io.open()
  • read_bytes(), read_text()
  • write_bytes(), write_text()

Directory Traversal

  • iterdir()
  • walk() with topdown, bottomup, onerror, follow_symlinks

3.14 File-Tree Operations

  • copy() — copy file or directory tree to exact target
  • copy_into() — copy into an existing directory
  • move() — move file or directory tree to exact target
  • move_into() — move into an existing directory
  • delete() — recursively delete file or directory tree
  • _delete() — CPython private-API alias for delete()

Verification

  • All vendored CPython tests pass
  • CI passes on all platforms: Linux, macOS, Windows (Python 3.10 + 3.14)

Phase 4: Glob & Pattern Matching — Complete

  • glob() with full pattern syntax: **, *, ?, [abc], [!abc]
  • rglob() with full pattern syntax
  • Brace expansion in patterns
  • case_sensitive kwarg (3.12+)
  • recurse_symlinks kwarg (3.13+)
  • Symlink loop detection for recursive globs
  • Glob iterator bridging (Rust iterator → Python iterator protocol)
  • All vendored CPython glob tests pass

Phase 5: Parity & Maintenance — Closing

Vendored CPython 3.14.6 test suite: 810 passed, 394 skipped, 0 failures. 2 active skip entries (down from 239 baseline — 237 resolved).

Feature Parity — Complete

  • Path.home(), Path.cwd() class methods
  • Pure path edge cases: name/stem/parts for empty/. paths
  • __repr__ uses dynamic class name
  • __bytes__ and bytes type validation
  • with_name()/with_stem() reject empty/reserved names
  • as_uri() percent-encoding via urllib.parse.quote
  • __eq__ matches CPython 3.14: returns NotImplemented for non-PurePath types
  • Cross-flavour equality: PurePosixPath('a') != PureWindowsPath('a')
  • Cross-flavour ordering: PurePosixPath('a') < PureWindowsPath('a') raises TypeError
  • is_reserved() method with DeprecationWarning
  • Path/PosixPath constructors accept os.PathLike objects
  • Path multi-arg constructor normalizes separators
  • relative_to() rejects .. segments
  • Subclass pickle/protocol support
  • Constructor rejects unknown kwargs with TypeError
  • PurePosixPath(PureWindowsPath(...)) cross-flavour construction
  • from_uri() Windows support (DOS drive letters, UNC, pipe notation)
  • from_uri() POSIX support
  • owner()/group() raise UnsupportedOperation on Windows-flavoured paths
  • resolve() cross-platform: canonicalize on POSIX, read_link on Windows
  • Windows symlink+.. lexical cancellation
  • absolute() drive-relative path CWD on Windows
  • Windows UNC/device/extended-path edge cases — 37 Rust unit tests covering all forms

Remaining Skips — 2 entries (both permanently unfixable)

Skip Blocker
PurePathTest.test_concrete_class PyO3 #[new] must return Self — cannot auto-dispatch PurePath('a') to PurePosixPath
PathTest.test_delete_unwritable Windows FILE_ATTRIBUTE_READONLY on directories doesn't prevent file deletion inside

Infrastructure — Complete

  • Performance benchmark suite (benchmarks/) — 84 tests, 7 categories
  • Release-mode benchmarks (make bench builds via maturin develop --release)
  • CI benchmark workflow with baseline storage and PR regression comparison
  • Published benchmark results (BENCHMARKS.md, CI step summary)
  • Automated upstream test sync workflow (scripts/sync_vendored_tests.py + make sync-vendored + weekly CI)

CI / Infrastructure

  • AGENTS.md with project overview and agent instructions
  • CLAUDE.md symlinked to AGENTS.md
  • Makefile with self-documenting make help
  • .pre-commit-config.yaml with Rust + Python hooks
  • CI workflow (.github/workflows/ci.yml) — full Python matrix (3.10-3.14) on Linux/macOS/Windows
  • CI benchmark job with baseline artifact storage and PR regression comment
  • Vendored CPython 3.14.6 test suite
  • tests/conftest.py with --windows-flavour support
  • pathlib._local shim for CPython 3.13 unpickling
  • isjunction shim for Python < 3.12
  • pathname2url(add_scheme=True) shim for Python < 3.14
  • infinite_recursion monkey-patch for Python < 3.11
  • subst_drive shim for Python < 3.14
  • Automated upstream test sync workflow

Phase 6: Performance Optimization

Detailed plan in OPTIMIZATION.md.

Current benchmark state: 14 faster, 21 slower, 4 at parity (39 benchmarks).

Goal: 0 benchmarks slower than pathlib.

Step 1: Infrastructure (prep for Wins 1-3)

  • Replace Mutex<Option<Py<PathInfo>>> with OnceLock<Py<PathInfo>>
  • Add str_cache: OnceLock<String> to PathRepr + cached __str__
  • Pre-size all Vec<u8> path builders with with_capacity

Step 2: _make_child_fast — Rust-native construction

  • Fast Rust construction with subclass-override detection
  • Wire into __truediv__, __rtruediv__, joinpath
  • Wire into parent, with_name, with_stem, with_suffix
  • Wire into relative_to, absolute, resolve, readlink
  • Wire into FS ops (rename, replace, copy, copy_into, move_, move_into, iterdir) Targeted: truediv (3.23→1.2×), parent (2.03→1.2×), joinpath (2.51→1.2×)

Step 3: Shallow Parsing — avoid full parse when not needed

  • quick_anchor_end() for POSIX and Windows
  • parent_bytes() working on raw &[u8]
  • name_bytes() working on raw &[u8]
  • Refactor property getters (parent, name, stem, suffix, suffixes) to fast path
  • Refactor mutators (with_name, with_stem, with_suffix) to fast path
  • Refactor truediv, joinpath to skip parse entirely Targeted: truediv (1.2→1.0×), parent (1.2→1.0×), joinpath (1.2→1.0×)

Step 4: Allocation Squash — inline short paths

  • Implement CompactOsString with 30-byte inline buffer
  • Swap PathRepr.raw from OsString to CompactOsString
  • Inline ParsedPath into PathRepr (remove Box) Targeted: construct_and_discard (2.98→1.1×), sizeof (2.20→1.0×)

Step 5: Iterators & Glob

  • Lazy iterdir iterator class with __next__ Targeted: iterdir (2.17→1.0×)
  • Brace-alternatives in pattern AST + single-scan glob walk Targeted: glob("{py,txt}") (4.94→1.3×)

Step 6: Polish

  • write_bytes remove data.to_vec() copy
  • read_text/write_text UTF-8 fast path
  • Cached parts tuple in PathRepr
  • Cached name/stem/suffix/suffixes in ParsedPath Targeted: parts (1.43→1.0×), str (1.71→1.0×), write_bytes (1.43→1.0×)