Metadata-Version: 2.4
Name: pathlib_next
Version: 0.5.0
Summary: Generic Path Protocol based pathlib
Project-URL: Homepage, https://github.com/jose-pr/pathlib_next/
Project-URL: Documentation, https://jose-pr.github.io/pathlib_next/
Project-URL: Issues, https://github.com/jose-pr/pathlib_next/issues
Author: Jose A
License-File: LICENSE
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.9
Provides-Extra: dev
Requires-Dist: build; extra == 'dev'
Requires-Dist: hatchling; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: twine; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs; extra == 'docs'
Requires-Dist: mkdocs-material; extra == 'docs'
Requires-Dist: mkdocstrings[python]; extra == 'docs'
Provides-Extra: http
Requires-Dist: bs4; extra == 'http'
Requires-Dist: htmllistparse; extra == 'http'
Requires-Dist: requests; extra == 'http'
Requires-Dist: uritools; extra == 'http'
Provides-Extra: sftp
Requires-Dist: paramiko; extra == 'sftp'
Requires-Dist: uritools; extra == 'sftp'
Provides-Extra: uri
Requires-Dist: uritools; extra == 'uri'
Description-Content-Type: text/markdown

# pathlib_next

[![Version](https://img.shields.io/pypi/v/pathlib_next.svg)](https://pypi.org/project/pathlib_next/)
[![Python versions](https://img.shields.io/pypi/pyversions/pathlib_next.svg)](https://pypi.org/project/pathlib_next/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Docs](https://img.shields.io/badge/docs-latest-blue.svg)](https://jose-pr.github.io/pathlib_next/)
[![CI](https://img.shields.io/github/actions/workflow/status/jose-pr/pathlib_next/test.yml)](https://github.com/jose-pr/pathlib_next/actions/workflows/test.yml)

A **robust, extensible pathlib-like base** for any resource addressable as a
path or URI. Same method names, signatures, semantics, and exception types as
`pathlib.Path` wherever a `pathlib.Path` equivalent exists -- write code once
against `Path`/`UriPath` and it works against your local disk, an in-memory
tree, an HTTP index, or an SFTP server. Every intentional divergence from
`pathlib`'s behavior is documented, not silent -- see
[`docs/divergences.md`](https://jose-pr.github.io/pathlib_next/divergences/).

## Features

| Capability | `LocalPath` | `file:` | `mem:` (`MemPath`) | `http(s):` | `sftp:` |
| --- | --- | --- | --- | --- | --- |
| Read | Yes | Yes | Yes | Yes | Yes |
| Write | Yes | Yes | Yes | No | Yes |
| List (`iterdir`) | Yes | Yes | Yes | Yes (HTML index) | Yes |
| Stat / exists / is_dir / is_file | Yes | Yes | Yes | Yes | Yes |
| `mkdir` | Yes | Yes | Yes | No | Yes |
| Delete | Yes | Yes | Yes | No | Yes |
| `rename` | Yes | Yes | No (copy+unlink fallback) | No | Yes |
| Extra required | none | none | none | `http` | `sftp` |

Every scheme shares the same `glob()`, `walk()`, `copy()`/`move()`, `rm()`
implementations -- see the full matrix and notes in
[Schemes](https://jose-pr.github.io/pathlib_next/guides/schemes/).

- **Unified path interface** across local files, in-memory paths, and
  `sftp`/`http`/`file` URIs.
- **`MemPath`** -- a lightweight virtual filesystem for mocks, tests, or
  transient storage.
- **`PathSyncer`** -- one-way checksum-driven tree sync between any two
  `Path` implementations, with dry-run and event hooks.
- **`Query`/`Source`** -- parse and serialize URL query strings and URI
  authority components.
- **Extensible two ways**: subclass `Path` directly for a custom
  non-URI resource, or subclass `UriPath` for a new URI scheme -- see
  [Extending](https://jose-pr.github.io/pathlib_next/guides/extending/).

## Installation

```bash
pip install pathlib_next
```

Optional features/extras:

| Extra/flag | Adds | Needed for |
| --- | --- | --- |
| `uri` | `uritools` | URI parsing capabilities |
| `http` | `requests`, `bs4`, `htmllistparse` | Read and list files over HTTP/HTTPS |
| `sftp` | `paramiko` | SFTP path operations and transfers |

`import pathlib_next` and `LocalPath`/`MemPath` work with no extras
installed.

## Quick start

**Local filesystem** -- drop-in `pathlib.Path`:

```python
from pathlib_next import Path

p = Path("./data") / "report.txt"
p.write_text("hello")
print(p.read_text())
```

**In-memory** (`mem:`) -- a virtual filesystem, no disk I/O:

```python
from pathlib_next.mempath import MemPath

p = MemPath("/config/settings.json")
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text('{"debug": true}')
```

**`file:`** -- the same local filesystem, addressed as a URI:

```python
from pathlib_next.uri import UriPath

p = UriPath("file:./data/report.txt")
print(p.read_text())
```

**`http(s):`** -- read files and list Apache/nginx-style directory indexes:

```python
from pathlib_next.uri import UriPath

p = UriPath("http://example.com/data/")
for child in p.iterdir():
    if child.is_file():
        print(child.name, child.stat().st_size)
```

**`sftp:`** -- same interface, over SSH:

```python
from pathlib_next.uri import UriPath

p = UriPath("sftp://user@host/var/log/app.log")
print(p.read_text())
```

## Extending

Two first-class ways to add a new path-addressable resource -- both covered
in depth, with worked examples, in
[Extending](https://jose-pr.github.io/pathlib_next/guides/extending/):

- Subclass `Path` directly for a custom, non-URI resource (`MemPath` is the
  reference exemplar).
- Subclass `UriPath` and set `__SCHEMES` for a new URI scheme (`FileUri`/
  `HttpPath`/`SftpPath` are the built-in examples).

`pathlib_next.testing.PathContract` is a reusable pytest mixin covering the
baseline contract every implementation must satisfy -- subclass it with a
`root` fixture to verify your own.

## API overview

| Module/Package | Purpose |
| --- | --- |
| `pathlib_next.path` | Base Path implementation and protocols |
| `pathlib_next.uri` | URI/URL specific path support and Query utils |
| `pathlib_next.mempath` | In-memory transient path structure |
| `pathlib_next.utils.sync` | Synchronization functions and PathSyncer class |
| `pathlib_next.testing` | `PathContract`, a pytest mixin for verifying custom implementations |

## Supported Python versions

Python >= 3.9, tested on 3.9 and 3.13 in CI (see
[`.github/workflows/test.yml`](.github/workflows/test.yml)).

## Development

```bash
pip install -e ".[dev,uri,http,sftp]"
pytest -q
```

If you maintain separate virtual environments per Python version locally
(e.g. `.venv/3.9/`, `.venv/3.13/`), run the same `pytest -q` in each --
CI does the equivalent across Python 3.9/3.13 on Linux, macOS, and Windows.

### Releasing

This project follows [Semantic Versioning](https://semver.org/) and keeps a
[`CHANGELOG.md`](CHANGELOG.md). Pushing a tag matching `v*` triggers the release
workflow: test gate → build → publish → docs deploy.

### Documentation site

MkDocs builds the API reference from `docs/`, published on every
release. To preview locally: `mkdocs serve`.

## License

MIT — see [LICENSE](LICENSE).
