Expand the origin Python pathlib module:
- work-a-round for Windows MAX_PATH limit, by adding \\?\ path prefix
- add missing stuff, like: makedirs, utime, scandir etc.
There is also the class, called DirEntryPath that holds more cached information than os.DirEntry
Used in PyHardLinkBackup: https://github.com/jedie/PyHardLinkBackup
requirement: python 3.6 or newer
Please, try, fork and contribute! ;)
travis-ci.org/jedie/pathlib_revised | |
ci.appveyor.com/project/jedie/pathlib_revised | |
coveralls.io/r/jedie/pathlib_revised | |
requires.io/github/jedie/pathlib_revised/requirements/ |
There is a limit in the Windows API: Path can't be longer than 259 characters (called: "MAX_PATH"). The work-a-round is to add the prefix \\?\ to every absolute path, see:
The Path2() class has the additional property extended_path:
>>> from pathlib_revised import Path2 >>> p=Path2("c:\foo\bar") >>> p.extended_path '\\?\c:\foo\bar'
All existing methods of Path2() will internally use extended_path, so that the MAX_PATH limit is not longer a problem.
extended_path exist also under Posix-Systems, but it's the same as path:
>>> p=Path2("/foo/bar") >>> p.path '/foo/bar' >>> p.extended_path '/foo/bar'
- os.listdir()
>>> Path2("/").listdir() ['sbin', 'boot', 'tmp', 'sys', 'var', 'dev', 'usr', 'root', 'home', ..., 'initrd.img', 'vmlinuz']
- shutil.copyfile()
>>> Path2("a_file.txt").copyfile(Path2("a_file_copy.txt"))
- os.path.expanduser()
>>> p=Path2("~", "sub", "dir") >>> p PosixPath2('~/sub/dir') >>> p.expanduser() PosixPath2('/home/username/sub/dir')
- os.link()
>>> Path2("source.txt").link(Path2("hardlinked.txt"))
- os.makedirs()
>>> Path2("a", "new", "path").makedirs()
- os.utime()
>>> mtime = 111111111 # UTC: 1973-07-10 00:11:51 >>> atime = 222222222 # UTC: 1977-01-16 01:23:42 >>> p.Path2("dir/or/file") >>> p.utime(times=(atime, mtime)) >>> stat = p.stat() >>> stat.st_atime 222222222 >>> stat.st_mtime 111111111
- os.scandir()
>>> p=Path2("/foo/bar") >>> for dir_item in p.scandir(): ... print(dir_item) ... <PosixDirEntry: 'filename'> <PosixDirEntry: 'directory'> <PosixDirEntry: '...'>
It's a generator that yields os.DirEntry instances. scandir is new in Python 3.5, but in Path2() is will fall-back to the external scandir module.
You miss a method? Please, fork, implement, add tests and send a pull request! ;)
The DirEntryPath holds more cached information:
instance.path_instance | Path2() instance |
instance.resolved_path | Path2() instance from .resolve() (If resolve errored: None) |
instance.resolve_error | The error Instance, if .resolve() failed. |
instance.path | string of the path, same as: str(instance.path_instande) |
instance.is_symlink | bool |
instance.is_file | bool |
instance.is_dir | bool |
instance.stat | bool |
Create a instance by feeding a os.DirEntry instance, e.g.:
>>> from pathlib_revised import Path2, DirEntryPath >>> src_path = Path2("foo/") >>> for dir_entry in src_path.scandir(): ... dir_entry_path = DirEntryPath(dir_entry) ... print(dir_entry_path.pformat()) *** <DirEntryPath foo/file1> : path...........: 'foo/file1' path instance..: PosixPath2('foo/file1') resolved path..: PosixPath2('/home/bar/foo/file1') resolve error..: None different path.: True is symlink.....: False is file........: False is dir.........: True stat.size......: 38 *** <DirEntryPath foo/BrokenSymlink.ext> : path...........: 'foo/BrokenSymlink.ext' path instance..: PosixPath2('foo/BrokenSymlink.ext') resolved path..: None resolve error..: FileNotFoundError(2, 'No such file or directory') different path.: True is symlink.....: True is file........: False is dir.........: False stat.size......: 15 *** <DirEntryPath foo/README.creole> : path...........: 'foo/README.creole' path instance..: PosixPath2('foo/README.creole') resolved path..: PosixPath2('/home/bar/foo/README.creole') resolve error..: None different path.: True is symlink.....: False is file........: True is dir.........: False stat.size......: 4802
e.g.:
~$ git clone https://github.com/jedie/pathlib_revised.git ~$ cd pathlib_revised ~/pathlib_revised$ pipenv install ~/pathlib_revised$ pipenv shell (pathlib_revised) ~/pathlib_revised$ tox
- dev - compare v0.2.0...master
- TBC
- 15.09.2019 - compare v0.1.0...v0.2.0 WIP
- refactoring:
- DirEntryPath don't need a os.DirEntry() instance, so .dir_entry attribute was removed
- use pipenv for development
- tests used pytest
- refactoring:
- 08.02.2016 - v0.1.0
- code cleanup + more tests
- move files form PyHardLinkBackup