pathier

1from .pathier import Pathier
2
3__all__ = ["Pathier"]
class Pathier(pathlib.Path):
 12class Pathier(pathlib.Path):
 13    """Subclasses the standard library pathlib.Path class."""
 14
 15    def __new__(cls, *args, **kwargs):
 16        if cls is Pathier:
 17            cls = WindowsPath if os.name == "nt" else PosixPath
 18        self = cls._from_parts(args)
 19        if not self._flavour.is_supported:
 20            raise NotImplementedError(
 21                "cannot instantiate %r on your system" % (cls.__name__,)
 22            )
 23        return self
 24
 25    def mkdir(self, mode: int = 511, parents: bool = True, exist_ok: bool = True):
 26        """Create this directory.
 27        Same as Path().mkdir() except
 28        'parents' and 'exist_ok' default
 29        to True instead of False."""
 30        super().mkdir(mode, parents, exist_ok)
 31
 32    def write_text(
 33        self,
 34        data: Any,
 35        encoding: Any | None = None,
 36        errors: Any | None = None,
 37        newline: Any | None = None,
 38        parents: bool = True,
 39    ):
 40        """Write data to file. If a TypeError is raised, the function
 41        will attempt to case data to a str and try the write again.
 42        If a FileNotFoundError is raised and parents = True,
 43        self.parent will be created."""
 44        write = functools.partial(
 45            super().write_text,
 46            encoding=encoding,
 47            errors=errors,
 48            newline=newline,
 49        )
 50        try:
 51            write(data)
 52        except TypeError:
 53            data = str(data)
 54            write(data)
 55        except FileNotFoundError:
 56            if parents:
 57                self.parent.mkdir(parents=True)
 58                write(data)
 59            else:
 60                raise
 61        except Exception as e:
 62            raise
 63
 64    def write_bytes(self, data: bytes, parents: bool = True):
 65        """Write bytes to file.
 66
 67        :param parents: If True and the write operation fails
 68        with a FileNotFoundError, make the parent directory
 69        and retry the write."""
 70        try:
 71            super().write_bytes(data)
 72        except FileNotFoundError:
 73            if parents:
 74                self.parent.mkdir(parents=True)
 75                super().write_bytes(data)
 76            else:
 77                raise
 78        except Exception as e:
 79            raise
 80
 81    def json_loads(self, encoding: Any | None = None, errors: Any | None = None) -> Any:
 82        """Load json file."""
 83        return json.loads(self.read_text(encoding, errors))
 84
 85    def json_dumps(
 86        self,
 87        data: Any,
 88        encoding: Any | None = None,
 89        errors: Any | None = None,
 90        newline: Any | None = None,
 91        sort_keys: bool = False,
 92        indent: Any | None = None,
 93        default: Any | None = None,
 94        parents: bool = True,
 95    ) -> Any:
 96        """Dump data to json file."""
 97        self.write_text(
 98            json.dumps(data, indent=indent, default=default, sort_keys=sort_keys),
 99            encoding,
100            errors,
101            newline,
102            parents,
103        )
104
105    def toml_loads(self, encoding: Any | None = None, errors: Any | None = None) -> Any:
106        """Load toml file."""
107        return tomlkit.loads(self.read_text(encoding, errors))
108
109    def toml_dumps(
110        self,
111        data: Any,
112        encoding: Any | None = None,
113        errors: Any | None = None,
114        newline: Any | None = None,
115        sort_keys: bool = False,
116        parents: bool = True,
117    ):
118        """Dump data to toml file."""
119        self.write_text(
120            tomlkit.dumps(data, sort_keys), encoding, errors, newline, parents
121        )
122
123    def loads(self, encoding: Any | None = None, errors: Any | None = None) -> Any:
124        """Load a json or toml file based off this instance's suffix."""
125        match self.suffix:
126            case ".json":
127                return self.json_loads(encoding, errors)
128            case ".toml":
129                return self.toml_loads(encoding, errors)
130
131    def dumps(
132        self,
133        data: Any,
134        encoding: Any | None = None,
135        errors: Any | None = None,
136        newline: Any | None = None,
137        sort_keys: bool = False,
138        indent: Any | None = None,
139        default: Any | None = None,
140        parents: bool = True,
141    ):
142        """Dump data to a json or toml file based off this instance's suffix."""
143        match self.suffix:
144            case ".json":
145                self.json_dumps(
146                    data, encoding, errors, newline, sort_keys, indent, default, parents
147                )
148            case ".toml":
149                self.toml_dumps(data, encoding, errors, newline, sort_keys, parents)
150
151    def delete(self, missing_ok: bool = True):
152        """Delete the file or folder pointed to by this instance.
153        Uses self.unlink() if a file and uses shutil.rmtree() if a directory."""
154        if self.is_file():
155            self.unlink(missing_ok)
156        elif self.is_dir():
157            shutil.rmtree(self)
158
159    def copy(
160        self, new_path: Self | pathlib.Path | str, overwrite: bool = False
161    ) -> Self:
162        """Copy the path pointed to by this instance
163        to the instance pointed to by new_path using shutil.copyfile
164        or shutil.copytree. Returns the new path.
165
166        :param new_path: The copy destination.
167
168        :param overwrite: If True, files already existing in new_path
169        will be overwritten. If False, only files that don't exist in new_path
170        will be copied."""
171        new_path = Pathier(new_path)
172        if self.is_dir():
173            if overwrite or not new_path.exists():
174                shutil.copytree(self, new_path, dirs_exist_ok=True)
175            else:
176                files = self.rglob("*.*")
177                for file in files:
178                    dst = new_path.with_name(file.name)
179                    if not dst.exists():
180                        shutil.copyfile(file, dst)
181        elif self.is_file():
182            if overwrite or not new_path.exists():
183                shutil.copyfile(self, new_path)
184        return new_path

Subclasses the standard library pathlib.Path class.

Pathier()
def mkdir(self, mode: int = 511, parents: bool = True, exist_ok: bool = True):
25    def mkdir(self, mode: int = 511, parents: bool = True, exist_ok: bool = True):
26        """Create this directory.
27        Same as Path().mkdir() except
28        'parents' and 'exist_ok' default
29        to True instead of False."""
30        super().mkdir(mode, parents, exist_ok)

Create this directory. Same as Path().mkdir() except 'parents' and 'exist_ok' default to True instead of False.

def write_text( self, data: Any, encoding: typing.Any | None = None, errors: typing.Any | None = None, newline: typing.Any | None = None, parents: bool = True):
32    def write_text(
33        self,
34        data: Any,
35        encoding: Any | None = None,
36        errors: Any | None = None,
37        newline: Any | None = None,
38        parents: bool = True,
39    ):
40        """Write data to file. If a TypeError is raised, the function
41        will attempt to case data to a str and try the write again.
42        If a FileNotFoundError is raised and parents = True,
43        self.parent will be created."""
44        write = functools.partial(
45            super().write_text,
46            encoding=encoding,
47            errors=errors,
48            newline=newline,
49        )
50        try:
51            write(data)
52        except TypeError:
53            data = str(data)
54            write(data)
55        except FileNotFoundError:
56            if parents:
57                self.parent.mkdir(parents=True)
58                write(data)
59            else:
60                raise
61        except Exception as e:
62            raise

Write data to file. If a TypeError is raised, the function will attempt to case data to a str and try the write again. If a FileNotFoundError is raised and parents = True, self.parent will be created.

def write_bytes(self, data: bytes, parents: bool = True):
64    def write_bytes(self, data: bytes, parents: bool = True):
65        """Write bytes to file.
66
67        :param parents: If True and the write operation fails
68        with a FileNotFoundError, make the parent directory
69        and retry the write."""
70        try:
71            super().write_bytes(data)
72        except FileNotFoundError:
73            if parents:
74                self.parent.mkdir(parents=True)
75                super().write_bytes(data)
76            else:
77                raise
78        except Exception as e:
79            raise

Write bytes to file.

Parameters
  • parents: If True and the write operation fails with a FileNotFoundError, make the parent directory and retry the write.
def json_loads( self, encoding: typing.Any | None = None, errors: typing.Any | None = None) -> Any:
81    def json_loads(self, encoding: Any | None = None, errors: Any | None = None) -> Any:
82        """Load json file."""
83        return json.loads(self.read_text(encoding, errors))

Load json file.

def json_dumps( self, data: Any, encoding: typing.Any | None = None, errors: typing.Any | None = None, newline: typing.Any | None = None, sort_keys: bool = False, indent: typing.Any | None = None, default: typing.Any | None = None, parents: bool = True) -> Any:
 85    def json_dumps(
 86        self,
 87        data: Any,
 88        encoding: Any | None = None,
 89        errors: Any | None = None,
 90        newline: Any | None = None,
 91        sort_keys: bool = False,
 92        indent: Any | None = None,
 93        default: Any | None = None,
 94        parents: bool = True,
 95    ) -> Any:
 96        """Dump data to json file."""
 97        self.write_text(
 98            json.dumps(data, indent=indent, default=default, sort_keys=sort_keys),
 99            encoding,
100            errors,
101            newline,
102            parents,
103        )

Dump data to json file.

def toml_loads( self, encoding: typing.Any | None = None, errors: typing.Any | None = None) -> Any:
105    def toml_loads(self, encoding: Any | None = None, errors: Any | None = None) -> Any:
106        """Load toml file."""
107        return tomlkit.loads(self.read_text(encoding, errors))

Load toml file.

def toml_dumps( self, data: Any, encoding: typing.Any | None = None, errors: typing.Any | None = None, newline: typing.Any | None = None, sort_keys: bool = False, parents: bool = True):
109    def toml_dumps(
110        self,
111        data: Any,
112        encoding: Any | None = None,
113        errors: Any | None = None,
114        newline: Any | None = None,
115        sort_keys: bool = False,
116        parents: bool = True,
117    ):
118        """Dump data to toml file."""
119        self.write_text(
120            tomlkit.dumps(data, sort_keys), encoding, errors, newline, parents
121        )

Dump data to toml file.

def loads( self, encoding: typing.Any | None = None, errors: typing.Any | None = None) -> Any:
123    def loads(self, encoding: Any | None = None, errors: Any | None = None) -> Any:
124        """Load a json or toml file based off this instance's suffix."""
125        match self.suffix:
126            case ".json":
127                return self.json_loads(encoding, errors)
128            case ".toml":
129                return self.toml_loads(encoding, errors)

Load a json or toml file based off this instance's suffix.

def dumps( self, data: Any, encoding: typing.Any | None = None, errors: typing.Any | None = None, newline: typing.Any | None = None, sort_keys: bool = False, indent: typing.Any | None = None, default: typing.Any | None = None, parents: bool = True):
131    def dumps(
132        self,
133        data: Any,
134        encoding: Any | None = None,
135        errors: Any | None = None,
136        newline: Any | None = None,
137        sort_keys: bool = False,
138        indent: Any | None = None,
139        default: Any | None = None,
140        parents: bool = True,
141    ):
142        """Dump data to a json or toml file based off this instance's suffix."""
143        match self.suffix:
144            case ".json":
145                self.json_dumps(
146                    data, encoding, errors, newline, sort_keys, indent, default, parents
147                )
148            case ".toml":
149                self.toml_dumps(data, encoding, errors, newline, sort_keys, parents)

Dump data to a json or toml file based off this instance's suffix.

def delete(self, missing_ok: bool = True):
151    def delete(self, missing_ok: bool = True):
152        """Delete the file or folder pointed to by this instance.
153        Uses self.unlink() if a file and uses shutil.rmtree() if a directory."""
154        if self.is_file():
155            self.unlink(missing_ok)
156        elif self.is_dir():
157            shutil.rmtree(self)

Delete the file or folder pointed to by this instance. Uses self.unlink() if a file and uses shutil.rmtree() if a directory.

def copy( self, new_path: Union[Self, pathlib.Path, str], overwrite: bool = False) -> Self:
159    def copy(
160        self, new_path: Self | pathlib.Path | str, overwrite: bool = False
161    ) -> Self:
162        """Copy the path pointed to by this instance
163        to the instance pointed to by new_path using shutil.copyfile
164        or shutil.copytree. Returns the new path.
165
166        :param new_path: The copy destination.
167
168        :param overwrite: If True, files already existing in new_path
169        will be overwritten. If False, only files that don't exist in new_path
170        will be copied."""
171        new_path = Pathier(new_path)
172        if self.is_dir():
173            if overwrite or not new_path.exists():
174                shutil.copytree(self, new_path, dirs_exist_ok=True)
175            else:
176                files = self.rglob("*.*")
177                for file in files:
178                    dst = new_path.with_name(file.name)
179                    if not dst.exists():
180                        shutil.copyfile(file, dst)
181        elif self.is_file():
182            if overwrite or not new_path.exists():
183                shutil.copyfile(self, new_path)
184        return new_path

Copy the path pointed to by this instance to the instance pointed to by new_path using shutil.copyfile or shutil.copytree. Returns the new path.

Parameters
  • new_path: The copy destination.

  • overwrite: If True, files already existing in new_path will be overwritten. If False, only files that don't exist in new_path will be copied.

Inherited Members
pathlib.Path
cwd
home
samefile
iterdir
glob
rglob
absolute
resolve
stat
owner
group
open
read_bytes
read_text
touch
chmod
lchmod
rmdir
lstat
rename
replace
exists
is_dir
is_file
is_mount
is_block_device
is_char_device
is_fifo
is_socket
expanduser
pathlib.PurePath
as_posix
as_uri
drive
root
anchor
name
suffix
suffixes
stem
with_name
with_stem
with_suffix
relative_to
is_relative_to
parts
joinpath
parent
parents
is_absolute
is_reserved
match