Skip to main content

backport of pathlib 3.10 to python 3.6, 3.7, 3.8, 3.9 with a few extensions

Project description

pathlib3x

Version v2.0.2.1 as of 2022-06-03 see Changelog

build_badge license pypi PyPI - Downloads black

codecov better_code Maintainability Maintainability Code Coverage snyk

Backport of Python 3.11.0a0 pathlib for Python 3.6, 3.7, 3.8, 3.9, 3.10 with a few tweaks to make it compatible.

added wrappers to shutil copy, copy2, rmtree, copytree and other useful functions.

fully typed PEP561 package

this will be updated periodically to have the latest version of pathlib available on 3.6, 3.7, 3.8, 3.9, 3.10 and probably others.

WHY pathlib3x ?

There are a number of small, but very handy features added in pathlib over the last python versions, so I want to be able to use those also on older python versions.

if You are used to :

import pathlib

pathlib.Path('some_file').unlink(missing_ok=True)

You will have no luck on python 3.7 - because the “missing_ok” parameter was added in python3.8

Of course You can do :

import pathlib

try:
    pathlib.Path('some_file').unlink()
except FileNotFoundError:
    pass

but that clutters the code unnecessarily. So just use :

import pathlib3x as pathlib

and You can enjoy the latest pathlib features even on older python versions.

Some own extensions to that pathlib will be added probably over time. At the moment we added some wrappers to shutil like “copy”, “rmtree”, “copytree”, so You can do :

import pathlib3x as pathlib
my_file = pathlib.Path('/etc/hosts')
to_file = pathlib.Path('/tmp/foo')
my_file.copy(to_file)

If You have some nice features for pathlib, let me know - I will consider to integrate them.


automated tests, Travis Matrix, Documentation, Badges, etc. are managed with PizzaCutter (cookiecutter on steroids)

Python version required: 3.6.0 or newer

tested on recent linux with python 3.6, 3.7, 3.8, 3.9, 3.10, pypy-3.8 - architectures: amd64

100% (for my added functions) code coverage, flake8 style checking ,mypy static type checking ,tested under Linux, macOS, Windows, automatic daily builds and monitoring



Usage

just check out the latest python documentation : https://docs.python.org/3/library/pathlib.html and select 3.10 Branch

Additional Features are documented here :

PurePath.append_suffix(suffix)

Return a new path with the suffix appended. If the original path doesn’t have a suffix, the new suffix is appended. If the original path have a suffix, the new suffix will be appended at the end. If suffix is an empty string the original Path will be returned.

>>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz')
>>> p.append_suffix('.bz2')
PureWindowsPath('c:/Downloads/pathlib.tar.gz.bz2')
>>> p = PureWindowsPath('README')
>>> p.append_suffix('.txt')
PureWindowsPath('README.txt')
>>> p = PureWindowsPath('README.txt')
>>> p.append_suffix('')
PureWindowsPath('README.txt')
PurePath.is_path_instance(__obj)

Return True if __obj is instance of the original pathlib.Path or pathlib3x.Path. Useful if You need to check for Path type, in an environment were You mix pathlib and pathlib3x

>>> import pathlib3x
>>> import pathlib

>>> pathlib3x_path = pathlib3x.Path('some_path')  # this might happen in another module !
>>> pathlib_path = pathlib.Path('some_path')
>>> isinstance(pathlib3x_path, pathlib.Path)
False
>>> isinstance(pathlib_path, pathlib3x.Path)
False

# in such cases were You need to mix pathlib and pathlib3x in different modules, use:
>>> pathlib3x_path.Path.is_path_instance(pathlib3x_path)
True
>>> pathlib3x_path.Path.is_path_instance(pathlib_path)
True
PurePath.replace_parts(old, new, count=-1)

Return a new Path with parts replaced. If the Original Path or old has no parts, the Original Path will be returned. On Windows, the replacement operation is not case sensitive, because of case folding on drives, directory and filenames. You can also replace absolute paths with relative paths what is quite handy - just be aware that the results might look unexpected, especially on Windows.

old, new can be pathlib.Path or Path-like objects

if the Original Path is resolved, You should probably also resolve old and new - because if symlinks are involved, the results might be unexpected.

be aware of case folding in windows, the file “c:/Test/test.txt” is the same as “c:/test/Test.TXT”

>>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz')
>>> p.replace_parts(PureWindowsPath('C:/downloads'), PureWindowsPath('D:/uploads'))
PureWindowsPath('D:/uploads/pathlib.tar.gz')

>>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz')
>>> p.replace_parts('C:/downloads','D:/uploads')
PureWindowsPath('D:/uploads/pathlib.tar.gz')

# handy to replace source directories with target directories on copy or move operations :
>>> source_dir = pathlib.Path('c:/source_dir')
>>> target_dir = pathlib.Path('c:/target_dir')
>>> source_files = source_dir.glob('**/*.txt')
>>> for source in source_files:
        target = source.replace_parts(source_dir, target_dir)
...     source.copy(target)

# this will always return PureWindowsPath(), because PureWindowsPath('.') has no parts to replace
>>> p = PureWindowsPath('.')
>>> p.replace_parts('.', 'test')
PureWindowsPath()

# looks unexpected but is correct, since PureWindowsPath('/uploads') is a relative path in Windows
>>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz')
>>> p.replace_parts('C:/downloads', '/uploads')
PureWindowsPath('uploads/pathlib.tar.gz')

# take care when replace, it might match on parts You are not aware of
>>> p = PureWindowsPath('c:/downloads/Downloads.tar.gz')
>>> p.replace_parts('downloads', 'uploads')
PureWindowsPath('c:/uploads/uploads.tar.gz')    # that was not intended !

# better
>>> p = PureWindowsPath('c:/downloads/Downloads.tar.gz')
>>> p.replace_parts('downloads', 'uploads', 1)
PureWindowsPath('c:/uploads/Downloads.tar.gz')

# much better
>>> p = PureWindowsPath('c:/downloads/Downloads.tar.gz')
>>> p.replace_parts('c:/downloads', 'c:/uploads')
PureWindowsPath('c:/uploads/Downloads.tar.gz')

shutil wrappers

Path.copy(target, follow_symlinks)

wraps shutil.copy, see: https://docs.python.org/3/library/shutil.html

>>> import pathlib3x as pathlib
>>> s = pathlib.Path('c:/Downloads/pathlib.tar.gz')
>>> t = pathlib.Path('c:/Downloads/pathlib.tar.gz.backup')
>>> s.copy(t)
Path.copy2(target, follow_symlinks=True)

wraps shutil.copy2, see: https://docs.python.org/3/library/shutil.html

>>> import pathlib3x as pathlib
>>> s = pathlib.Path('c:/Downloads/pathlib.tar.gz')
>>> t = pathlib.Path('c:/Downloads/pathlib.tar.gz.backup')
>>> s.copy2(t)
Path.copyfile(target, follow_symlinks)

wraps shutil.copyfile, see: https://docs.python.org/3/library/shutil.html

>>> import pathlib3x as pathlib
>>> s = pathlib.Path('c:/Downloads/pathlib.tar.gz')
>>> t = pathlib.Path('c:/Downloads/pathlib.tar.gz.backup')
>>> s.copyfile(t)
Path.copymode(target, follow_symlinks=True)

wraps shutil.copymode, see: https://docs.python.org/3/library/shutil.html

>>> import pathlib3x as pathlib
>>> s = pathlib.Path('c:/Downloads/pathlib.tar.gz')
>>> t = pathlib.Path('c:/Downloads/pathlib.tar.gz.backup')
>>> s.copymode(t)
Path.copystat(target, follow_symlinks=True)

wraps shutil.copystat, see: https://docs.python.org/3/library/shutil.html

>>> import pathlib3x as pathlib
>>> s = pathlib.Path('c:/Downloads/pathlib.tar.gz')
>>> t = pathlib.Path('c:/Downloads/pathlib.tar.gz.backup')
>>> s.copystat(t)
Path.copytree(target, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=True, dirs_exists_ok=False)

wraps shutil.copytree, see: https://docs.python.org/3/library/shutil.html

dirs_exists_ok=True will raise a TypeError on Python Versions < 3.8

>>> import pathlib3x as pathlib
>>> s = pathlib.Path('c:/Downloads')
>>> t = pathlib.Path('c:/temp/Backups')
>>> s.copytree(t)
Path.rmtree(ignore_errors=False, onerror=None)

wraps shutil.rmtree, see: https://docs.python.org/3/library/shutil.html

>>> import pathlib3x as pathlib
>>> p = pathlib.Path('c:/Downloads/old')
>>> p.rmtree()

Caveats of pathlib3x

>>> import pathlib3x
>>> import pathlib

>>> pathlib3x_path = pathlib3x.Path('some_path')  # this might happen in another module !
>>> pathlib_path = pathlib.Path('some_path')
>>> isinstance(pathlib3x_path, pathlib.Path)
False
>>> isinstance(pathlib_path, pathlib3x.Path)
False

# in such cases were You need to mix pathlib and pathlib3x in different modules, use:
>>> pathlib3x_path.Path.is_path_instance(pathlib3x_path)
True
>>> pathlib3x_path.Path.is_path_instance(pathlib_path)
True

So dont mix pathlib with pathlib3x and expect that objects are an instance of Pathlib and vice versa. This can happen easily if You have many Modules. Just keep it in mind !

Usage from Commandline

Usage: pathlib3x [OPTIONS] COMMAND [ARGS]...

  backport of pathlib 3.10 to python 3.6, 3.7, 3.8, 3.9 with a few extensions

Options:
  --version                     Show the version and exit.
  --traceback / --no-traceback  return traceback information on cli
  -h, --help                    Show this message and exit.

Commands:
  info  get program informations

Installation and Upgrade

  • Before You start, its highly recommended to update pip and setup tools:

python -m pip --upgrade pip
python -m pip --upgrade setuptools
  • to install the latest release from PyPi via pip (recommended):

python -m pip install --upgrade pathlib3x
  • to install the latest version from github via pip:

python -m pip install --upgrade git+https://github.com/bitranox/pathlib3x.git
  • include it into Your requirements.txt:

# Insert following line in Your requirements.txt:
# for the latest Release on pypi:
pathlib3x

# for the latest development version :
pathlib3x @ git+https://github.com/bitranox/pathlib3x.git

# to install and upgrade all modules mentioned in requirements.txt:
python -m pip install --upgrade -r /<path>/requirements.txt
  • to install the latest development version from source code:

# cd ~
$ git clone https://github.com/bitranox/pathlib3x.git
$ cd pathlib3x
python setup.py install
  • via makefile: makefiles are a very convenient way to install. Here we can do much more, like installing virtual environments, clean caches and so on.

# from Your shell's homedirectory:
$ git clone https://github.com/bitranox/pathlib3x.git
$ cd pathlib3x

# to run the tests:
$ make test

# to install the package
$ make install

# to clean the package
$ make clean

# uninstall the package
$ make uninstall

Requirements

following modules will be automatically installed :

## Project Requirements
click
cli_exit_tools

Acknowledgements

  • special thanks to “uncle bob” Robert C. Martin, especially for his books on “clean code” and “clean architecture”

Contribute

I would love for you to fork and send me pull request for this project. - please Contribute

License

This software is licensed under the MIT license

Changelog

  • new MAJOR version for incompatible API changes,

  • new MINOR version for added functionality in a backwards compatible manner

  • new PATCH version for backwards compatible bug fixes

v2.0.2.1

2022-06-03: use io.encoding only on 3.10 upwards

v2.0.2

2022-06-03: define __fspath__ only on python >= 3.10

v2.0.1

2022-06-03: use io.encoding only on 3.10 upwards

v2.0.0

2022-06-03:
  • upgrade to pathlib python 3.11a0 version

  • upgrade to github actions @v3

v1.3.9

2020-10-09: service release
  • update travis build matrix for linux 3.9-dev

  • update travis build matrix (paths) for windows 3.9 / 3.10

v1.3.8

2020-08-08: service release
  • fix documentation

  • fix travis

  • deprecate pycodestyle

  • implement flake8

v1.3.7

2020-08-01: fix pypi deploy

v1.3.6

2020-07-31: fix travis build

v0.3.5

2020-07-29: feature release
  • use the new pizzacutter template

  • use cli_exit_tools

v0.3.4

2020-07-15patch release
  • fix cli test

  • enable traceback option on cli errors

v0.3.3

2020-07-15patch release
  • fix minor typos

v0.3.2

2020-07-05patch release
  • fix typo in setup.py setup parameter zip_safe

v0.3.1

2020-07-05patch release
  • fix version issues in the stub files

v0.3.0

2020-07-05added functions, include stub files for typing, setup python_requires
  • added python_requires in setup.py

  • include type stub files, its fully type hinted package now (PEP 561)

  • pep8 fix the standard library code

  • added PurePath.replace_parts

  • added PurePath.is_path_instance

  • added Path.copy

  • added Path.copy2

  • added Path.copyfile

  • added Path.copymode

  • added Path.copystat

  • added Path.copytree

  • added Path.rmtree

v0.2.0

2020-07-02added function: PurePath.append_suffix(suffix)
  • added function: PurePath.append_suffix(suffix)

v0.1.1

2020-07-01: patch release
  • guarded the sys.audit calls with try-except clauses, because sys.event is only avail in python 3.8

v0.1.0

2020-06-29: initial release
  • initial release

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pathlib3x-2.0.2.1.tar.gz (29.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pathlib3x-2.0.2.1-py3.10.egg (44.2 kB view details)

Uploaded Egg

pathlib3x-2.0.2.1-py3.9.egg (43.9 kB view details)

Uploaded Egg

pathlib3x-2.0.2.1-py3.8.egg (43.9 kB view details)

Uploaded Egg

pathlib3x-2.0.2.1-py3.7.egg (43.8 kB view details)

Uploaded Egg

pathlib3x-2.0.2.1-py3.6.egg (43.8 kB view details)

Uploaded Egg

pathlib3x-2.0.2.1-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file pathlib3x-2.0.2.1.tar.gz.

File metadata

  • Download URL: pathlib3x-2.0.2.1.tar.gz
  • Upload date:
  • Size: 29.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.9 tqdm/4.64.0 importlib-metadata/4.2.0 keyring/23.4.1 rfc3986/1.5.0 colorama/0.4.4 CPython/3.6.15

File hashes

Hashes for pathlib3x-2.0.2.1.tar.gz
Algorithm Hash digest
SHA256 88efe37ecb1cb138e2938416002aa72a3f2759d11439dd12511ec9265b6c2a65
MD5 a914a37893f34a041b58c1f9b597dc70
BLAKE2b-256 c762ac549248cd46136cad0053d6da9c81307cd9f2687660659d751f2fc16f67

See more details on using hashes here.

File details

Details for the file pathlib3x-2.0.2.1-py3.10.egg.

File metadata

  • Download URL: pathlib3x-2.0.2.1-py3.10.egg
  • Upload date:
  • Size: 44.2 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.4

File hashes

Hashes for pathlib3x-2.0.2.1-py3.10.egg
Algorithm Hash digest
SHA256 ae71c96cc323725ffe2058172a05751554b4c5807ea1e5762f1814e2c27f1abc
MD5 34a85a9b326f12a56a0ead0c0b98bb4a
BLAKE2b-256 b2a0fd584267532856c9a15411c355295589e3632464b875ca011ab9e4bcb0ea

See more details on using hashes here.

File details

Details for the file pathlib3x-2.0.2.1-py3.9.egg.

File metadata

  • Download URL: pathlib3x-2.0.2.1-py3.9.egg
  • Upload date:
  • Size: 43.9 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.13

File hashes

Hashes for pathlib3x-2.0.2.1-py3.9.egg
Algorithm Hash digest
SHA256 443a5bc4cf5ef1e8082150c0d44ec2fc954129f36899e197480fe9ff5bd00452
MD5 dfe2bb8e29984e29b42722225e5327cc
BLAKE2b-256 7ff38645b1c32a329d270b630376e70d0e8c28cfb0b81617639ee1bef1108c3e

See more details on using hashes here.

File details

Details for the file pathlib3x-2.0.2.1-py3.8.egg.

File metadata

  • Download URL: pathlib3x-2.0.2.1-py3.8.egg
  • Upload date:
  • Size: 43.9 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.8.12

File hashes

Hashes for pathlib3x-2.0.2.1-py3.8.egg
Algorithm Hash digest
SHA256 d0e0947db4cc58e573eea586c9800f4220b35b986cd964ff55adbf7dc668ec2b
MD5 b7ec0ace4a55710b72d53dca02d29ff1
BLAKE2b-256 9de1d5938de047501f907470cfe6efa84203c7600823f16db9dc6fd423444392

See more details on using hashes here.

File details

Details for the file pathlib3x-2.0.2.1-py3.7.egg.

File metadata

  • Download URL: pathlib3x-2.0.2.1-py3.7.egg
  • Upload date:
  • Size: 43.8 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.7.13

File hashes

Hashes for pathlib3x-2.0.2.1-py3.7.egg
Algorithm Hash digest
SHA256 fc7b9c650d2d02cf61340b1b86fc79121c3553b00a967fd3521320b37d1af4bd
MD5 0de9e601fcca7d1582f736318298f8b6
BLAKE2b-256 33e91c222beccf70dcfa3dccd59bf749ee089c33629ca1f911ef51f53a2712f6

See more details on using hashes here.

File details

Details for the file pathlib3x-2.0.2.1-py3.6.egg.

File metadata

  • Download URL: pathlib3x-2.0.2.1-py3.6.egg
  • Upload date:
  • Size: 43.8 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.9 tqdm/4.64.0 importlib-metadata/4.2.0 keyring/23.4.1 rfc3986/1.5.0 colorama/0.4.4 CPython/3.6.15

File hashes

Hashes for pathlib3x-2.0.2.1-py3.6.egg
Algorithm Hash digest
SHA256 cd09e7b529b1e2f2ba0111932fb876fe832b8b5c9714ff8ef85e8d7cff5cf67b
MD5 e7a2e6748051570b9d30e871763855a5
BLAKE2b-256 e5737e43842e5fa54becfacd208cf870d2359e23669038229e0ea5ebe964a507

See more details on using hashes here.

File details

Details for the file pathlib3x-2.0.2.1-py3-none-any.whl.

File metadata

  • Download URL: pathlib3x-2.0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 25.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.9 tqdm/4.64.0 importlib-metadata/4.2.0 keyring/23.4.1 rfc3986/1.5.0 colorama/0.4.4 CPython/3.6.15

File hashes

Hashes for pathlib3x-2.0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c736db3ae4b8aa3c98cbe3f3566f0a185949a7e9c04983d38016c0f8d251f041
MD5 adfdeec53cd08abf602ce7c19737992b
BLAKE2b-256 f5150020c2627d1e628e7148d1fcb100d53b6649a9e5e0d2fdf1a0d30f0a04e5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page