monkeyfs 0.2.1__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/PKG-INFO +1 -1
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/conformance.py +10 -1
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/mount.py +2 -1
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/virtual.py +10 -5
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs.egg-info/PKG-INFO +1 -1
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/pyproject.toml +1 -1
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_directory_ops.py +48 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_open_optional.py +1 -1
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/LICENSE +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/README.md +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/__init__.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/base.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/context.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/isolated.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/patching/__init__.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/patching/core.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/patching/fdtable.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/patching/install.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/patching/patches.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/py.typed +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/readonly.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs/virtualfile.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs.egg-info/SOURCES.txt +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs.egg-info/dependency_links.txt +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs.egg-info/requires.txt +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/monkeyfs.egg-info/top_level.txt +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/setup.cfg +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_bulk_operations.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_conformance.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_expanduser.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_fd_emulation.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_finalization_and_invalidate.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_isolated.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_lazy_binary_read.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_metadata.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_mount.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_patching.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_patching_pathlib.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_patching_safe_paths.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_protocol.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_ranged_read.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_readonly.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_symlink_entries.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_vfs_optional.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_vfs_size_limit.py +0 -0
- {monkeyfs-0.2.1 → monkeyfs-0.2.2}/tests/test_virtual.py +0 -0
|
@@ -212,12 +212,21 @@ def _check_listing_paths(fs: Any, scratch: str) -> None:
|
|
|
212
212
|
f"{absolute.get('probe.bin')!r}",
|
|
213
213
|
)
|
|
214
214
|
|
|
215
|
-
|
|
215
|
+
entries = fs.list_detailed(scratch, True)
|
|
216
|
+
deep = [info.path for info in entries]
|
|
216
217
|
_require(
|
|
217
218
|
f"{scratch}/nested/leaf.bin" in deep,
|
|
218
219
|
f"a recursive list_detailed({scratch!r}) must name a nested entry "
|
|
219
220
|
f"{scratch + '/nested/leaf.bin'!r}, got {deep!r}",
|
|
220
221
|
)
|
|
222
|
+
for info in entries:
|
|
223
|
+
_require(
|
|
224
|
+
info.name == info.path.rsplit("/", 1)[-1],
|
|
225
|
+
f"list_detailed(...).name is the entry's own name, the last "
|
|
226
|
+
f"component of its path, at every depth: for path "
|
|
227
|
+
f"{info.path!r} expected {info.path.rsplit('/', 1)[-1]!r}, "
|
|
228
|
+
f"got {info.name!r}",
|
|
229
|
+
)
|
|
221
230
|
|
|
222
231
|
start = fs.getcwd()
|
|
223
232
|
fs.chdir(scratch)
|
|
@@ -285,10 +285,11 @@ class MountFS:
|
|
|
285
285
|
for name in names:
|
|
286
286
|
full_abs = f"{norm}/{name}" if norm else f"/{name}"
|
|
287
287
|
display = f"{user_prefix}/{name}" if user_prefix != "." else name
|
|
288
|
+
basename = name.rsplit("/", 1)[-1]
|
|
288
289
|
meta = self.stat(full_abs)
|
|
289
290
|
result.append(
|
|
290
291
|
FileInfo(
|
|
291
|
-
name=
|
|
292
|
+
name=basename,
|
|
292
293
|
path=display,
|
|
293
294
|
size=meta.size,
|
|
294
295
|
created_at=meta.created_at,
|
|
@@ -1325,7 +1325,10 @@ class VirtualFS:
|
|
|
1325
1325
|
recursive: If True, list all nested files and directories.
|
|
1326
1326
|
|
|
1327
1327
|
Returns:
|
|
1328
|
-
List of FileInfo objects sorted by
|
|
1328
|
+
List of FileInfo objects sorted by path relative to the queried
|
|
1329
|
+
directory, so a directory precedes its contents. ``name`` is the
|
|
1330
|
+
entry's own name, the last component of ``path``, at every depth;
|
|
1331
|
+
it is not what the list is ordered by.
|
|
1329
1332
|
|
|
1330
1333
|
Example:
|
|
1331
1334
|
>>> files = vfs.list_detailed("/shared")
|
|
@@ -1350,7 +1353,9 @@ class VirtualFS:
|
|
|
1350
1353
|
internal_path = f"{base}/{name}" if base else name
|
|
1351
1354
|
absolute = "/" + internal_path
|
|
1352
1355
|
|
|
1353
|
-
# Display path preserves the user's queried prefix
|
|
1356
|
+
# Display path preserves the user's queried prefix; the name
|
|
1357
|
+
# is the last component alone, whatever depth the entry sits at.
|
|
1358
|
+
basename = name.rsplit("/", 1)[-1]
|
|
1354
1359
|
display = f"{user_prefix}/{name}" if user_prefix != "." else name
|
|
1355
1360
|
|
|
1356
1361
|
meta = self._meta_at(internal_path)
|
|
@@ -1360,7 +1365,7 @@ class VirtualFS:
|
|
|
1360
1365
|
now = self._now_iso()
|
|
1361
1366
|
result.append(
|
|
1362
1367
|
FileInfo(
|
|
1363
|
-
name=
|
|
1368
|
+
name=basename,
|
|
1364
1369
|
path=display,
|
|
1365
1370
|
size=0,
|
|
1366
1371
|
created_at=meta.created_at if meta is not None else now,
|
|
@@ -1371,7 +1376,7 @@ class VirtualFS:
|
|
|
1371
1376
|
elif meta is not None:
|
|
1372
1377
|
result.append(
|
|
1373
1378
|
FileInfo(
|
|
1374
|
-
name=
|
|
1379
|
+
name=basename,
|
|
1375
1380
|
path=display,
|
|
1376
1381
|
size=meta.size,
|
|
1377
1382
|
created_at=meta.created_at,
|
|
@@ -1385,7 +1390,7 @@ class VirtualFS:
|
|
|
1385
1390
|
now = self._now_iso()
|
|
1386
1391
|
result.append(
|
|
1387
1392
|
FileInfo(
|
|
1388
|
-
name=
|
|
1393
|
+
name=basename,
|
|
1389
1394
|
path=display,
|
|
1390
1395
|
size=len(content),
|
|
1391
1396
|
created_at=now,
|
|
@@ -466,3 +466,51 @@ class TestImplicitDirectories:
|
|
|
466
466
|
assert vfs.list("/") == ["pkg", "top.py"]
|
|
467
467
|
assert vfs.list("pkg") == ["__init__.py", "sub", "utils.py"]
|
|
468
468
|
assert vfs.list("pkg/sub") == ["mod.py"]
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
# -- list_detailed().name is the entry's own name at every depth ---------------
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
def _nested_tree(fs):
|
|
475
|
+
fs.makedirs("/probe/sub")
|
|
476
|
+
fs.write("/probe/one.txt", b"1")
|
|
477
|
+
fs.write("/probe/sub/two.txt", b"2")
|
|
478
|
+
return fs
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
def _names_and_paths(fs):
|
|
482
|
+
# The sequence as returned, not a sorted copy: every backend orders a
|
|
483
|
+
# recursive listing by path relative to the queried directory, so a
|
|
484
|
+
# directory precedes its contents, and a backend that drifts from
|
|
485
|
+
# that order fails here rather than being tidied into agreement.
|
|
486
|
+
return [(i.name, i.path) for i in fs.list_detailed("/probe", recursive=True)]
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
def test_virtualfs_recursive_listing_names_are_basenames():
|
|
490
|
+
from monkeyfs import VirtualFS
|
|
491
|
+
|
|
492
|
+
assert _names_and_paths(_nested_tree(VirtualFS({}))) == [
|
|
493
|
+
("one.txt", "/probe/one.txt"),
|
|
494
|
+
("sub", "/probe/sub"),
|
|
495
|
+
("two.txt", "/probe/sub/two.txt"),
|
|
496
|
+
]
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
def test_mountfs_recursive_listing_names_are_basenames():
|
|
500
|
+
from monkeyfs import MountFS, VirtualFS
|
|
501
|
+
|
|
502
|
+
assert _names_and_paths(_nested_tree(MountFS(VirtualFS({})))) == [
|
|
503
|
+
("one.txt", "/probe/one.txt"),
|
|
504
|
+
("sub", "/probe/sub"),
|
|
505
|
+
("two.txt", "/probe/sub/two.txt"),
|
|
506
|
+
]
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
def test_isolatedfs_recursive_listing_names_are_basenames(tmp_path):
|
|
510
|
+
from monkeyfs import IsolatedFS
|
|
511
|
+
|
|
512
|
+
assert _names_and_paths(_nested_tree(IsolatedFS(str(tmp_path)))) == [
|
|
513
|
+
("one.txt", "/probe/one.txt"),
|
|
514
|
+
("sub", "/probe/sub"),
|
|
515
|
+
("two.txt", "/probe/sub/two.txt"),
|
|
516
|
+
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|