1#!/usr/bin/env python3
2
3"""Patch the pathlib Path which has no equivalent to expanduser or expandvars."""
4
5import os
6import shutil
7import contextlib
8from datetime import datetime
9from pathlib import PurePath
10from pathlib import Path
11
12# don't import anything from chart here as we are imported from settings
13
14def expand(self):
15 """Pathlin has no equivalent function to expand ~ and $ markup."""
16 return self.__class__(
17 os.path.expanduser(
18 os.path.expandvars(
19 str(self))))
20
21Path.expand = expand
22
23
24def copy(self, target):
25 """Pathlib lacks any copy function (!)."""
26 # I'm sure shutil.copy used to work when `dst` was a directory.
27 # Apparently it doesn't though.
28 if not isinstance(target, Path):
29 target = Path(target)
30
31 if target.is_dir():
32 shutil.copyfile(str(self), str(target.joinpath(self.name)))
33
34 else:
35 shutil.copyfile(str(self), str(target))
36
37Path.copy = copy
38
39
40def rmtree(self, ignore_errors=False):
41 """Pathlib has normal unlink but no recursive delete."""
42 shutil.rmtree(str(self), ignore_errors)
43
44Path.rmtree = rmtree
45
46
47def rename(self, dst):
48 """Pathlib default move command doesn't allow `dst` to be a directory name."""
49 shutil.move(str(self), str(dst))
50
51Path.rename = rename
52
53
54def size(self):
55 """File or dir size in bytes."""
56 return self.stat().st_size
57
58Path.size = size
59
60def mtime(self):
61 """Read file last modification time."""
62 return datetime.utcfromtimestamp(self.stat().st_mtime)
63
64Path.mtime = mtime
65
66@contextlib.contextmanager
67def chdir(self):
68 """Change directory. Can be used as a context manager to return to old dir after block.
69
70 >> begin = os.getcwd()
71 >> print('Am starting in ', begin)
72 >> with Path('/tmp').chdir():
73 >> print(' Am now in ', os.getcwd())
74 >> assert os.getcwd() == begin
75 """
76 old_dir = os.getcwd()
77 os.chdir(str(self))
78 try:
79 yield
80 finally:
81 os.chdir(old_dir)
82
83Path.chdir = chdir
84
85
86# Set up child() as an better named alias to joinpath()
87Path.child = Path.joinpath