Skip to content

Path algebra — path_*

Pure path-string manipulation, no filesystem I/O (except the few that resolve against the running process, as documented). All functions accept a scalar, list, or pandas Series as the first argument and return tidy FsPath values.

pyrfs.path

path(*parts: PathInput, ext: str = '') -> FsPath

Construct a tidy path from parts, optionally adding an extension.

Parts are joined with / and tidied. The join is pure concatenation — an absolute later part does not reset the path, unlike os.path.join.

Parameters:

Name Type Description Default
*parts str or PathLike

Path components to join.

()
ext str

Extension to append, with or without the leading dot (one dot is guaranteed, never doubled).

''

Returns:

Type Description
FsPath

The joined, tidy path.

See Also

path_join : Join components given as a list (inverse of path_split). FsPath.truediv : The fluent / join operator.

Examples:

>>> path("foo", "bar", "a", ext="txt")
FsPath('foo/bar/a.txt')
>>> path("a/", "/b")  # concatenation, not os.path.join reset
FsPath('a/b')

pyrfs.path_wd

path_wd() -> FsPath

Return the current working directory as a tidy path.

See Also

path_abs : Anchor a relative path to the working directory.

pyrfs.path_abs

path_abs(path: str) -> FsPath

Make a path absolute against the working directory (links unresolved).

A leading ~ is expanded first. Vectorized: also accepts an iterable or pandas Series of paths.

See Also

path_real : Also resolve symlinks (canonical form). path_norm : Lexical ./.. normalization only.

Examples:

>>> path_abs("data").startswith("/")
True

pyrfs.path_real

path_real(path: str) -> FsPath

Canonicalize a path, resolving symlinks (touches the filesystem).

Vectorized: also accepts an iterable or pandas Series of paths.

See Also

path_abs : Absolute form without resolving links.

pyrfs.path_norm

path_norm(path: str) -> FsPath

Normalize . and .. components lexically (no filesystem access).

Vectorized: also accepts an iterable or pandas Series of paths.

Examples:

>>> path_norm("a/../b/./c")
FsPath('b/c')

pyrfs.path_rel

path_rel(path: str, start: PathInput = '.') -> FsPath

Return the path expressed relative to start.

Vectorized: also accepts an iterable or pandas Series of paths.

Parameters:

Name Type Description Default
path str or PathLike

The path to re-express.

required
start str or PathLike

The anchor directory (default: the working directory).

'.'
See Also

path_has_parent : Test containment instead of computing the relation. FsPath.rel_to : Fluent equivalent.

Examples:

>>> path_rel("/a/b/c", "/a")
FsPath('b/c')
>>> path_rel("/a/b", "/a/d")
FsPath('../b')

pyrfs.path_expand

path_expand(path: str) -> FsPath

Expand a leading ~ to the user's home directory.

Vectorized: also accepts an iterable or pandas Series of paths.

See Also

path_home : Build paths under the home directory directly.

pyrfs.path_home

path_home(*parts: PathInput) -> FsPath

Return the user's home directory, optionally joined with parts.

Examples:

>>> path_home("data").endswith("/data")
True

pyrfs.path_temp

path_temp(*parts: PathInput) -> FsPath

Return the session temp directory, optionally joined with parts.

See Also

pyrfs.file_temp : A unique temp file name (not just the directory).

pyrfs.path_tidy

path_tidy(path: str) -> FsPath

Tidy a path: / separators, no doubled or trailing slashes.

Every pyrfs function already returns tidy paths; use this to normalize paths from elsewhere. Vectorized: also accepts an iterable or pandas Series of paths.

Examples:

>>> path_tidy("src//a.txt/")
FsPath('src/a.txt')
>>> path_tidy("C:\\data\\x")
FsPath('C:/data/x')

pyrfs.path_split

path_split(path: str) -> list[str]

Split a tidy path into components (a leading root stays '/').

Vectorized: a list of paths yields a list of component lists.

See Also

path_join : The inverse operation. FsPath.parts : Fluent equivalent.

Examples:

>>> path_split("/usr/bin")
['/', 'usr', 'bin']
>>> path_split("a/b")
['a', 'b']

pyrfs.path_join

path_join(parts: Iterable[PathInput | Iterable[PathInput]]) -> FsPath | list[FsPath]

Join split components back into path(s) — the inverse of path_split.

Parameters:

Name Type Description Default
parts iterable

Either one sequence of components, or a sequence of such sequences (joining each one).

required
See Also

path : Variadic construction with an optional extension.

Examples:

>>> path_join(["/", "usr", "bin"])
FsPath('/usr/bin')
>>> path_join([["a", "b"], ["c", "d"]])
[FsPath('a/b'), FsPath('c/d')]

pyrfs.path_file

path_file(path: str) -> FsPath

Return the file name — the last path component.

Vectorized: also accepts an iterable or pandas Series of paths.

See Also

path_dir : The complementary directory part. FsPath.name : Fluent equivalent.

Examples:

>>> path_file("a/b/c.txt")
FsPath('c.txt')

pyrfs.path_dir

path_dir(path: str) -> FsPath

Return the directory part of a path ('.' if there is none).

Vectorized: also accepts an iterable or pandas Series of paths.

See Also

path_file : The complementary file-name part. FsPath.dir : Fluent equivalent.

Examples:

>>> path_dir("a/b/c.txt")
FsPath('a/b')
>>> path_dir("c.txt")
FsPath('.')

pyrfs.path_ext

path_ext(path: str) -> str

Return the extension without the dot ('' if none).

Dotfiles like .gitignore count as having no extension. Vectorized: also accepts an iterable or pandas Series of paths.

See Also

path_ext_set, path_ext_remove

Examples:

>>> path_ext("a.tar.gz")
'gz'
>>> path_ext(".gitignore")
''

pyrfs.path_ext_remove

path_ext_remove(path: str) -> FsPath

Remove the extension (dotfiles like .gitignore are left intact).

Vectorized: also accepts an iterable or pandas Series of paths.

Examples:

>>> path_ext_remove("d/a.tar.gz")
FsPath('d/a.tar')

pyrfs.path_ext_set

path_ext_set(path: str, ext: str) -> FsPath

Replace (or add) the extension; an empty ext removes it.

Vectorized: also accepts an iterable or pandas Series of paths.

Parameters:

Name Type Description Default
path str or PathLike

The path to modify.

required
ext str

New extension, with or without the leading dot; "" removes the current extension.

required
See Also

FsPath.with_ext : Fluent equivalent.

Examples:

>>> path_ext_set("report.md", "html")
FsPath('report.html')
>>> path_ext_set(["a.txt", "b"], "py")
[FsPath('a.py'), FsPath('b.py')]

pyrfs.path_common

path_common(paths: Iterable[PathInput]) -> FsPath

Return the longest common path prefix of paths.

Parameters:

Name Type Description Default
paths iterable of str or os.PathLike

At least one path; all absolute or all relative.

required

Raises:

Type Description
FsValueError

If paths is empty or mixes absolute and relative paths.

Examples:

>>> path_common(["a/b/c", "a/b/d"])
FsPath('a/b')

pyrfs.path_filter

path_filter(paths: Iterable[PathInput], glob: str | None = None, regexp: str | None = None, *, invert: bool = False) -> list[FsPath]

Filter paths by a glob or a regular expression (mutually exclusive).

Parameters:

Name Type Description Default
paths iterable of str or os.PathLike

Paths to filter.

required
glob str

Wildcard pattern matched against the whole path (e.g. "*.py"); mutually exclusive with regexp.

None
regexp str

Regular expression searched within the path; mutually exclusive with glob.

None
invert bool

Keep the paths that do not match.

False

Raises:

Type Description
FsValueError

If both glob and regexp are set.

See Also

pyrfs.dir_ls : Directory listing with the same filter arguments.

Examples:

>>> path_filter(["a.py", "b.txt", "src/c.py"], glob="*.py")
[FsPath('a.py'), FsPath('src/c.py')]
>>> path_filter(["a.py", "b.txt"], glob="*.py", invert=True)
[FsPath('b.txt')]

pyrfs.path_has_parent

path_has_parent(path: str, parent: PathInput) -> bool

Return whether path sits at or below parent.

Both are anchored to the working directory before comparing, so relative and absolute forms compare consistently. Vectorized: also accepts an iterable or pandas Series of paths.

See Also

path_rel : Compute the relative path instead of testing containment.

Examples:

>>> path_has_parent("/x/y", "/x")
True
>>> path_has_parent("/xy/z", "/x")
False

pyrfs.path_sanitize

path_sanitize(filename: str, replacement: str = '') -> str

Turn an untrusted string into a filename safe on all major OSes.

Removes control characters, characters illegal in filenames (/\?<>:*|"), trailing dots/spaces, and Windows-reserved device names; truncates to 255 characters. Operates on a filename, not a path — separators are stripped, not preserved.

Parameters:

Name Type Description Default
filename str

The untrusted string.

required
replacement str

What to substitute for removed characters (default: nothing).

''

Examples:

>>> path_sanitize("rep/ort:2026*")
'report2026'
>>> path_sanitize("a/b", "_")
'a_b'