file
Version: 9.1.6
wexample-file wraps local file and directory paths in typed Python objects — LocalFile and LocalDirectory — so each path is always stored as a resolved absolute pathlib.Path and carries a consistent set of operations: mtime-keyed read caching, write with automatic parent creation, touch, rename, and idempotent removal. It is aimed at Python 3.10+ projects that want predictable, typed filesystem access without raw pathlib calls scattered through application code.
Table of Contents
- Installation
- Quickstart
- Tests
- Architecture
- Integration in the Suite
- Dependencies
- Versioning & Compatibility Policy
- License
- About us
- Known Limitations & Roadmap
- Status & Compatibility
- Useful Links
- Migration Notes
Installation
pip install wexample-file
Requires Python >=3.10.
Quickstart
Install the package:
pip install wexample-file
Working with a file
from wexample_file.common.local_file import LocalFile
f = LocalFile("/tmp/hello.txt")
f.write("hello, world") # creates parent dirs automatically
content = f.read() # "hello, world"
f.remove() # idempotent — no error if already gone
write creates any missing parent directories. read returns None when the file does not exist, and caches the content keyed on the file's mtime so repeated calls are cheap.
Working with a directory
from wexample_file.common.local_directory import LocalDirectory
d = LocalDirectory("/tmp/myapp/data")
d.create() # mkdir -p equivalent
d.remove() # shutil.rmtree, idempotent
Both classes accept a plain string or a pathlib.Path and always store a resolved absolute path in .path. Passing check_exists=True to either constructor raises FileNotFoundException or DirectoryNotFoundException when the path is absent.
Tests
This project uses pytest for testing and pytest-cov for code coverage analysis.
Installation
First, install the required testing dependencies:
.venv/bin/python -m pip install pytest pytest-cov
Basic Usage
Run all tests with coverage:
.venv/bin/python -m pytest --cov --cov-report=html
Common Commands
# Run tests with coverage for a specific module
.venv/bin/python -m pytest --cov=your_module
# Show which lines are not covered
.venv/bin/python -m pytest --cov=your_module --cov-report=term-missing
# Generate an HTML coverage report
.venv/bin/python -m pytest --cov=your_module --cov-report=html
# Combine terminal and HTML reports
.venv/bin/python -m pytest --cov=your_module --cov-report=term-missing --cov-report=html
# Run specific test file with coverage
.venv/bin/python -m pytest tests/test_file.py --cov=your_module --cov-report=term-missing
Viewing HTML Reports
After generating an HTML report, open htmlcov/index.html in your browser to view detailed line-by-line coverage information.
Coverage Threshold
To enforce a minimum coverage percentage:
.venv/bin/python -m pytest --cov=your_module --cov-fail-under=80
This will cause the test suite to fail if coverage drops below 80%.
Architecture
The package (wexample-file, declared in pyproject.toml) lives entirely under src/wexample_file/ and splits into four namespaces: common, mixin, enum, and exception, plus a helper module for standalone utilities. There are no services, no I/O threads, and no global state — every call is synchronous and scoped to the instance it is made on.
common — the two concrete types
src/wexample_file/common/abstract_local_item_path.py defines AbstractLocalItemPath, which extends WithPathMixin from wexample_helpers. Its __init__ accepts a str or pathlib.Path, calls .expanduser().resolve(strict=False), and stores the result in self.path. That normalisation happens once at construction; all subsequent operations compare against the resolved path. The constructor also calls _validate_existing_type() before the optional check_exists guard, so a LocalFile pointing at an existing directory is always rejected, regardless of whether existence is being asserted.
The two concrete classes each implement the two abstract methods (item_type and remove) and add their own surface:
src/wexample_file/common/local_file.py — LocalFile
Holds _cached_content: str | None and _cached_mtime_ns: int | None. Every call to read() stats the file first; if the on-disk st_mtime_ns matches the cached value the content is returned without I/O. Any write or removal operation updates — or clears — both cache fields before returning, so the cache is always coherent with what the instance last wrote. read() returns None (not an exception) when the file is absent; check_exists=True at construction time is the opt-in for eager failure. _validate_existing_type() raises NotAFileException when the path exists but is a directory.
src/wexample_file/common/local_directory.py — LocalDirectory
Has no cache. create() calls mkdir(parents=True, exist_ok=True). remove() delegates to shutil.rmtree and is idempotent. _validate_existing_type() raises NotADirectoryException when the path exists but is not a directory.
mixin — composable entry points
src/wexample_file/mixin/with_local_file_mixin.py provides WithLocalFileMixin. Any class that also inherits WithPathMixin (and therefore has get_path()) gains get_local_file(), which constructs a LocalFile lazily and caches it on _local_file; if get_path() changes between calls the stale instance is discarded and a fresh one built.
src/wexample_file/mixin/with_local_directory_mixin.py provides WithLocalDirectoryMixin. get_local_directory() constructs a fresh LocalDirectory on every call — no per-instance cache, because LocalDirectory carries no mutable state.
enum — type discriminator
src/wexample_file/enum/local_path_type.py declares LocalPathType with two members, FILE and DIRECTORY. It is returned by item_type() on each concrete class and is available for any external code that needs to branch on kind without isinstance.
exception — typed errors
All four exceptions are decorated with @base_class from wexample_helpers and use its structured field/message protocol:
- src/wexample_file/exception/file_not_found_exception.py —
FileNotFoundException(error codeFILE_NOT_FOUND), raised byLocalFilewhencheck_exists=Trueand the path is absent. - src/wexample_file/exception/directory_not_found_exception.py —
DirectoryNotFoundException(error codeDIRECTORY_NOT_FOUND), raised byLocalDirectoryunder the same condition. - src/wexample_file/exception/not_a_file_exception.py —
NotAFileException(error codeFILE_EXPECTED), raised on construction when an existing path is a directory, and onwrite()for the same reason. - src/wexample_file/exception/not_a_directory_exception.py —
NotADirectoryException(error codeDIRECTORY_EXPECTED), raised on construction when an existing path is a regular file.
The not-found pair inherits LocalPathNotFoundException from wexample_helpers; the type-mismatch pair inherits UndefinedException.
helper — standalone utilities
src/wexample_file/helper/line.py exports line_count_recursive(path, pattern="*"), which walks a directory with rglob, opens each file with errors="ignore", and sums line counts. It operates on a plain pathlib.Path rather than the typed wrappers, so it can be used independently of the rest of the package.
Call path through a LocalFile.read()
LocalFile("/some/path")—AbstractLocalItemPath.__init__resolves the path,_validate_existing_typerejects it if it is a live directory.f.read()—is_file()returnsFalse→Noneimmediately; otherwise the method stats forst_mtime_ns.- If mtime matches
_cached_mtime_nsand_cached_contentis set, the cached string is returned. - Otherwise
path.read_text(encoding=encoding)is called, followed by a second stat; both fields are updated before the method returns.
write() follows: mkdir for parents → write_text → stat → update _cached_content and _cached_mtime_ns. remove() calls unlink(missing_ok=True) and nulls both cache fields.
Tests
Tests live under tests/package/ and map directly to the source namespaces:
- tests/package/common/test_local_file.py — covers instantiation with str/Path, extension parsing, read/write/remove/touch, cache coherence edge cases, and type-rejection.
- tests/package/common/test_local_directory.py — covers instantiation,
create, recursiveremove, idempotency, and type-rejection. - tests/package/helper/test_line.py — covers empty directory, multi-file recursive count, and glob pattern filtering.
Integration in the Suite
This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.
Related Packages
The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
Visit the Wexample Suite documentation for the complete package ecosystem.
Dependencies
- attrs: >=23.1.0
- cattrs: >=23.1.0
- wexample-helpers: >=20.0.0
Versioning & Compatibility Policy
Wexample packages follow Semantic Versioning (SemVer):
- MAJOR: Breaking changes
- MINOR: New features, backward compatible
- PATCH: Bug fixes, backward compatible
We maintain backward compatibility within major versions and provide clear migration guides for breaking changes.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Free to use in both personal and commercial projects.
About us
Wexample stands as a cornerstone of the digital ecosystem — a collective of seasoned engineers, researchers, and creators driven by a relentless pursuit of technological excellence. More than a media platform, it has grown into a vibrant community where innovation meets craftsmanship, and where every line of code reflects a commitment to clarity, durability, and shared intelligence.
This packages suite embodies this spirit. Trusted by professionals and enthusiasts alike, it delivers a consistent, high-quality foundation for modern development — open, elegant, and battle-tested. Its reputation is built on years of collaboration, refinement, and rigorous attention to detail, making it a natural choice for those who demand both robustness and beauty in their tools.
Wexample cultivates a culture of mastery. Each package, each contribution carries the mark of a community that values precision, ethics, and innovation — a community proud to shape the future of digital craftsmanship.
Known Limitations & Roadmap
Current limitations and planned features are tracked in the GitHub issues.
See the project roadmap for upcoming features and improvements.
Status & Compatibility
Maturity: Production-ready
Python Support: >=3.10
OS Support: Linux, macOS, Windows
Status: Actively maintained
Useful Links
- Homepage: https://github.com/wexample/python-file
- Documentation: docs.wexample.com
- Issue Tracker: https://github.com/wexample/python-file/issues
- Discussions: https://github.com/wexample/python-file/discussions
- PyPI: pypi.org/project/wexample-file
Migration Notes
When upgrading between major versions, refer to the migration guides in the documentation.
Breaking changes are clearly documented with upgrade paths and examples.
Metadata
Release files for wexample-file 9.1.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| wexample_file-9.1.6.tar.gz | 18.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wexample_file-9.1.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.4 kB
Release files / wexample_file-9.1.6.tar.gz
| Download URL | wexample_file-9.1.6.tar.gz |
|---|---|
| Size | 18.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
827c3c1dbf47456106cc7dacab5f669979f6da61b3d7104f72d8dc4f82f640e0
|
|
BLAKE2b-256 checksum How to use checksums |
33fc12ff8d1fddf174f80cd0de3ee9d15e2d75ee55669b4a26b180f323b3b2da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.25.9 CPython/3.12.3 Linux/6.8.0-138-generic
|
Release files / wexample_file-9.1.6-py3-none-any.whl
| Download URL | wexample_file-9.1.6-py3-none-any.whl |
|---|---|
| Size | 17.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f9aae4d5b544f1dd0ac931feda6c754fcb789c8bba82b132ebc622bc3909b9be
|
|
BLAKE2b-256 checksum How to use checksums |
87509e95698a7417d706bc032f740769f6a0f7c0691ba83649ee3d615e17daf1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.25.9 CPython/3.12.3 Linux/6.8.0-138-generic
|