This PEP proposes a protocol for classes which represent a file system path to be able to provide a str or bytes representation. Changes to Python's standard library are also proposed to utilize this protocol where appropriate to facilitate the use of path objects where historically only str and/or bytes file system paths are accepted. The goal is to facilitate the migration of users towards rich path objects while providing an easy way to work with code expecting str or bytes .

Historically in Python, file system paths have been represented as strings or bytes. This choice of representation has stemmed from C's own decision to represent file system paths as const char * . While that is a totally serviceable format to use for file system paths, it's not necessarily optimal. At issue is the fact that while all file system paths can be represented as strings or bytes, not all strings or bytes represent a file system path. This can lead to issues where any e.g. string duck-types to a file system path whether it actually represents a path or not.

To help elevate the representation of file system paths from their representation as strings and bytes to a richer object representation, the pathlib module was provisionally introduced in Python 3.4 through PEP 428. While considered by some as an improvement over strings and bytes for file system paths, it has suffered from a lack of adoption. Typically the key issue listed for the low adoption rate has been the lack of support in the standard library. This lack of support required users of pathlib to manually convert path objects to strings by calling str(path) which many found error-prone.

One issue in converting path objects to strings comes from the fact that the only generic way to get a string representation of the path was to pass the object to str() . This can pose a problem when done blindly as nearly all Python objects have some string representation whether they are a path or not, e.g. str(None) will give a result that builtins.open() will happily use to create a new file.

Exacerbating this whole situation is the DirEntry object . While path objects have a representation that can be extracted using str() , DirEntry objects expose a path attribute instead. Having no common interface between path objects, DirEntry , and any other third-party path library has become an issue. A solution that allows any path-representing object to declare that it is a path and a way to extract a low-level representation that all path objects could support is desired.

This PEP then proposes to introduce a new protocol to be followed by objects which represent file system paths. Providing a protocol allows for explicit signaling of what objects represent file system paths as well as a way to extract a lower-level representation that can be used with older APIs which only support strings or bytes.

Discussions regarding path objects that led to this PEP can be found in multiple threads on the python-ideas mailing list archive for the months of March and April 2016 and on the python-dev mailing list archives during April 2016.