Starting directories¶
A walk can start in a subdirectory and still apply the ignore-files above it. Pass the subdirectory as Walker.walk's start, relative to the directory you walk, and Mosey yields exactly what a walk of the whole directory would yield within it, without listing anything beside it.
For example, this walk yields only the files within templates/docs/guides, and still skips whatever templates/.walkignore and templates/docs/.walkignore ignore:
from mosey import Mosey
builder = Mosey()
builder.set_ignore_filename(".walkignore")
walker = builder.build()
for step in walker.walk("templates", start="docs/guides"):
print(step.relative_as_posix)
Rules¶
startis a path relative to the directory you walk, as a string or a path-like object like aPath. Its default,".", starts in the directory you walk.startcan't be absolute, have a drive, or hold.., because it has to stay beneath the directory you walk. Like the directory you walk, it can't be empty either: pass"."for that.- Mosey reads the ignore-files in the directory you walk and in every directory down to
start, just as a walk of the whole directory would on its way there, then walksstartas usual. - Mosey lists the directories above
start, to read their ignore-files and judge the names on the way down, but walks nothing besidestart. - Each step's
relative_as_posixstays relative to the directory you walk, and begins withstartas a POSIX-style path, then a forward slash. Sorelative_as_posix.removeprefix("docs/guides/")gives a path relative tostart. - When an ignore-file or pattern ignores
start, or any directory above it, the walk yields nothing, because a walk of the whole directory would never reach it. startnever goes through a symlink, because a walk never walks into one.- Like the directory you walk, a
startthat doesn't exist, or can't exist because it's beneath anything but a directory, raisesFileNotFoundError. - A
startthat's anything but a directory, like a file, a symlink, a FIFO, a socket, or a device, raisesNotADirectoryError. Mosey checks both before the walk begins. - Each name in
starthas to be spelled exactly as the file system lists it, even on macOS and Windows, where the file system itself would findDOCSfordocs. Otherwise, it doesn't exist as far as the walk is concerned, and raisesFileNotFoundError. Mosey never translates names, so they match the paths in each step'srelative_as_posix.
Example¶
Microsoft Windows
On Windows, start can use backslashes or forward slashes, like docs\guides or docs/guides, but each step's relative_as_posix begins with docs/guides/ either way. Step.path gives you each step's path in Windows' own convention.
This convention aside, Mosey supports Windows as a first-class platform. Every code change is tested on Linux, macOS, and Windows, for compatibility and feature parity.
Take a directory with these files and ignore-files:
templates/
├── .walkignore ← *.log
├── docs/
│ ├── .walkignore ← drafts/
│ ├── guides/
│ │ ├── drafts/
│ │ │ └── next.md
│ │ ├── install.md
│ │ └── install.log
│ └── index.md
└── readme.md
A walk of templates with start="docs/guides" yields only this file:
It skips docs/guides/install.log because of templates/.walkignore, and docs/guides/drafts/ because of templates/docs/.walkignore. It never lists docs/index.md or readme.md, because they're beside docs/guides, not within it.
A walk with start="docs/guides/drafts" yields nothing, because a walk of templates would never walk into docs/guides/drafts.
Checking without walking¶
To find out whether a walk can start, without walking, call Walker.check_walk_can_start with the arguments you'd pass to walk:
- It runs exactly the checks that
walkruns before the walk begins, and raises exactly whatwalkraises for them: the same exceptions, naming the same paths. - It returns
Nonewhen they pass, rather thanTrueorFalse, so you always get the real error. - It lists nothing within
start, and reads no ignore-files. So a walk that can start can still fail partway through, like when it can't list a directory deep withinstart, or can't read an ignore-file, even one abovestart. - A
startthat an ignore-file or pattern ignores passes the check, but the walk yields nothing.
Behaviour you might not expect¶
startis tidied up like aPath."docs//guides/"and"./docs/guides"both start indocs/guides, and each step'srelative_as_posixbegins withdocs/guides/.start="DOCS/Guides"doesn't start indocs/guides, even on macOS and Windows, where openingDOCS/Guideswould work. It raisesFileNotFoundError, just as.WALKIGNOREis never read as.walkignore. On macOS, the same goes for a name with an accent that's encoded differently from the one on disk, likecafétyped with a combinedéand saved with aneand a separate accent.- Errors about
startcome before the walk, but ignoring comes during it. Astartthat doesn't exist raises an error even when an ignore-file ignores a directory above it, and astartthat's ignored raises nothing: the walk just yields nothing.