Coverage for dirdict.py: 100%

48 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-10-14 16:51 +0000

1from pathlib import Path 

2from typing import Any, Union, Iterator 

3 

4 

5class DirDict: 

6 path: Path 

7 

8 def __init__(self, path: str | Path = Path(".")): 

9 self.path = path if isinstance(path, Path) else Path(path) 

10 if not self.path.exists(): 

11 self.path.mkdir() 

12 if not self.path.is_dir(): 

13 raise EnvironmentError("DirDict path must be a directory or non-existing") 

14 

15 def __setitem__(self, name: str | Path, item: bytes): 

16 with open(self.path / name, "wb") as f: 

17 f.write(item) 

18 

19 def __getitem__(self, name: str | Path) -> Union[bytes, "DirDict"]: 

20 filepath = self.path / name 

21 if filepath.is_dir(): 

22 return DirDict(filepath) 

23 with open(filepath, "rb") as f: 

24 return f.read() 

25 

26 def get(self, key: str | Path, default: Any = None) -> Any: 

27 if key in self: 

28 return self[key] 

29 else: 

30 return default 

31 

32 def __contains__(self, key: str | Path) -> bool: 

33 if isinstance(key, Path): 

34 return key.resolve().exists() 

35 else: 

36 return key in self.keys() 

37 

38 def __truediv__(self, other: str | Path) -> "DirDict": 

39 return DirDict(path=self.path / other) 

40 

41 def __eq__(self, other: Any) -> bool: 

42 if isinstance(other, DirDict): 

43 return other.path.resolve() == self.path.resolve() 

44 return False 

45 

46 def __delitem__(self, name: str | Path) -> None: 

47 targetpath = self.path / name 

48 if targetpath.is_dir(): 

49 targetpath.rmdir() 

50 else: 

51 targetpath.unlink() 

52 

53 def __iter__(self) -> Iterator[str]: 

54 return self.keys() 

55 

56 def keys(self) -> Iterator[str]: 

57 return (p.name for p in self.path.glob("*")) 

58 

59 def values(self) -> Iterator[Union[bytes, "DirDict"]]: 

60 return (self[p.name] for p in self.path.glob("*")) 

61 

62 def items(self) -> Iterator[tuple[str, Union[bytes, "DirDict"]]]: 

63 return ((p.name, self[p.name]) for p in self.path.glob("*")) 

64 

65 def __hash__(self) -> int: 

66 return hash(self.path.resolve())