SkillAgentSearch skills...

Pathlib3x

backport of latest pathlib (3.10.a0) to python 3.6 and newer with a few extensions

Install / Use

/learn @bitranox/Pathlib3x
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

pathlib3x

Version v2.0.3 as of 2023-07-20 see Changelog_

|build_badge| |codeql| |license| |pypi| |pypi-downloads| |black| |codecov| |cc_maintain| |cc_issues| |cc_coverage| |snyk|

.. |build_badge| image:: https://github.com/bitranox/pathlib3x/actions/workflows/python-package.yml/badge.svg :target: https://github.com/bitranox/pathlib3x/actions/workflows/python-package.yml

.. |codeql| image:: https://github.com/bitranox/pathlib3x/actions/workflows/codeql-analysis.yml/badge.svg?event=push :target: https://github.com//bitranox/pathlib3x/actions/workflows/codeql-analysis.yml

.. |license| image:: https://img.shields.io/github/license/webcomics/pywine.svg :target: http://en.wikipedia.org/wiki/MIT_License

.. |jupyter| image:: https://mybinder.org/badge_logo.svg :target: https://mybinder.org/v2/gh/bitranox/pathlib3x/master?filepath=pathlib3x.ipynb

.. for the pypi status link note the dashes, not the underscore ! .. |pypi| image:: https://img.shields.io/pypi/status/pathlib3x?label=PyPI%20Package :target: https://badge.fury.io/py/pathlib3x

.. |codecov| image:: https://img.shields.io/codecov/c/github/bitranox/pathlib3x :target: https://codecov.io/gh/bitranox/pathlib3x

.. |cc_maintain| image:: https://img.shields.io/codeclimate/maintainability-percentage/bitranox/pathlib3x?label=CC%20maintainability :target: https://codeclimate.com/github/bitranox/pathlib3x/maintainability :alt: Maintainability

.. |cc_issues| image:: https://img.shields.io/codeclimate/issues/bitranox/pathlib3x?label=CC%20issues :target: https://codeclimate.com/github/bitranox/pathlib3x/maintainability :alt: Maintainability

.. |cc_coverage| image:: https://img.shields.io/codeclimate/coverage/bitranox/pathlib3x?label=CC%20coverage :target: https://codeclimate.com/github/bitranox/pathlib3x/test_coverage :alt: Code Coverage

.. |snyk| image:: https://snyk.io/test/github/bitranox/pathlib3x/badge.svg :target: https://snyk.io/test/github/bitranox/pathlib3x

.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg :target: https://github.com/psf/black

.. |pypi-downloads| image:: https://img.shields.io/pypi/dm/pathlib3x :target: https://pypi.org/project/pathlib3x/ :alt: PyPI - Downloads

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 :

.. code-block::

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 :

.. code-block::

import pathlib

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

but that clutters the code unnecessarily. So just use :

.. code-block::

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 :

.. code-block::

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, Github Actions, Documentation, Badges, etc. are managed with PizzaCutter <https://github .com/bitranox/PizzaCutter>_ (cookiecutter on steroids)

Python version required: 3.8.0 or newer

tested on recent linux with python 3.8, 3.9, 3.10, 3.11, 3.12-dev, pypy-3.9, pypy-3.10 - architectures: amd64

100% (for my added functions) code coverage <https://codeclimate.com/github/bitranox/pathlib3x/test_coverage>, flake8 style checking ,mypy static type checking ,tested under Linux, macOS, Windows <https://github.com/bitranox/pathlib3x/actions/workflows/python-package.yml>, automatic daily builds and monitoring


  • Usage_
  • Usage from Commandline_
  • Installation and Upgrade_
  • Requirements_
  • Acknowledgements_
  • Contribute_
  • Report Issues <https://github.com/bitranox/pathlib3x/blob/master/ISSUE_TEMPLATE.md>_
  • Pull Request <https://github.com/bitranox/pathlib3x/blob/master/PULL_REQUEST_TEMPLATE.md>_
  • Code of Conduct <https://github.com/bitranox/pathlib3x/blob/master/CODE_OF_CONDUCT.md>_
  • License_
  • Changelog_

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.

.. code-block:: python

>>> 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

.. code-block:: python

>>> 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"

.. code-block:: python

>>> 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

.. code-block:: python

>>> 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

.. code-block:: python

>>> 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

.. code-block:: python

>>> import pathlib3x as pat
View on GitHub
GitHub Stars14
CategoryDevelopment
Updated1mo ago
Forks3

Languages

Python

Security Score

95/100

Audited on Feb 21, 2026

No findings