lib.FcWrapper: Add a delegating file context wrapper
Add a file context that sits in front of another one and delegates every primitive call to it. The wrapper adopts the identity of the wrapped context: uri, root, chroot flag, and the chroot path composition are the wrapped context's, so a path composed by the wrapper composes identically in the wrapped context. Every primitive is forwarded to the wrapped context's primitives, which receive the already-composed path; open() and close() are forwarded to the wrapped context's public methods, so the open count is kept in one place. The point is to give derived contexts a stable base: a caching context, or any other filter, overrides the primitives it cares about and inherits the rest, instead of re-deriving the chroot bookkeeping of every method. Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v1.1.0 Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
e5656d7d18
commit
cda9e210da
1 changed files with 290 additions and 0 deletions
122
src/python/jw/pkg/lib/FcWrapper.py
Normal file
122
src/python/jw/pkg/lib/FcWrapper.py
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Iterable, override
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .base import Result, StatResult
|
||||
from .file_types import FileType
|
||||
|
||||
from .FileContext import FileContext
|
||||
|
||||
class FcWrapper(FileContext): # export
|
||||
"""A file context that delegates to a wrapped context.
|
||||
|
||||
The wrapper adopts the identity of the wrapped context: uri,
|
||||
root, chroot flag, and the chroot path composition are all the
|
||||
wrapped context's, so a path composed by the wrapper composes
|
||||
identically in the wrapped context. Every primitive call is
|
||||
forwarded to the wrapped context's primitives, which receive
|
||||
the already-composed path; open and close are forwarded to the
|
||||
wrapped context's public methods, so the open count is kept in
|
||||
one place.
|
||||
"""
|
||||
|
||||
def __init__(self, wrapped: FileContext) -> None:
|
||||
super().__init__(
|
||||
wrapped.uri,
|
||||
interactive = wrapped.interactive,
|
||||
verbose_default = wrapped.verbose_default,
|
||||
chroot = wrapped.chroot,
|
||||
)
|
||||
self.__wrapped = wrapped
|
||||
|
||||
@property
|
||||
def wrapped(self) -> FileContext:
|
||||
return self.__wrapped
|
||||
|
||||
@override
|
||||
async def _open(self) -> None:
|
||||
await self.__wrapped.open()
|
||||
|
||||
@override
|
||||
async def _close(self) -> None:
|
||||
await self.__wrapped.close()
|
||||
|
||||
@override
|
||||
async def _get(
|
||||
self, path: str, wd: str | None, throw: bool, verbose: bool | None, title: str
|
||||
) -> Result:
|
||||
return await self.__wrapped._get(path, wd, throw, verbose, title)
|
||||
|
||||
@override
|
||||
async def _put(
|
||||
self,
|
||||
path: str,
|
||||
content: bytes,
|
||||
wd: str | None,
|
||||
throw: bool,
|
||||
verbose: bool | None,
|
||||
title: str,
|
||||
owner: str | None,
|
||||
group: str | None,
|
||||
mode: str | None,
|
||||
atomic: bool,
|
||||
ftype: FileType,
|
||||
) -> Result:
|
||||
return await self.__wrapped._put(
|
||||
path,
|
||||
content,
|
||||
wd,
|
||||
throw,
|
||||
verbose,
|
||||
title,
|
||||
owner,
|
||||
group,
|
||||
mode,
|
||||
atomic,
|
||||
ftype,
|
||||
)
|
||||
|
||||
@override
|
||||
async def _unlink(self, path: str) -> None:
|
||||
await self.__wrapped._unlink(path)
|
||||
|
||||
@override
|
||||
async def _erase(self, path: str) -> None:
|
||||
await self.__wrapped._erase(path)
|
||||
|
||||
@override
|
||||
async def _rename(self, src: str, dst: str) -> None:
|
||||
await self.__wrapped._rename(src, dst)
|
||||
|
||||
@override
|
||||
async def _mkdir(self, path: str, mode: int, ftype: FileType) -> None:
|
||||
await self.__wrapped._mkdir(path, mode, ftype)
|
||||
|
||||
@override
|
||||
async def _mktemp(self, tmpl: str, directory: bool) -> str:
|
||||
return await self.__wrapped._mktemp(tmpl, directory)
|
||||
|
||||
@override
|
||||
async def _chown(self, path: str, owner: str | None, group: str | None) -> None:
|
||||
await self.__wrapped._chown(path, owner, group)
|
||||
|
||||
@override
|
||||
async def _chmod(self, path: str, mode: int) -> None:
|
||||
await self.__wrapped._chmod(path, mode)
|
||||
|
||||
@override
|
||||
async def _stat(self, path: str, follow_symlinks: bool) -> StatResult:
|
||||
return await self.__wrapped._stat(path, follow_symlinks)
|
||||
|
||||
@override
|
||||
async def _file_exists(self, path: str) -> bool:
|
||||
return await self.__wrapped._file_exists(path)
|
||||
|
||||
@override
|
||||
async def _is_dir(self, path: str, follow_symlinks: bool) -> bool:
|
||||
return await self.__wrapped._is_dir(path, follow_symlinks)
|
||||
|
||||
@override
|
||||
async def _readdir(self, path: str) -> Iterable[str]:
|
||||
return await self.__wrapped._readdir(path)
|
||||
Loading…
Reference in a new issue