Package: pathlibutil
pathlibutilpathlibutil.Pathinherits frompathlib.Pathwith some useful built-in python functions fromshutilandhashlibPath.hexdigest()to calculate andPath.verify()for verification of hexdigest from a filePath.default_hashto configurate default hash algorithm forPathclass (default:'md5')Path.size()to get size in bytes of a file or directorybyteintfunction decorator converts the return value ofintto aByteIntobjectPath.read_lines()to yield over all lines from a file until EOFcontextmanagerto change current working directory withwithstatementPath.copy()copy a file or directory to a new path destinationPath.delete()delete a file or directory-treePath.move()move a file or directory to a new path destinationPath.make_archive()creates andPath.unpack_archive()uncompresses an archive from a file or directoryPath.archive_formatsto get all available archive formatsPath.stat()returns aStatResultobject to get file or directory information containingTimeIntobjects foratime,ctime,mtimeandbirthtimeByteIntobject forsizePath.relative_to()to get relative path from a file or directory,walk_upto walk up the directory tree.Installationpipinstallpathlibutil7zip supportto handle 7zip archives, an extra packagepy7zr>=0.20.2is required!# install as extra dependencypipinstallpathlibutil[7z]UsagefrompathlibutilimportPathreadme=Path('README.md')print(f'File size:{readme.size()}Bytes')Example 1Read 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 2Write 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(f"# 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 3Read a file with md5 checksums and verify them.Path.verify(),Path.default_hashandcontextmanagerfrompathlibutilimportPathfile=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 4Search 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()andByteIntfrompathlibutilimportPath,ByteIntmem=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 5Inherit frompathlibutil.Pathto register new a archive format. Specify aarchiveas 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()importpathlibutilimportshutilclassRegisterFooBarFormat(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 createbase_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 archivepath (`str`): directory the archive must be extracted tofilter (`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}")