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