Skip to main content

A lightweight Python library to persistently add or remove directories from PATH.

Project description

pathreg

Persistently add or remove directories from PATH on Windows, Linux, and macOS.

Installation

pip install pathreg

CLI Usage

pathreg add /some/directory             # append (default)
pathreg add --index 0 /some/directory   # insert at position 0
pathreg prepend /some/directory         # insert at front
pathreg remove /some/directory
pathreg move /some/directory 0          # move existing entry to position 0
pathreg set /a /b /c                    # replace PATH with given directories
pathreg list
pathreg list --filter exists
pathreg list --filter writable
pathreg list --filter readable
pathreg list --filter is_symlink
pathreg list --filter is_real
pathreg list --filter is_empty
pathreg list --filter is_nonempty
pathreg list --filter has_executables
pathreg list --filter is_user
pathreg list --filter is_system
pathreg list --filter is_venv
pathreg list --filter has_executable --filter-arg python
pathreg list --filter depth      --filter-arg 3
pathreg list --filter min_depth  --filter-arg 2
pathreg list --filter max_depth  --filter-arg 4
pathreg list --filter newer_than --filter-arg 7     # days
pathreg list --filter older_than --filter-arg 30
pathreg list --filter contains   --filter-arg usr
pathreg list --filter matches    --filter-arg "^/usr"
pathreg list --filter startswith --filter-arg /usr
pathreg count                           # prints number of PATH entries
pathreg check /some/directory           # prints "yes" or "no"
pathreg find python                     # prints full path or "not found"
pathreg find-all python                 # prints all matches (shadows included), or "not found"
pathreg clean                           # removes duplicates and non-existent entries
pathreg duplicates                      # list entries that appear more than once
pathreg swap /a /b                      # swap positions of two entries
pathreg rename /old /new                # replace an entry in-place, keeping its position
pathreg save /path/to/file.txt          # write current PATH entries to a file, one per line
pathreg load /path/to/file.txt          # add entries from a file

Python API

from pathreg import (
    add_path, prepend_path, remove_path, move_path, set_path,
    list_paths, path_len, in_path, find_executable, find_all_executables,
    clean_path, diff_paths, duplicate_paths, swap_paths, rename_path,
    snapshot_path, restore_path, save_path_to_file, load_path_from_file,
    path_context,
)
from pathreg import filters

add_path("/some/directory")          # append (default); idempotent
add_path("/some/directory", index=0) # insert at position 0; idempotent
prepend_path("/some/directory")      # insert at front; idempotent
remove_path("/some/directory")       # no-op if not found
move_path("/some/directory", 0)      # move existing entry to position 0; no-op if absent
set_path(["/a", "/b", "/c"])         # replace PATH entirely
list_paths()                         # returns list[Path] of current PATH entries
list_paths(filters.exists)           # pass any callable(Path) -> bool as filter
list_paths(filters.contains("usr"))  # factory filters return a predicate
path_len()                           # returns number of PATH entries (faster than len(list_paths()))
in_path("/some/directory")           # returns True if directory is in PATH
find_executable("python")            # returns Path to first match, or None
find_all_executables("python")       # returns list[Path] of all matches (useful for spotting shadows)
clean_path()                         # removes duplicates and non-existent dirs, returns cleaned list[Path]
diff_paths(before, after)            # returns {"added": [...], "removed": [...]} comparing two PATH lists
duplicate_paths()                    # returns entries that appear more than once (does not modify PATH)
swap_paths("/a", "/b")               # swap positions of two entries in the current process
rename_path("/old", "/new")          # replace an entry in-place, keeping its position
snapshot_path()                      # returns current PATH as list[str] for later restoration
restore_path(snapshot)               # restores PATH from a snapshot_path() result
save_path_to_file("/path/file.txt")  # writes current PATH entries to a file, one per line
load_path_from_file("/path/file.txt") # adds entries from a file (idempotent)

with path_context("/tmp/mybin", "/opt/extra"):
    ...  # directories are in PATH here; PATH restored on exit (even on exception)

add_path, remove_path, move_path, and set_path modify the shell profile and the current process's PATH immediately (move_path only updates the current process).

Behavior

  • Paths are normalized: trailing separators stripped, slashes converted per platform.
  • add_path is idempotent, does nothing if the entry already exists. The optional index parameter controls insertion position (default None = append to end); supports negative indices.
  • move_path moves an existing entry to the given index in the current process PATH only; no-op if absent.
  • remove_path is a no-op if the entry is absent or the profile file does not exist.
  • list_paths reflects the current process PATH; it does not read the profile file. An optional filter predicate (Callable[[Path], bool]) narrows the results.
  • pathreg.filters provides ready-made predicates:
    • Plain: exists, writable, readable, is_symlink, is_real, is_empty, is_nonempty, has_executables, is_user, is_system, is_venv
    • Factories (return a predicate): contains(s), matches(pattern), startswith(prefix), has_executable(name), depth(n), min_depth(n), max_depth(n), newer_than(days), older_than(days)
    • Combinators: not_(pred), all_(*preds), any_(*preds)
  • in_path normalizes trailing separators before comparing, matching add_path behaviour.
  • find_executable walks PATH entries in order and returns the first regular file that is executable, or None.
  • clean_path removes non-existent directories and duplicates (resolved via symlinks) from the current process PATH in-place, and returns the cleaned list.
  • find_all_executables walks all PATH entries and returns every match, not just the first — useful for detecting shadowed binaries.
  • diff_paths(before, after) compares two list[Path] values and returns {"added": [...], "removed": [...]} — useful for debugging shell startup changes.
  • duplicate_paths returns entries that appear more than once (resolved via symlinks) without modifying PATH.
  • swap_paths(a, b) swaps the positions of two entries in the current process PATH; no-op if either is absent.
  • rename_path(old, new) replaces old with new at the same position; no-op if absent.
  • snapshot_path / restore_path save and restore PATH as a plain list[str] — useful in scripts and tests.
  • save_path_to_file / load_path_from_file write/read PATH entries one per line.
  • path_context(*directories) is a context manager that adds directories for the duration of a with block then restores PATH — works correctly even when exceptions are raised.

Platform support

Platform Persistence target
Windows HKCU\Environment via winreg; broadcasts WM_SETTINGCHANGE to notify the shell
bash ~/.bash_profile (falls back to ~/.profile if it exists)
zsh ~/.zshenv
sh ~/.profile

The active shell is detected from the SHELL environment variable.

No third-party dependencies required.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pathreg-1.0.8.tar.gz (27.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pathreg-1.0.8-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

Details for the file pathreg-1.0.8.tar.gz.

File metadata

  • Download URL: pathreg-1.0.8.tar.gz
  • Upload date:
  • Size: 27.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pathreg-1.0.8.tar.gz
Algorithm Hash digest
SHA256 d3fba465f669c1f87229bb1be5a85ce5925682abdbb667628343f72a03738123
MD5 738a1c5df18c77d46634a53497fa0d43
BLAKE2b-256 38ae425b29c075c6ed9039009ac191595df010476586d0904be0bcdb026721a2

See more details on using hashes here.

Provenance

The following attestation bundles were made for pathreg-1.0.8.tar.gz:

Publisher: publish.yml on tn3w/pathreg

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pathreg-1.0.8-py3-none-any.whl.

File metadata

  • Download URL: pathreg-1.0.8-py3-none-any.whl
  • Upload date:
  • Size: 14.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pathreg-1.0.8-py3-none-any.whl
Algorithm Hash digest
SHA256 4f6b46aab073c932aa13321c4e4eaa4c501de445551d8ce3867d89a102fd39fa
MD5 9bf85de2260d6bb9af382e9be3c237df
BLAKE2b-256 d7d7de31f391ba9bee5b6854512002232f910259f4133b86ab8c84e12c412c90

See more details on using hashes here.

Provenance

The following attestation bundles were made for pathreg-1.0.8-py3-none-any.whl:

Publisher: publish.yml on tn3w/pathreg

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page