pathlibutil 0.1.8__tar.gz → 0.2.0__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.
- {pathlibutil-0.1.8 → pathlibutil-0.2.0}/PKG-INFO +51 -3
- {pathlibutil-0.1.8 → pathlibutil-0.2.0}/README.md +50 -2
- {pathlibutil-0.1.8 → pathlibutil-0.2.0}/pathlibutil/__init__.py +1 -1
- pathlibutil-0.2.0/pathlibutil/json.py +25 -0
- {pathlibutil-0.1.8 → pathlibutil-0.2.0}/pathlibutil/path.py +173 -16
- {pathlibutil-0.1.8 → pathlibutil-0.2.0}/pathlibutil/types.py +2 -1
- {pathlibutil-0.1.8 → pathlibutil-0.2.0}/pyproject.toml +27 -23
- {pathlibutil-0.1.8 → pathlibutil-0.2.0}/LICENSE +0 -0
- {pathlibutil-0.1.8 → pathlibutil-0.2.0}/pathlibutil/base.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pathlibutil
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: inherits from pathlib.Path with methods for hashing, copying, deleting and more
|
|
5
5
|
Home-page: https://d-chris.github.io
|
|
6
6
|
License: MIT
|
|
@@ -32,6 +32,7 @@ Description-Content-Type: text/markdown
|
|
|
32
32
|
[](https://d-chris.github.io/pathlibutil)
|
|
33
33
|
[](https://github.com/d-chris/pathlibutil)
|
|
34
34
|
[](https://d-chris.github.io/pathlibutil/htmlcov)
|
|
35
|
+
[](https://github.com/pre-commit/pre-commit)
|
|
35
36
|
|
|
36
37
|
---
|
|
37
38
|
|
|
@@ -52,6 +53,15 @@ Description-Content-Type: text/markdown
|
|
|
52
53
|
- `TimeInt` objects for `atime`, `ctime`, `mtime` and `birthtime`
|
|
53
54
|
- `ByteInt` object for `size`
|
|
54
55
|
- `Path.relative_to()` to get relative path from a file or directory, `walk_up` to walk up the directory tree.
|
|
56
|
+
- `Path.with_suffix()` to change the multiple suffixes of a file
|
|
57
|
+
- `Path.cwd()` to get the current working directory or executable path when script is bundled, e.g. with `pyinstaller`
|
|
58
|
+
- `Path.resolve()` to resolve a unc path to a mapped windows drive.
|
|
59
|
+
- `Path.walk()` to walk over a directory tree like `os.walk()`
|
|
60
|
+
- `Path.iterdir()` with `recursive` all files from the directory tree will be yielded and `exclude_dirs` via callable.
|
|
61
|
+
|
|
62
|
+
JSON serialization of `Path` objects is supported in `pathlibutil.json`.
|
|
63
|
+
|
|
64
|
+
- `pathlibutil.json.dumps()` and `pathlibutil.json.dump()` to serialize `Path` objects as posix paths.
|
|
55
65
|
|
|
56
66
|
## Installation
|
|
57
67
|
|
|
@@ -173,7 +183,7 @@ deleted directories and the amount of memory freed in MB.
|
|
|
173
183
|
> `Path.delete()`, `Path.size()` and `ByteInt`
|
|
174
184
|
|
|
175
185
|
```python
|
|
176
|
-
from pathlibutil import
|
|
186
|
+
from pathlibutil import ByteInt, Path
|
|
177
187
|
|
|
178
188
|
mem = ByteInt(0)
|
|
179
189
|
i = 0
|
|
@@ -200,9 +210,10 @@ to register new archive formats.
|
|
|
200
210
|
> Path.make_archive(), Path.archive_formats and Path.move()
|
|
201
211
|
|
|
202
212
|
```python
|
|
203
|
-
import pathlibutil
|
|
204
213
|
import shutil
|
|
205
214
|
|
|
215
|
+
import pathlibutil
|
|
216
|
+
|
|
206
217
|
|
|
207
218
|
class RegisterFooBarFormat(pathlibutil.Path, archive="foobar"):
|
|
208
219
|
@classmethod
|
|
@@ -261,3 +272,40 @@ backup = archive.move("./backup/")
|
|
|
261
272
|
print(f"archive created: {archive.name} and moved to: {backup.parent}")
|
|
262
273
|
```
|
|
263
274
|
|
|
275
|
+
## Example 6
|
|
276
|
+
|
|
277
|
+
Access the current working directory with optional parameter `frozen` to determine
|
|
278
|
+
different directories when script is bundled to an executable,
|
|
279
|
+
e.g. with `pyinstaller`.
|
|
280
|
+
> `Path.cwd()`
|
|
281
|
+
|
|
282
|
+
```cmd
|
|
283
|
+
>>> poetry run examples/example6.py -b
|
|
284
|
+
Building frozen: K:/pathlibutil/examples/example6.exe
|
|
285
|
+
Build succeeded: 0
|
|
286
|
+
|
|
287
|
+
>>> poetry run examples/example6.py
|
|
288
|
+
we are not frozen
|
|
289
|
+
|
|
290
|
+
bundle dir is K:/pathlibutil/examples
|
|
291
|
+
sys.argv[0] is K:/pathlibutil/examples/example6.py
|
|
292
|
+
sys.executable is K:/pathlibutil/.venv/Scripts/python.exe
|
|
293
|
+
os.getcwd is K:/pathlibutil
|
|
294
|
+
|
|
295
|
+
Path.cwd(frozen=True) is K:/pathlibutil
|
|
296
|
+
Path.cwd(frozen=False) is K:/pathlibutil
|
|
297
|
+
Path.cwd(frozen=_MEIPASS) is K:/pathlibutil
|
|
298
|
+
|
|
299
|
+
>>> examples/example6.exe
|
|
300
|
+
we are ever so frozen
|
|
301
|
+
|
|
302
|
+
bundle dir is C:/Users/CHRIST~1.DOE/AppData/Local/Temp/_MEI106042
|
|
303
|
+
sys.argv[0] is examples/example6.exe
|
|
304
|
+
sys.executable is K:/pathlibutil/examples/example6.exe
|
|
305
|
+
os.getcwd is K:/pathlibutil
|
|
306
|
+
|
|
307
|
+
Path.cwd(frozen=True) is K:/pathlibutil/examples
|
|
308
|
+
Path.cwd(frozen=False) is K:/pathlibutil
|
|
309
|
+
Path.cwd(frozen=_MEIPASS) is C:/Users/CHRIST~1.DOE/AppData/Local/Temp/_MEI106042
|
|
310
|
+
```
|
|
311
|
+
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
[](https://d-chris.github.io/pathlibutil)
|
|
9
9
|
[](https://github.com/d-chris/pathlibutil)
|
|
10
10
|
[](https://d-chris.github.io/pathlibutil/htmlcov)
|
|
11
|
+
[](https://github.com/pre-commit/pre-commit)
|
|
11
12
|
|
|
12
13
|
---
|
|
13
14
|
|
|
@@ -28,6 +29,15 @@
|
|
|
28
29
|
- `TimeInt` objects for `atime`, `ctime`, `mtime` and `birthtime`
|
|
29
30
|
- `ByteInt` object for `size`
|
|
30
31
|
- `Path.relative_to()` to get relative path from a file or directory, `walk_up` to walk up the directory tree.
|
|
32
|
+
- `Path.with_suffix()` to change the multiple suffixes of a file
|
|
33
|
+
- `Path.cwd()` to get the current working directory or executable path when script is bundled, e.g. with `pyinstaller`
|
|
34
|
+
- `Path.resolve()` to resolve a unc path to a mapped windows drive.
|
|
35
|
+
- `Path.walk()` to walk over a directory tree like `os.walk()`
|
|
36
|
+
- `Path.iterdir()` with `recursive` all files from the directory tree will be yielded and `exclude_dirs` via callable.
|
|
37
|
+
|
|
38
|
+
JSON serialization of `Path` objects is supported in `pathlibutil.json`.
|
|
39
|
+
|
|
40
|
+
- `pathlibutil.json.dumps()` and `pathlibutil.json.dump()` to serialize `Path` objects as posix paths.
|
|
31
41
|
|
|
32
42
|
## Installation
|
|
33
43
|
|
|
@@ -149,7 +159,7 @@ deleted directories and the amount of memory freed in MB.
|
|
|
149
159
|
> `Path.delete()`, `Path.size()` and `ByteInt`
|
|
150
160
|
|
|
151
161
|
```python
|
|
152
|
-
from pathlibutil import
|
|
162
|
+
from pathlibutil import ByteInt, Path
|
|
153
163
|
|
|
154
164
|
mem = ByteInt(0)
|
|
155
165
|
i = 0
|
|
@@ -176,9 +186,10 @@ to register new archive formats.
|
|
|
176
186
|
> Path.make_archive(), Path.archive_formats and Path.move()
|
|
177
187
|
|
|
178
188
|
```python
|
|
179
|
-
import pathlibutil
|
|
180
189
|
import shutil
|
|
181
190
|
|
|
191
|
+
import pathlibutil
|
|
192
|
+
|
|
182
193
|
|
|
183
194
|
class RegisterFooBarFormat(pathlibutil.Path, archive="foobar"):
|
|
184
195
|
@classmethod
|
|
@@ -236,3 +247,40 @@ backup = archive.move("./backup/")
|
|
|
236
247
|
|
|
237
248
|
print(f"archive created: {archive.name} and moved to: {backup.parent}")
|
|
238
249
|
```
|
|
250
|
+
|
|
251
|
+
## Example 6
|
|
252
|
+
|
|
253
|
+
Access the current working directory with optional parameter `frozen` to determine
|
|
254
|
+
different directories when script is bundled to an executable,
|
|
255
|
+
e.g. with `pyinstaller`.
|
|
256
|
+
> `Path.cwd()`
|
|
257
|
+
|
|
258
|
+
```cmd
|
|
259
|
+
>>> poetry run examples/example6.py -b
|
|
260
|
+
Building frozen: K:/pathlibutil/examples/example6.exe
|
|
261
|
+
Build succeeded: 0
|
|
262
|
+
|
|
263
|
+
>>> poetry run examples/example6.py
|
|
264
|
+
we are not frozen
|
|
265
|
+
|
|
266
|
+
bundle dir is K:/pathlibutil/examples
|
|
267
|
+
sys.argv[0] is K:/pathlibutil/examples/example6.py
|
|
268
|
+
sys.executable is K:/pathlibutil/.venv/Scripts/python.exe
|
|
269
|
+
os.getcwd is K:/pathlibutil
|
|
270
|
+
|
|
271
|
+
Path.cwd(frozen=True) is K:/pathlibutil
|
|
272
|
+
Path.cwd(frozen=False) is K:/pathlibutil
|
|
273
|
+
Path.cwd(frozen=_MEIPASS) is K:/pathlibutil
|
|
274
|
+
|
|
275
|
+
>>> examples/example6.exe
|
|
276
|
+
we are ever so frozen
|
|
277
|
+
|
|
278
|
+
bundle dir is C:/Users/CHRIST~1.DOE/AppData/Local/Temp/_MEI106042
|
|
279
|
+
sys.argv[0] is examples/example6.exe
|
|
280
|
+
sys.executable is K:/pathlibutil/examples/example6.exe
|
|
281
|
+
os.getcwd is K:/pathlibutil
|
|
282
|
+
|
|
283
|
+
Path.cwd(frozen=True) is K:/pathlibutil/examples
|
|
284
|
+
Path.cwd(frozen=False) is K:/pathlibutil
|
|
285
|
+
Path.cwd(frozen=_MEIPASS) is C:/Users/CHRIST~1.DOE/AppData/Local/Temp/_MEI106042
|
|
286
|
+
```
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from pathlibutil.path import Path, Register7zFormat
|
|
6
|
-
from pathlibutil.types import ByteInt, TimeInt, byteint
|
|
6
|
+
from pathlibutil.types import ByteInt, StatResult, TimeInt, byteint
|
|
7
7
|
|
|
8
8
|
__all__ = ["Path", "Register7zFormat", "ByteInt", "byteint", "TimeInt", "StatResult"]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
import importlib
|
|
3
|
+
import pathlib
|
|
4
|
+
|
|
5
|
+
json = importlib.import_module("json")
|
|
6
|
+
|
|
7
|
+
from json import load, loads
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PathEncoder(json.JSONEncoder):
|
|
11
|
+
def default(self, obj):
|
|
12
|
+
if isinstance(obj, pathlib.Path):
|
|
13
|
+
return obj.as_posix()
|
|
14
|
+
|
|
15
|
+
return super().default(obj)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@functools.wraps(json.dump)
|
|
19
|
+
def dump(obj, fp, *, cls=PathEncoder, **kwargs):
|
|
20
|
+
return json.dump(obj, fp, cls=cls, **kwargs)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@functools.wraps(json.dumps)
|
|
24
|
+
def dumps(obj, *, cls=PathEncoder, **kwargs):
|
|
25
|
+
return json.dumps(obj, cls=cls, **kwargs)
|
|
@@ -2,8 +2,11 @@ import errno
|
|
|
2
2
|
import hashlib
|
|
3
3
|
import itertools
|
|
4
4
|
import os
|
|
5
|
+
import re
|
|
5
6
|
import shutil
|
|
6
|
-
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
from typing import Callable, Dict, Generator, List, Literal, Set, Tuple, Union
|
|
7
10
|
|
|
8
11
|
from pathlibutil.base import BasePath, _Path
|
|
9
12
|
from pathlibutil.types import ByteInt, StatResult, _stat_result, byteint
|
|
@@ -19,8 +22,8 @@ class Path(BasePath):
|
|
|
19
22
|
|
|
20
23
|
- Contextmanger lets you change the current working directory.
|
|
21
24
|
```python
|
|
22
|
-
with Path(
|
|
23
|
-
print(f
|
|
25
|
+
with Path("path/to/directory") as cwd:
|
|
26
|
+
print(f"current working directory: {cwd}")
|
|
24
27
|
```
|
|
25
28
|
"""
|
|
26
29
|
|
|
@@ -81,15 +84,20 @@ class Path(BasePath):
|
|
|
81
84
|
if not self.is_file():
|
|
82
85
|
raise FileNotFoundError(f"'{self}' is not an existing file")
|
|
83
86
|
|
|
84
|
-
|
|
85
|
-
args = (kwargs.pop("length"),)
|
|
86
|
-
except KeyError:
|
|
87
|
-
args = ()
|
|
88
|
-
|
|
89
|
-
return hashlib.new(
|
|
87
|
+
hash = hashlib.new(
|
|
90
88
|
name=algorithm or self.default_hash,
|
|
91
89
|
data=self.read_bytes(),
|
|
92
|
-
)
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
return hash.hexdigest()
|
|
94
|
+
except TypeError as e:
|
|
95
|
+
try:
|
|
96
|
+
length = kwargs["length"]
|
|
97
|
+
except KeyError:
|
|
98
|
+
raise e
|
|
99
|
+
|
|
100
|
+
return hash.hexdigest(length)
|
|
93
101
|
|
|
94
102
|
def verify(
|
|
95
103
|
self, digest: str, algorithm: str = None, *, strict: bool = True, **kwargs
|
|
@@ -475,6 +483,157 @@ class Path(BasePath):
|
|
|
475
483
|
|
|
476
484
|
return relative
|
|
477
485
|
|
|
486
|
+
@classmethod
|
|
487
|
+
def cwd(cls, *, frozen: Literal[True, False, "_MEIPASS"] = False) -> _Path:
|
|
488
|
+
"""
|
|
489
|
+
Return a `Path` object representing the current working directory.
|
|
490
|
+
|
|
491
|
+
The `frozen` parameter takes only effect when the script is bundled to a
|
|
492
|
+
executable, e.g. with `pyinstaller`.
|
|
493
|
+
|
|
494
|
+
- `False`: Returns the current working directory, this is the default.
|
|
495
|
+
- `True`: Returns the directory of the executable.
|
|
496
|
+
- `"_MEIPASS"`: Returns the directory of the bundled resources.
|
|
497
|
+
"""
|
|
498
|
+
if getattr(sys, "frozen", False):
|
|
499
|
+
if frozen is True:
|
|
500
|
+
return cls(sys.executable).parent
|
|
501
|
+
elif isinstance(frozen, str):
|
|
502
|
+
return cls(getattr(sys, frozen))
|
|
503
|
+
|
|
504
|
+
return super().cwd()
|
|
505
|
+
|
|
506
|
+
@classmethod
|
|
507
|
+
def _net_use(cls) -> Dict[str, str]:
|
|
508
|
+
"""
|
|
509
|
+
Return a dictionary of mapped network drives. Keys are UNC paths and values
|
|
510
|
+
are drive letters.
|
|
511
|
+
"""
|
|
512
|
+
|
|
513
|
+
def run(cmd: str) -> str:
|
|
514
|
+
"""execute `command` and return stdout with cp850 encoding."""
|
|
515
|
+
result = subprocess.run(
|
|
516
|
+
cmd,
|
|
517
|
+
capture_output=True,
|
|
518
|
+
shell=True,
|
|
519
|
+
encoding="cp850",
|
|
520
|
+
check=True,
|
|
521
|
+
)
|
|
522
|
+
|
|
523
|
+
return result.stdout
|
|
524
|
+
|
|
525
|
+
try:
|
|
526
|
+
mapped_drives = re.finditer(
|
|
527
|
+
r"^OK\s+(?P<drive>[A-Z]):\s+(?P<unc>\S+)",
|
|
528
|
+
run("net use"),
|
|
529
|
+
re.IGNORECASE | re.MULTILINE,
|
|
530
|
+
)
|
|
531
|
+
return {
|
|
532
|
+
match.group("unc") + "\\": cls(match.group("drive") + ":\\")
|
|
533
|
+
for match in mapped_drives
|
|
534
|
+
}
|
|
535
|
+
except Exception:
|
|
536
|
+
return {}
|
|
537
|
+
|
|
538
|
+
def _resolve_unc(self) -> _Path:
|
|
539
|
+
"""
|
|
540
|
+
Resolve UNC paths to mapped network drives.
|
|
541
|
+
"""
|
|
542
|
+
if not hasattr(self.__class__, "_netuse"):
|
|
543
|
+
self.__class__._netuse = self._net_use()
|
|
544
|
+
|
|
545
|
+
try:
|
|
546
|
+
drive = self._netuse[self.anchor]
|
|
547
|
+
return drive.joinpath(self.relative_to(self.anchor))
|
|
548
|
+
except KeyError:
|
|
549
|
+
return self
|
|
550
|
+
|
|
551
|
+
def resolve(self, strict: bool = False, unc: bool = True) -> _Path:
|
|
552
|
+
"""
|
|
553
|
+
Make the path absolute, resolving all symlinks on the way and also normalizing
|
|
554
|
+
it.
|
|
555
|
+
|
|
556
|
+
If `strict` is `True`, a `FileNotFoundError` will be raised if the path does
|
|
557
|
+
not exist.
|
|
558
|
+
|
|
559
|
+
On Windows if `unc` is `False`, UNC paths will be resolved to mapped network
|
|
560
|
+
drives.
|
|
561
|
+
|
|
562
|
+
>>> Path("T:/file.txt").resolve()
|
|
563
|
+
Path("\\\\server\\temp\\file.txt")
|
|
564
|
+
|
|
565
|
+
>>> Path("//server/temp/file.txt").resolve(unc=False)
|
|
566
|
+
Path("T:\\file.txt")
|
|
567
|
+
"""
|
|
568
|
+
|
|
569
|
+
p = super().resolve(strict)
|
|
570
|
+
|
|
571
|
+
if unc is True or os.name != "nt":
|
|
572
|
+
return p
|
|
573
|
+
|
|
574
|
+
return p._resolve_unc()
|
|
575
|
+
|
|
576
|
+
def walk(
|
|
577
|
+
self,
|
|
578
|
+
top_down: bool = True,
|
|
579
|
+
on_error: Callable[[OSError], object] = None,
|
|
580
|
+
follow_symlinks: bool = False,
|
|
581
|
+
) -> Generator[Tuple[_Path, List[str], List[str]], None, None]:
|
|
582
|
+
"""
|
|
583
|
+
Walks the directory tree and yields a 3-tuple of (dirpath, dirnames, filenames).
|
|
584
|
+
"""
|
|
585
|
+
try:
|
|
586
|
+
yield from super().walk(
|
|
587
|
+
top_down,
|
|
588
|
+
on_error,
|
|
589
|
+
follow_symlinks,
|
|
590
|
+
)
|
|
591
|
+
except AttributeError:
|
|
592
|
+
for dirpath, dirnames, filenames in os.walk(
|
|
593
|
+
self,
|
|
594
|
+
top_down,
|
|
595
|
+
on_error,
|
|
596
|
+
follow_symlinks,
|
|
597
|
+
):
|
|
598
|
+
yield self.__class__(dirpath), dirnames, filenames
|
|
599
|
+
|
|
600
|
+
def iterdir(
|
|
601
|
+
self,
|
|
602
|
+
*,
|
|
603
|
+
recursive: Union[bool, int] = False,
|
|
604
|
+
exclude_dirs: Callable[[_Path], bool] = None,
|
|
605
|
+
**kwargs,
|
|
606
|
+
) -> Generator[_Path, None, None]:
|
|
607
|
+
"""
|
|
608
|
+
Iterates over the files in the directory.
|
|
609
|
+
|
|
610
|
+
If `recursive` is `True` all files from the directory tree will
|
|
611
|
+
be yielded if it is an `integer` files are yielded to this max. directory depth
|
|
612
|
+
optional` **kwargs` are passed to `Path.walk()`.
|
|
613
|
+
|
|
614
|
+
When recursing, folders can be excluded by passing a callable for `exclude_dirs`, e.g.
|
|
615
|
+
|
|
616
|
+
```python
|
|
617
|
+
def exclude_version_control(dirpath: _Path) -> bool:
|
|
618
|
+
return dirpath.name in (".git", ".svn", ".hg", ".bzr", "CVS")
|
|
619
|
+
```
|
|
620
|
+
"""
|
|
621
|
+
if recursive is not False:
|
|
622
|
+
if exclude_dirs and not callable(exclude_dirs):
|
|
623
|
+
raise TypeError("exclude_dirs must be a callable")
|
|
624
|
+
|
|
625
|
+
depth = recursive if type(recursive) == int else None
|
|
626
|
+
|
|
627
|
+
for root, dirs, files in self.walk(**kwargs):
|
|
628
|
+
if depth is not None and len(root.relative_to(self).parts) >= depth:
|
|
629
|
+
dirs[:] = []
|
|
630
|
+
elif exclude_dirs:
|
|
631
|
+
dirs[:] = [d for d in dirs if not exclude_dirs(root.joinpath(d))]
|
|
632
|
+
|
|
633
|
+
yield from (root.joinpath(file) for file in files)
|
|
634
|
+
else:
|
|
635
|
+
yield from super().iterdir()
|
|
636
|
+
|
|
478
637
|
|
|
479
638
|
class Register7zFormat(Path, archive="7z"):
|
|
480
639
|
"""
|
|
@@ -491,20 +650,18 @@ class Register7zFormat(Path, archive="7z"):
|
|
|
491
650
|
|
|
492
651
|
Example:
|
|
493
652
|
```python
|
|
494
|
-
class Register7zArchive(pathlibutil.Path, archive=
|
|
653
|
+
class Register7zArchive(pathlibutil.Path, archive="7z"):
|
|
495
654
|
@classmethod
|
|
496
655
|
def _register_archive_format(cls):
|
|
497
656
|
try:
|
|
498
657
|
from py7zr import pack_7zarchive, unpack_7zarchive
|
|
499
658
|
except ModuleNotFoundError:
|
|
500
|
-
raise ModuleNotFoundError(
|
|
659
|
+
raise ModuleNotFoundError("pip install pathlibutil[7z]")
|
|
501
660
|
else:
|
|
502
661
|
shutil.register_archive_format(
|
|
503
|
-
|
|
504
|
-
)
|
|
505
|
-
shutil.register_unpack_format(
|
|
506
|
-
'7z', ['.7z'], unpack_7zarchive
|
|
662
|
+
"7z", pack_7zarchive, description="7zip archive"
|
|
507
663
|
)
|
|
664
|
+
shutil.register_unpack_format("7z", [".7z"], unpack_7zarchive)
|
|
508
665
|
```
|
|
509
666
|
"""
|
|
510
667
|
|
|
@@ -2,7 +2,7 @@ import functools
|
|
|
2
2
|
import os
|
|
3
3
|
import re
|
|
4
4
|
from datetime import datetime, tzinfo
|
|
5
|
-
from typing import Set, Tuple, TypeVar
|
|
5
|
+
from typing import Iterable, Set, Tuple, TypeVar
|
|
6
6
|
|
|
7
7
|
_ByteInt = TypeVar("_ByteInt", bound="ByteInt")
|
|
8
8
|
_stat_result = TypeVar("_stat_result", bound="os.stat_result")
|
|
@@ -206,6 +206,7 @@ def byteint(func):
|
|
|
206
206
|
```python
|
|
207
207
|
randbyte = byteint(random.randint)
|
|
208
208
|
|
|
209
|
+
|
|
209
210
|
@byteint
|
|
210
211
|
def randhexbyte():
|
|
211
212
|
return hex(random.randint(0, 2**32))
|
|
@@ -1,31 +1,38 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
build-backend = "poetry.core.masonry.api"
|
|
3
|
+
|
|
4
|
+
requires = [
|
|
5
|
+
"poetry-core",
|
|
6
|
+
]
|
|
7
|
+
|
|
1
8
|
[tool.poetry]
|
|
2
9
|
name = "pathlibutil"
|
|
3
|
-
version = "v0.
|
|
10
|
+
version = "v0.2.0"
|
|
4
11
|
description = "inherits from pathlib.Path with methods for hashing, copying, deleting and more"
|
|
5
|
-
authors = ["Christoph Dörrer <d-chris@web.de>"]
|
|
12
|
+
authors = [ "Christoph Dörrer <d-chris@web.de>" ]
|
|
6
13
|
readme = "README.md"
|
|
7
14
|
license = "MIT"
|
|
8
15
|
classifiers = [
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
"Programming Language :: Python :: 3.8",
|
|
17
|
+
"Programming Language :: Python :: 3.9",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
16
23
|
]
|
|
17
|
-
keywords = ["pathlib", "hashlib", "shutil"]
|
|
24
|
+
keywords = [ "pathlib", "hashlib", "shutil" ]
|
|
18
25
|
homepage = "https://d-chris.github.io"
|
|
19
26
|
repository = "https://github.com/d-chris/pathlibutil"
|
|
20
27
|
documentation = "https://d-chris.github.io/pathlibutil"
|
|
21
|
-
include = ["LICENSE"]
|
|
28
|
+
include = [ "LICENSE" ]
|
|
22
29
|
|
|
23
30
|
[tool.poetry.dependencies]
|
|
24
31
|
python = ">=3.8.1,<3.13"
|
|
25
32
|
py7zr = { version = "^0.20.2", optional = true }
|
|
26
33
|
|
|
27
34
|
[tool.poetry.extras]
|
|
28
|
-
7z = ["py7zr"]
|
|
35
|
+
7z = [ "py7zr" ]
|
|
29
36
|
|
|
30
37
|
[tool.poetry.group.dev.dependencies]
|
|
31
38
|
pytest = "^7.4.3"
|
|
@@ -44,6 +51,7 @@ docformatter = "^1.7.5"
|
|
|
44
51
|
jinja2-pdoc = "^0.2.0"
|
|
45
52
|
pdoc = "^14.3.0"
|
|
46
53
|
click = "^8.1.7"
|
|
54
|
+
pyinstaller = "^6.5.0"
|
|
47
55
|
|
|
48
56
|
[[tool.poetry.source]]
|
|
49
57
|
name = "PyPI"
|
|
@@ -54,19 +62,15 @@ name = "testpypi"
|
|
|
54
62
|
url = "https://test.pypi.org/legacy/"
|
|
55
63
|
priority = "explicit"
|
|
56
64
|
|
|
57
|
-
[build-system]
|
|
58
|
-
requires = ["poetry-core"]
|
|
59
|
-
build-backend = "poetry.core.masonry.api"
|
|
60
|
-
|
|
61
65
|
[tool.pytest.ini_options]
|
|
62
66
|
minversion = "6.0"
|
|
63
67
|
testpaths = "tests"
|
|
64
68
|
addopts = [
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
"--random-order",
|
|
70
|
+
"--color=yes",
|
|
71
|
+
"-s",
|
|
72
|
+
# "--cov=pathlibutil",
|
|
73
|
+
# "--cov-report=term-missing:skip-covered",
|
|
74
|
+
# "--cov-append",
|
|
75
|
+
# "--cov-report=html",
|
|
72
76
|
]
|
|
File without changes
|
|
File without changes
|