Skip to main content

Object-oriented paths

Project description

pathable

Package version Python versions License

About

Pathable provides a small set of "path" objects for traversing hierarchical data (mappings, lists, and other subscriptable trees) using a familiar path-like syntax.

It’s especially handy when you want to:

  • express deep lookups as a single object (and pass it around)
  • build paths incrementally (p / "a" / 0 / "b")
  • safely probe (exists(), get(...)) or strictly require segments (//)

Key features

  • Intuitive path-based navigation for nested data (e.g., dicts/lists)
  • Pluggable accessor layer for custom backends
  • Pythonic, chainable API for concise and readable code
  • Per-instance (bounded LRU) cached lookup accessor for repeated reads of the same tree

Quickstart

from pathable import LookupPath

data = {
    "parts": {
        "part1": {"name": "Part One"},
        "part2": {"name": "Part Two"},
    }
}

root = LookupPath.from_lookup(data)

name = (root / "parts" / "part2" / "name").read_value()
assert name == "Part Two"

Usage

from pathable import LookupPath

data = {
    "parts": {
        "part1": {"name": "Part One"},
        "part2": {"name": "Part Two"},
    }
}

p = LookupPath.from_lookup(data)

# Concatenate path segments with /
parts = p / "parts"

# Check membership (mapping keys or list indexes)
assert "part2" in parts

# Read a value
assert (parts / "part2" / "name").read_value() == "Part Two"

# Iterate children as paths
for child in parts:
    print(child, child.read_value())

# Work with keys/items
print(list(parts.keys()))
print({k: v.read_value() for k, v in parts.items()})

# Safe access
print(parts.get("missing", default=None))

# Strict access (raises KeyError if missing)
must_exist = parts // "part2"

# "Open" yields the current value as a context manager
with parts.open() as parts_value:
    assert isinstance(parts_value, dict)

# Optional metadata
print(parts.stat())

Filesystem example

Pathable can also traverse the filesystem via an accessor.

from pathlib import Path

from pathable import FilesystemPath

root_dir = Path(".")
p = FilesystemPath.from_path(root_dir)

readme = p / "README.md"
if readme.exists():
    content = readme.read_value()  # bytes
    print(content[:100])

Core concepts

  • BasePath is a pure path (segments + separator) with / joining.
  • AccessorPath is a BasePath bound to a NodeAccessor, enabling read_value(), exists(), keys(), iteration, etc.
  • FilesystemPath is an AccessorPath specialized for filesystem objects.
  • LookupPath is an AccessorPath specialized for mapping/list lookups.

Notes on parsing:

  • A segment like "a/b" is split into parts using the separator.
  • None segments are ignored.
  • "." segments are ignored (relative no-op).
  • Operations like relative_to() and is_relative_to() also respect the instance separator.

Equality and ordering:

  • BasePath equality, hashing, and ordering are all based on both separator and parts.
  • Ordering is separator-sensitive and deterministic, even when parts mix types (e.g. ints and strings).
  • Path parts are type-sensitive (0 is not equal to "0").

Lookup caching:

  • LookupPath uses a per-instance LRU cache (default maxsize: 128) on its accessor.
  • You can control it via path.accessor.clear_cache(), path.accessor.disable_cache(), and path.accessor.enable_cache(maxsize=...).
  • path.accessor.node is immutable; to point at a different tree, create a new LookupPath/accessor.

Installation

Recommended way (via pip):

pip install pathable

Alternatively you can download the code and install from the repository:

pip install -e git+https://github.com/p1c2u/pathable.git#egg=pathable

Benchmarks

Benchmarks live in tests/benchmarks/ and produce JSON reports.

Local run (recommended as modules):

poetry run python -m tests.benchmarks.bench_parse --output reports/bench-parse.json
poetry run python -m tests.benchmarks.bench_lookup --output reports/bench-lookup.json

Quick sanity run:

poetry run python -m tests.benchmarks.bench_parse --quick --output reports/bench-parse.quick.json
poetry run python -m tests.benchmarks.bench_lookup --quick --output reports/bench-lookup.quick.json

Compare two results (fails if candidate is >20% slower in any scenario):

poetry run python -m tests.benchmarks.compare_results \
    --baseline reports/bench-before.json \
    --candidate reports/bench-after.json \
    --tolerance 0.20

CI (on-demand):

  • GitHub Actions workflow Benchmarks runs via workflow_dispatch and uploads the JSON artifacts.

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

pathable-0.5.0b3.tar.gz (16.4 kB view details)

Uploaded Source

Built Distribution

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

pathable-0.5.0b3-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

File details

Details for the file pathable-0.5.0b3.tar.gz.

File metadata

  • Download URL: pathable-0.5.0b3.tar.gz
  • Upload date:
  • Size: 16.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pathable-0.5.0b3.tar.gz
Algorithm Hash digest
SHA256 bc3cdd374e3ffcaae54618d4f74306f68f51dfabb0d7be7f6a18931aea7b07b2
MD5 3df397151f3a298dbcc1e58e827b2e68
BLAKE2b-256 bda373d55e01c4ec6ba13caff7b4f8b940926bf87e08b6733804881d6e71dea8

See more details on using hashes here.

Provenance

The following attestation bundles were made for pathable-0.5.0b3.tar.gz:

Publisher: python-publish.yml on p1c2u/pathable

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

File details

Details for the file pathable-0.5.0b3-py3-none-any.whl.

File metadata

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

File hashes

Hashes for pathable-0.5.0b3-py3-none-any.whl
Algorithm Hash digest
SHA256 e19c41a84b22afc24e49d7072e59e7a2e08d0f8542c6c11fe0ad7ba58b782c90
MD5 350a898f28c3ffce4c0945ccebe7d8ec
BLAKE2b-256 cba1f38c7def6c5918a12f0c480ee673d68bb5834ba7ee1c62052706635e69fa

See more details on using hashes here.

Provenance

The following attestation bundles were made for pathable-0.5.0b3-py3-none-any.whl:

Publisher: python-publish.yml on p1c2u/pathable

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