lib.FileContext: Add readdir() method
FileContext offers get(), put(), unlink(), mkdir(), and stat(), but no way to list the entries of a directory, so consumers that need the names of the entries under a path in a context have no portable means to obtain them. Add readdir(), returning Iterable[str], following the _readdir() -> readdir() pattern used by the other operations: the public method chroots the path via _chroot() and delegates to the _readdir() hook, which raises NotImplementedError by default. Implement _readdir() in the context families: - Local._readdir(): os.listdir() - ExecContext._readdir(): runs ls -1A and splits the output into one entry per line; inherited by SSHClient and the other command-based contexts - Curl._readdir(): raises OSError with errno.ENOSYS Add unit tests covering Local (listing, hidden entries, missing directory) and Curl (ENOSYS). Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.87.1 Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
120100c9cb
commit
0c732672ed
4 changed files with 92 additions and 4 deletions
7
test/unit/python/jw/pkg/lib/ec/Curl/Makefile
Normal file
7
test/unit/python/jw/pkg/lib/ec/Curl/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
TOPDIR = ../../../../../../../..
|
||||
|
||||
include $(TOPDIR)/make/proj.mk
|
||||
include $(JWBDIR)/make/py-run.mk
|
||||
|
||||
all:
|
||||
test: run
|
||||
15
test/unit/python/jw/pkg/lib/ec/Curl/test.py
Normal file
15
test/unit/python/jw/pkg/lib/ec/Curl/test.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import asyncio
|
||||
import errno
|
||||
|
||||
from jw.pkg.lib.ec.Curl import Curl
|
||||
|
||||
async def run_tests() -> None:
|
||||
curl = Curl('https://example.com/')
|
||||
try:
|
||||
await curl.readdir('some/path')
|
||||
raise AssertionError('expected OSError with errno ENOSYS')
|
||||
except OSError as e:
|
||||
assert e.errno == errno.ENOSYS, e.errno
|
||||
|
||||
asyncio.run(run_tests())
|
||||
print('All Curl readdir tests passed')
|
||||
7
test/unit/python/jw/pkg/lib/ec/Local/Makefile
Normal file
7
test/unit/python/jw/pkg/lib/ec/Local/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
TOPDIR = ../../../../../../../..
|
||||
|
||||
include $(TOPDIR)/make/proj.mk
|
||||
include $(JWBDIR)/make/py-run.mk
|
||||
|
||||
all:
|
||||
test: run
|
||||
33
test/unit/python/jw/pkg/lib/ec/Local/test.py
Normal file
33
test/unit/python/jw/pkg/lib/ec/Local/test.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import asyncio
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from jw.pkg.lib.ec.Local import Local
|
||||
|
||||
async def run_tests() -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
for name in ['a', 'b', '.hidden']:
|
||||
with open(os.path.join(tmp, name), 'w') as f:
|
||||
f.write(name)
|
||||
os.mkdir(os.path.join(tmp, 'subdir'))
|
||||
|
||||
local = Local()
|
||||
entries = sorted(await local.readdir(tmp))
|
||||
assert entries == ['.hidden', 'a', 'b', 'subdir'], entries
|
||||
|
||||
# -- readdir() of a missing directory raises FileNotFoundError
|
||||
try:
|
||||
await local.readdir(os.path.join(tmp, 'missing'))
|
||||
raise AssertionError('expected FileNotFoundError')
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
# -- mkdir() in a chrooted context creates below the context root
|
||||
root = os.path.join(tmp, 'root')
|
||||
os.mkdir(root)
|
||||
chrooted = Local('local://localhost' + root, chroot = True)
|
||||
await chrooted.mkdir('sub')
|
||||
assert os.path.isdir(os.path.join(root, 'sub'))
|
||||
|
||||
asyncio.run(run_tests())
|
||||
print('All Local readdir tests passed')
|
||||
Loading…
Reference in a new issue