Skip to content

Repository files navigation

pathlibutil

PyPI - Python VersionPyPI - VersionPyPI - DownloadsPyPI - LicenseGitHub - PytestGitHub - PageGitHub - Releasecodecovpre-commit


pathlibutil.Path inherits from pathlib.Path with some useful built-in python functions from shutil and hashlib

  • Path.hexdigest() to calculate and Path.verify() for verification of hexdigest from a file
  • Path.default_hash to configurate default hash algorithm for Path class (default: 'md5')
  • Path.size() to get size in bytes of a file or directory
    • byteint function decorator converts the return value of int to a ByteInt object
  • Path.read_lines() to yield over all lines from a file until EOF
  • contextmanager to change current working directory with with statement
  • Path.copy() copy a file or directory to a new path destination
  • Path.delete() delete a file or directory-tree
  • Path.move() move a file or directory to a new path destination
  • Path.make_archive() creates and Path.unpack_archive() uncompresses an archive from a file or directory
  • Path.archive_formats to get all available archive formats
  • Path.stat() returns a StatResult object to get file or directory information containing
    • TimeInt objects for atime, ctime, mtime and birthtime
    • ByteInt object for size
  • Path.relative_to() to get relative path from a file or directory, walk_up to walk up the directory tree.
  • Path.with_suffix() to change the multiple suffixes of a file
  • Path.cwd() to get the current working directory or executable path when script is bundled, e.g. with pyinstaller
  • Path.resolve() to resolve a unc path to a mapped windows drive.
  • Path.walk() to walk over a directory tree like os.walk()
  • Path.iterdir() with recursive all files from the directory tree will be yielded and exclude_dirs via callable.
  • Path.is_expired() to check if a file is expired by a given datetime.timedelta
  • Path.expand() yields file paths for multiple file patterns if they exsits.
  • Path.with_anchor() to change the anchor of a path object, e.g. for UNC paths on Windows.

JSON serialization of Path objects is supported in pathlibutil.json.

  • pathlibutil.json.dumps() and pathlibutil.json.dump() to serialize Path objects as posix paths.

Parse and modify URLs with pathlibutil.urlpath.

  • pathlibutil.urlpath.UrlPath() modify URL and easy access the path of the url like a pathlib.PurePosixPath object.
  • pathlibutil.urlpath.UrlNetloc() to parse and modify the netloc part of a URL.
  • pathlibutil.urlpath.normalize() to normalize a URL string.
  • pathlibutil.urlpath.url_from() to create a URL from an UNC path object.

Installation

pip install pathlibutil

7zip support

to handle 7zip archives, an extra package py7zr>=0.20.2 is required!

PyPI - Version

# install as extra dependency
pip install pathlibutil[7z]

Usage

frompathlibutilimportPathreadme=Path('README.md')
print(f'File size: {readme.size()} Bytes')

Example 1

Read a file and print its content and some file information to stdout.

Path.read_lines()

frompathlibutilimportPathreadme=Path("README.md")
print(f"File size: {readme.size()} Bytes")
print(f'File sha1: {readme.hexdigest("sha1")}')
print("File content".center(80, "="))
forlineinreadme.read_lines(encoding="utf-8"):
print(line, end="")
print("EOF".center(80, "="))

Example 2

Write a file with md5 checksums of all python files in the pathlibutil-directory.

Path.hexdigest()

frompathlibutilimportPathfile=Path("pathlibutil.md5")
withfile.open("w") asf:
f.write(
"# MD5 checksums generated with pathlibutil ""(https://pypi.org/project/pathlibutil/)\n\n"
)
i=0fori, filenameinenumerate(Path("./pathlibutil").glob("*.py"), start=1):
f.write(f"{filename.hexdigest()} *{filename}\n")
print(f"\nwritten: {i:>5}{file.default_hash}-hashes to: {file}")

Example 3

Read a file with md5 checksums and verify them.

Path.verify(), Path.default_hash and contextmanager

frompathlibutilimportPathfile=Path("pathlibutil.md5")
defno_comment(line: str) ->bool:
returnnotline.startswith("#")
withfile.parentascwd:
miss=0ok=0fail=0forlineinfilter(no_comment, file.read_lines()):
try:
digest, filename=line.strip().split(" *")
verification=Path(filename).verify(digest, "md5")
exceptValueErrorassplit_failed:
continueexceptFileNotFoundErrorasverify_failed:
tag="missing"miss+=1else:
ifverification:
tag="ok"ok+=1else:
tag="fail"fail+=1print(f'{tag.ljust(len(digest), ".")} *{filename}')
print(f"\nok: {ok:<5} fail: {fail:<5} missing: {miss}")

Example 4

Search all pycache directories and free the memory and display the number of deleted directories and the amount of memory freed in MB.

Path.delete(), Path.size() and ByteInt

frompathlibutilimportByteInt, Pathmem=ByteInt(0)
i=0fori, cacheinenumerate(Path(".").rglob("*/__pycache__/"), start=1):
cache_size=cache.size()
try:
cache.delete(recursive=True)
exceptOSError:
print(f"Failed to delete {cache}")
else:
mem+=cache_sizeprint(f"{i} cache directories deleted, {mem:.1mb} MB freed.")

Example 5

Inherit from pathlibutil.Path to register new a archive format. Specify a archive as keyword argument in the new subclass, which has to be the suffix without . of the archives. Implement a classmethod _register_archive_format() to register new archive formats.

Path.make_archive(), Path.archive_formats and Path.move()

importshutilimportpathlibutilclassRegisterFooBarFormat(pathlibutil.Path, archive="foobar"):
@classmethoddef_register_archive_format(cls):
""" implement new register functions for given `archive` """try:
importrequired_package_nameexceptModuleNotFoundError:
raiseModuleNotFoundError("pip install <required_package_name>")
defpack_foobar(
base_name, base_dir, owner=None, group=None, dry_run=None, logger=None
) ->str:
"""callable that will be used to unpack archives. Args: base_name (`str`): name of the file to create base_dir (`str`): directory to start archiving from, defaults to `os.curdir` owner (`Any`, optional): as passed in `make_archive(*args, owner=None, **kwargs)`. Defaults to None. group (`Any`, optional): as passed in `make_archive(*args, group=None, **kwargs)`. Defaults to None. dry_run (`Any`, optional): as passed in `make_archive(*args, dry_run=None, **kwargs)`. Defaults to None. logger (`logging.Logger`, optional): as passed in `make_archive(*args, logger=None, **kwargs)`. Defaults to None. Returns: str: path of the new created archive """raiseNotImplementedError("implement your own pack function")
defunpack_foobar(archive, path, filter=None, extra_args=None) ->None:
"""callable that will be used to unpack archives. Args: archive (`str`): path of the archive path (`str`): directory the archive must be extracted to filter (`Any`, optional): as passed in `unpack_archive(*args, filter=None, **kwargs)`. Defaults to None. extra_args (`Sequence[Tuple[name, value]]`, optional): additional keyword arguments, specified by `register_unpack_format(*args, extra_args=None, **kwargs)`. Defaults to None. """raiseNotImplementedError("implement your own unpack function")
shutil.register_archive_format(
"foobar", pack_foobar, description="foobar archives"
)
shutil.register_unpack_format("foobar", [".foo.bar"], unpack_foobar)
file=pathlibutil.Path("README.md")
print(f"available archive formats: {file.archive_formats}")
archive=file.make_archive("README.foo.bar")
backup=archive.move("./backup/")
print(f"archive created: {archive.name} and moved to: {backup.parent}")

Example 6

Access the current working directory with optional parameter frozen to determine different directories when script is bundled to an executable, e.g. with pyinstaller.

Path.cwd()

>>> poetry run examples/example6.py -b
Building frozen: K:/pathlibutil/examples/example6.exe
Build succeeded: 0>>> poetry run examples/example6.py
we are not frozen
bundle dir is K:/pathlibutil/examples
sys.argv[0] is K:/pathlibutil/examples/example6.py
sys.executable is K:/pathlibutil/.venv/Scripts/python.exe
os.getcwd is K:/pathlibutil
Path.cwd(frozen=True) is K:/pathlibutil
Path.cwd(frozen=False) is K:/pathlibutil
Path.cwd(frozen=_MEIPASS) is K:/pathlibutil
>>> examples/example6.exe
we are ever so frozen
bundle dir is C:/Users/CHRIST~1.DOE/AppData/Local/Temp/_MEI106042
sys.argv[0] is examples/example6.exe
sys.executable is K:/pathlibutil/examples/example6.exe
os.getcwd is K:/pathlibutil
Path.cwd(frozen=True) is K:/pathlibutil/examples
Path.cwd(frozen=False) is K:/pathlibutil
Path.cwd(frozen=_MEIPASS) is C:/Users/CHRIST~1.DOE/AppData/Local/Temp/_MEI106042

Example 7

Console application to convert UNC paths to intranet URLs.

By default, it checks if the filename and URL are available and copies the normalized URL to the clipboard.

pathlibutil.urlpath.url_from()

importargparseimportsystry:
importpyperclipimportpathlibutil.urlpathasupexceptModuleNotFoundErrorase:
raiseModuleNotFoundError(f"pip install {e.name.split('.')[0]}") fromedefintranet_from(uncpath: str, check: bool=True) ->str:
""" Return the intranet URL for the given UNC path. """url=up.url_from(
uncpath,
hostname="http://intranet.example.de",
strict=check,
)
returnurl.normalize()
defcli():
parser=argparse.ArgumentParser(
description=intranet_from.__doc__,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"filename",
nargs="*",
help="The UNC path to the file.",
)
parser.add_argument(
"-c",
"--no-check",
action="store_false",
dest="check",
help="Don't check if filename and url is available.",
)
parser.add_argument(
"-s",
"--silent",
action="store_true",
help="Do not print the url to stdout.",
)
parser.add_argument(
"-n",
"--no-clip",
action="store_false",
dest="clip",
help="Don't copy the url to the clipboard.",
)
args=parser.parse_args()
filename=" ".join(args.filename)
url=intranet_from(filename, check=args.check)
ifnotargs.silent:
print(url)
ifargs.clip:
pyperclip.copy(url)
if__name__=="__main__":
try:
cli()
exceptExceptionase:
print(e, file=sys.stderr)
sys.exit(1)

About

python __class__ inherits from pathlib.Path with methods for hashing, copying, deleting and more

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages