
wend¶
Symbolic, typed, invertible filesystem paths built from Python t‑strings (3.14+).
A wend expression records how a path is built — which parts are literal, which are parameters, how values are formatted — instead of collapsing it to a string. The same expression can be resolved, partially bound, transformed structurally, matched against concrete paths, used to discover files on disk, compiled for batch resolution, and inferred from an existing directory tree.
from wend import Param, Segment, T
root = Param("root")
split = Segment("split", choices={"train", "test"})
idx = Param("idx", type=int)
shard = root / split / T(t"chunk_{idx:04d}.parquet")
>>> shard
PathExpr('{root}/{split}/chunk_{idx:04d}.parquet')
>>> shard.render(root="data", split="train", idx=7)
'data/train/chunk_0007.parquet'
>>> shard.match("data/test/chunk_0042.parquet")
Match('data/test/chunk_0042.parquet', {'root': 'data', 'split': 'test', 'idx': 42})
>>> [(m["split"], m["idx"]) for m in shard.glob(root="data")]
[('test', 0), ('train', 0), ('train', 1), ('train', 3)]
rendersubstitutes the values and applies the formatting:idx=7becomes0007.matchgoes the other way and returns typed values:idxis the integer42. It returnsNonefor a path the expression does not describe, such asdata/val/chunk_0001.parquet(valis not a declared split) ordata/test/chunk_42.parquet(not four digits).globlists only the directories the expression can reach, and yields the sameMatchobjects for the files it finds.
>>> print(shard.match("data/val/chunk_0001.parquet"))
None
>>> print(shard.match("data/test/chunk_42.parquet"))
None
Where to go¶
- Quickstart: build, render, match and glob one expression, in about ten minutes.
- How wend works: the idea behind the library, and a map of the concept pages.
Install¶
wend needs Python 3.14 or later.
pip install wend
The optional integrations are extras: wend[pydantic] for path fields on Pydantic
models, wend[fsspec] for object stores, and wend[polars] for resolving whole columns
of a DataFrame.
What an expression is for¶
| with one expression you can | using |
|---|---|
| render it with values | render, resolve, bind |
| read the values back out of a path | match |
| find the paths that exist | glob, unions, queries |
| keep its relation to other paths | rebase, sibling, cousin |
| say what must be true when it is used | conditions, Step |
| map one tree onto another | Lens |
| describe a whole project | Tree |
| recover it from an existing tree | infer |
| render it in bulk | compile, compile_many |
| record where a file came from | wend.lineage |
The API reference documents each of these.
wend grew out of the Future Paths essays, which set out what Python paths could keep track of beyond a concrete value.