Object-oriented file system path manipulation

Overview
tests Code style: Black https://readthedocs.org/projects/path/badge/?version=latest https://tidelift.com/badges/package/pypi/path

path (aka path pie, formerly path.py) implements path objects as first-class entities, allowing common operations on files to be invoked on those path objects directly. For example:

from path import Path

d = Path("/home/guido/bin")
for f in d.files("*.py"):
    f.chmod(0o755)

# Globbing
for f in d.files("*.py"):
    f.chmod("u+rwx")

# Changing the working directory:
with Path("somewhere"):
    # cwd in now `somewhere`
    ...

# Concatenate paths with /
foo_txt = Path("bar") / "foo.txt"

Path pie is hosted at Github.

Find the documentation here.

Guides and Testimonials

Yasoob wrote the Python 101 Writing a Cleanup Script based on path.

Advantages

Python 3.4 introduced pathlib, which shares many characteristics with path. In particular, it provides an object encapsulation for representing filesystem paths. One may have imagined pathlib would supersede path.

But the implementation and the usage quickly diverge, and path has several advantages over pathlib:

  • path implements Path objects as a subclass of str, and as a result these Path objects may be passed directly to other APIs that expect simple text representations of paths, whereas with pathlib, one must first cast values to strings before passing them to APIs unaware of pathlib. This shortcoming was addressed by PEP 519, in Python 3.6.
  • path goes beyond exposing basic functionality of a path and exposes commonly-used behaviors on a path, providing methods like rmtree (from shlib) and remove_p (remove a file if it exists).
  • As a PyPI-hosted package, path is free to iterate faster than a stdlib package. Contributions are welcome and encouraged.
  • path provides a uniform abstraction over its Path object, freeing the implementer to subclass it readily. One cannot subclass a pathlib.Path to add functionality, but must subclass Path, PosixPath, and WindowsPath, even if one only wishes to add a __dict__ to the subclass instances. path instead allows the Path.module object to be overridden by subclasses, defaulting to the os.path. Even advanced uses of path.Path that subclass the model do not need to be concerned with OS-specific nuances.

Alternatives

In addition to pathlib, the pylib project implements a LocalPath class, which shares some behaviors and interfaces with path.

Development

To install a development version, use the Github links to clone or download a snapshot of the latest code. Alternatively, if you have git installed, you may be able to use pip to install directly from the repository:

pip install git+https://github.com/jaraco/path.git

Testing

Tests are invoked with tox. After having installed tox, simply invoke tox in a checkout of the repo to invoke the tests.

Tests are also run in continuous integration. See the badges above for links to the CI runs.

Releasing

Tagged releases are automatically published to PyPI by Azure Pipelines, assuming the tests pass.

Origins

The path.py project was initially released in 2003 by Jason Orendorff and has been continuously developed and supported by several maintainers over the years.

For Enterprise

Available as part of the Tidelift Subscription.

This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.

Learn more.

Security Contact

To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure.

Comments
  • Fully support surrogate escaping with python 2

    Fully support surrogate escaping with python 2

    Currently there is partial support for the python 3 surrogate escaping when reading names from the file.system which were not encoded in the declared filesystem encoding in python 2. The problem with this support is that it is unable to encode the file names back to the original bytes in order to take any action on said files/directories. This pull aims to fix that, and allow the same support for these 'invalid' file names on python 2 as we currently have for python 3.

    • Bytes round trip from FS -> Path -> FS properly on PY2
    • ~~Path objects instantiated with bytes works~~
    • Add fs_path property to get path compatible with os methods, use internally when calling os functions
    • ~~Add __bytes__ (__str__ on PY2) method to convert to FS bytes (fix #73, although I don't know if there are any cases surrogateescape doesn't handle that will still warn)~~
    opened by gazpachoking 22
  • Add

    Add "config_dir" class method.

    I'd like to add a classmethod, "config_dir":

    @classmethod
    def config_dir(cls, app_name):
        """
        Return a path object referencing a suitable config
        directory for the relevant platform. Honors the
        `XDG Base Directory Specification
        <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_
        on Unix and App Data conventions on Windows.
        Ensures that directory exists.
        """
    

    Thoughts?

    enhancement 
    opened by jaraco 19
  • Pylint gets confused: No name 'path' in module 'path'

    Pylint gets confused: No name 'path' in module 'path'

    Pylint doesn't understand that path.py defines the name "path". It does so with the @alias decorator, which is only used once in the file. So there are six extra lines of code to define a decorator which only serves to confuse pylint.

    Would you mind getting rid of the decorator and replacing it with path = Path? Then pylint will understand.

    opened by nedbat 18
  • Crash on walk with errors set to warn

    Crash on walk with errors set to warn

    Seems there can be an issue creating the warning text when using the walk method in warn mode. I suspect this might only happen on python 2.

      File "/usr/lib64/python2.7/site-packages/flexget/plugins/filter/exists.py", line 44, in on_task_filter
        for p in folder.walk(errors='warn'):
      File "/usr/lib64/python2.7/site-packages/path.py", line 576, in walk
        TreeWalkWarning)
      File "/usr/lib64/python2.7/warnings.py", line 29, in _show_warning
        file.write(formatwarning(message, category, filename, lineno, line))
      File "/usr/lib64/python2.7/warnings.py", line 38, in formatwarning
        s =  "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 46-60: ordinal not in range(128)
    
    wontfix 
    opened by gazpachoking 17
  • Why is not `Path(

    Why is not `Path("test.txt").parent.parent` a valid path?

    Hello.

    I love the concept of path.py, but this is the first time I use it and I am a bit disappointed.

    While working with relative paths, I was wondering why Path("test.txt").parent.parent and Path("test.txt").parent return both "" instead of "../somefolder/" and ".".

    My use case is very simple. The user gives me some string path where I need to create a file. So, I first need to create the folder where the file will be located.

    Path("test.txt").parent.makedirs_p()
    

    This raises a FileNotFoundError because path Path('') does not exist.

    By extension, I notice that parent.parent will unfortunately not return a relative path starting with ...

    I have the feeling that we miss the opportunity for a very useful feature here.

    Do you think this would make sense to implement this?

    opened by Delgan 16
  • Cannot walk path on Linux/Python 2 made of non-unicode/non-fs-decodable bytes

    Cannot walk path on Linux/Python 2 made of non-unicode/non-fs-decodable bytes

    On Linux/Python 2/path.py 10.3.1 I am trying to walkfiles() a path that contains a file name which is raw bytes. The specific of this path is that it is not in the fs.encoding (which is UTF-8) and therefore cannot be decoded to unicode as-is, unless I guess surrogate escape are used or something else.

    With os.walk it works when the top is bytes, but fails if the top is unicode.

    With path.py it fails both when using a bytes or unicode top input. You can see the tests here: https://github.com/nexB/scancode-toolkit/pull/723/files#diff-ada144052a705a1e2fc3c96a033cc425R552

    And the test failures are visible here:

    • https://travis-ci.org/nexB/scancode-toolkit/jobs/264691364#L1786
    • https://travis-ci.org/nexB/scancode-toolkit/jobs/264691364#L1907
    opened by pombredanne 13
  • New maintainer needed

    New maintainer needed

    The time has come for me to step back and limit my involvement in this project. In order to avoid it being abandoned, I'd like to identify a successor to take over maintenance. I'm happy to mentor a new maintainer and contribute incidentally, but a volunteer is needed to maintain the project. I would like to transfer the repository and assign ownership to the path.py project in PyPI. Please express your interest here (preferred) or message me privately if appropriate.

    opened by jaraco 10
  • add ifiles and idirs for case insensitive fnmatching.

    add ifiles and idirs for case insensitive fnmatching.

    first compile regex for fnmatch then apply the match using the case insensitive re flag.

    Honestly.. this may just be a crazy corner case.. I work with satellite imagery and it's nice to be able to match .TIF and .tif and .TiF

    opened by whardier 10
  • path.walkdirs() unicode problem

    path.walkdirs() unicode problem

    Traceback (most recent call last):
      File "./cleanup.py", line 104, in <module>
        for subdir in reversed(list(path(dir).walkdirs())):
      File "/usr/local/lib/python2.7/dist-packages/path.py", line 535, in walkdirs
        dirs = self.dirs()
      File "/usr/local/lib/python2.7/dist-packages/path.py", line 450, in dirs
        return [p for p in self.listdir(pattern) if p.isdir()]
      File "/usr/local/lib/python2.7/dist-packages/path.py", line 437, in listdir
        return [self / child for child in names]
      File "/usr/local/lib/python2.7/dist-packages/path.py", line 201, in __div__
        return self._next_class(self.module.join(self, rel))
      File "/usr/lib/python2.7/posixpath.py", line 69, in join
        path +=  b
      File "/usr/local/lib/python2.7/dist-packages/path.py", line 185, in __add__
        return self._next_class(super(path, self).__add__(more))
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xb0 in position 11: ordinal not in range(128)
    
    opened by franciscolourenco 10
  • pip install fails to find a version to install

    pip install fails to find a version to install

    Py version should not be specified as it's available for py2&3. It causes below pip install error:

    $ pip install path.py
    Collecting path.py
      Could not find a version that satisfies the requirement path.py (from versions: )
    No matching distribution found for path.py
    

    pathpy_bug

    opened by lixxu 9
  • question: why isn't `self` used as `src` for shutil-functions?

    question: why isn't `self` used as `src` for shutil-functions?

    ciao,

    i'm thinking about using the path.py-module in a project.

    but i found it counter-intuitive and less effective in terms of simplifying my code when i stumpled over the fact that an instance isn't used as src-argument for the functions from shutil like copy etc. i wonder if this is intentional.

    if it is not, i would work on patches to achieve that behaviour.

    would you be interested in methods that allow merging filetrees from / to another?

    opened by funkyfuture 9
  • Add method to see the setted permissions

    Add method to see the setted permissions

    With path you can set file permissions with the chmod method, but you can't "get it back" without using the os module.

    Example usage:

    from path import Path
    p = Path('example_file')
    p.chmod(0o777)
    
    do_stuff()
    ...
    
    # how to get the permissions from file p?
    import os
    permission = os.stat(p).st_mode & 0o777 # permissions = 438
    print(f"permissions = {oct(permission)}") # permissions = '0o666'
    
    # possible implementation
    permission = p.st_mode() # permissions = 438
    permission_oct = p.st_mode(oct_str = True) # permission_oct = '0o666'
    

    I think this would be a nice addition to the project.

    opened by Sclafus 1
  • Add stacklevel=2 in deprecation warning

    Add stacklevel=2 in deprecation warning

    Hi,

    Could you add a stacklevel of as least 2 in

    https://github.com/jaraco/path/blob/6debbcecd357c30b080ea19bf2cfa0e2ab0fcd50/path/init.py#L682

    So that the user can know which code call the function. Without a stacklevel of as least 2, it will only show the deprecation warning originating from path/__init__.py.

    opened by char101 0
Releases(v16.6.0)
Owner
Jason R. Coombs
Jason R. Coombs
Vericopy - This Python script provides various usage modes for secure local file copying and hashing.

Vericopy This Python script provides various usage modes for secure local file copying and hashing. Hash data is captured and logged for paths before

15 Nov 05, 2022
Various technical documentation, in electronically parseable format

a-pile-of-documentation Various technical documentation, in electronically parseable format. You will need Python 3 to run the scripts and programs in

Jonathan Campbell 2 Nov 20, 2022
CleverCSV is a Python package for handling messy CSV files.

CleverCSV is a Python package for handling messy CSV files. It provides a drop-in replacement for the builtin CSV module with improved dialect detection, and comes with a handy command line applicati

The Alan Turing Institute 1k Dec 19, 2022
Object-oriented file system path manipulation

path (aka path pie, formerly path.py) implements path objects as first-class entities, allowing common operations on files to be invoked on those path

Jason R. Coombs 1k Dec 28, 2022
Yadl - it is a simple library for working with both dotenv files and environment variables.

Yadl Yadl - it is a simple library for working with both dotenv files and environment variables. Features Validation of whitespaces. Validation of num

Ivan Kapranov 3 Oct 19, 2021
LightCSV - This CSV reader is implemented in just pure Python.

LightCSV Simple light CSV reader This CSV reader is implemented in just pure Python. It allows to specify a separator, a quote char and column titles

Jose Rodriguez 6 Mar 05, 2022
CSV To VCF (Multiples en un archivo)

CSV To VCF Convierte archivo CSV a Tarjeta VCF (varias en una) How to use En main.py debes reemplazar CONTACTOS.csv por tu archivo csv, y debes respet

Jorge Ivaldi 2 Jan 12, 2022
Python virtual filesystem for SQLite to read from and write to S3

Python virtual filesystem for SQLite to read from and write to S3

Department for International Trade 70 Jan 04, 2023
Pti-file-format - Reverse engineering the Polyend Tracker instrument file format

pti-file-format Reverse engineering the Polyend Tracker instrument file format.

Jaap Roes 14 Dec 30, 2022
A python module to parse text files with contains secret variables.

A python module to parse text files with contains secret variables.

0 Dec 05, 2022
This project is a set of programs that I use to create a README.md file.

🤖 codex-readme 📜 codex-readme What is it? This project is a set of programs that I use to create a README.md file. How does it work? It reads progra

Tom Dörr 224 Jan 07, 2023
Python function to stream unzip all the files in a ZIP archive: without loading the entire ZIP file or any of its files into memory at once

Python function to stream unzip all the files in a ZIP archive: without loading the entire ZIP file or any of its files into memory at once

Department for International Trade 206 Jan 02, 2023
Convert All TXT Files To One File.

AllToOne Convert All TXT Files To One File. Hi 👋 , I'm Alireza A Python Developer Boy 🔭 I’m currently working on my C# projects 🌱 I’m currently Lea

4 Jun 07, 2022
Simple archive format designed for quickly reading some files without extracting the entire archive

Simple archive format designed for quickly reading some files without extracting the entire archive

Jarred Sumner 336 Dec 30, 2022
A simple bulk file renamer, written in python.

Python File Editor A simple bulk file renamer, written in python. There are two functions, the bulk rename and the bulk file extention change. Bulk Fi

Sam Bloomfield 2 Dec 22, 2021
csv2ir is a script to convert ir .csv files to .ir files for the flipper.

csv2ir csv2ir is a script to convert ir .csv files to .ir files for the flipper. For a repo of .ir files, please see https://github.com/logickworkshop

Alex 38 Dec 31, 2022
Provides a convenient way to append numpy arrays to a file.

Provides a convenient way to append numpy arrays to a file. The NpendWriter and NpendReader classes are used to write and read numpy arrays respective

3 May 14, 2022
Python's Filesystem abstraction layer

PyFilesystem2 Python's Filesystem abstraction layer. Documentation Wiki API Documentation GitHub Repository Blog Introduction Think of PyFilesystem's

pyFilesystem 1.8k Jan 02, 2023
Python code snippets for extracting PDB codes from .fasta files

Python_snippets_for_bioinformatics Python code snippets for extracting PDB codes from .fasta files If you have a single .fasta file for all protein se

Sofi-Mukhtar 3 Feb 09, 2022
This program can help you to move and rename many files at once

This program can help you to rename and save many files in a folder in seconds, but don't give the same name to files, it can delete both files.

João Assalim 1 Oct 10, 2022