Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] GH-110109: Make pathlib extensible #110321

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions Doc/library/pathlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1591,6 +1591,118 @@ call fails (for example because the path doesn't exist).
.. versionchanged:: 3.10
The *newline* parameter was added.


Virtual paths
-------------

.. class:: PurePathBase(*path_segments)

Abstract base class for path objects without I/O support.

The :class:`PurePath` class is a subclass of this class.

Unlike :class:`PurePath`, this class does not define any of these
magic methods:
:meth:`~os.PathLike.__fspath__`, :meth:`~object.__bytes__`,
:meth:`~object.__reduce__`,
:meth:`~object.__hash__`, :meth:`~object.__eq__`,
:meth:`~object.__lt__`, :meth:`~object.__le__`,
:meth:`~object.__gt__`, :meth:`~object.__ge__`.

.. versionadded:: 3.13


.. class:: PathBase(*path_segments)

Abstract base class for path objects with I/O support.

This class provides abstract implementations for methods that derived
classes can override selectively; the default implementations raise
:exc:`UnsupportedOperation`.

The :class:`Path` class is a subclass of this class that operates on the
local filesystem. User-defined subclasses may operate on other kinds of
filesystem, such as archive files or remote storage; instances of these
classes are *virtual paths*.

Like its superclass :class:`PurePathBase` (and unlike :class:`PurePath` and
:class:`Path`), this class does not define these magic methods:
:meth:`~os.PathLike.__fspath__`, :meth:`~object.__bytes__`,
:meth:`~object.__reduce__`,
:meth:`~object.__hash__`, :meth:`~object.__eq__`,
:meth:`~object.__lt__`, :meth:`~object.__le__`,
:meth:`~object.__gt__`, :meth:`~object.__ge__`.
In all other respects, its interface is the same as :class:`Path`.

The default implementations of the most basic methods, like ``stat()``
and ``iterdir()``, directly raise :exc:`UnsupportedOperation`. Other
methods like ``is_dir()`` and ``glob()`` call through to the basic methods.
The following table shows their relationships:

.. list-table::
:header-rows: 1

* - Basic Methods
- Mixin Methods
* - ``stat()``
- ``lstat()``, ``exists()``, ``resolve()``, ``samefile()``,
``is_dir()``, ``is_file()``, ``is_mount()``, ``is_symlink()``,
``is_block_device()``, ``is_char_device()``, ``is_fifo()``,
``is_socket()``
* - ``open()``
- ``read_text()``, ``write_text()``,
``read_bytes()``, ``write_bytes()``
* - ``iterdir()`` and ``stat()``
- ``glob()``, ``rglob()``, ``walk()``
* - ``chmod()``
- ``lchmod()``
* - ``expanduser()``
- ``home()``
* - ``absolute()``
- ``cwd()``
* - ``symlink_to()``, ``hardlink_to()``, ``mkdir()``, ``touch()``,
``rename()``, ``replace()``, ``unlink()``, ``rmdir()``,
``owner()``, ``group()``, ``from_uri()``, ``as_uri()``,
``is_junction()``
- No mixin methods

These methods are described in the documentation for
:ref:`concrete paths <concrete-paths>`. That said, some methods deserve
special attention:

.. method:: stat(*, follow_symlinks=True)

Returns information about the path.

The default implementation of this method immediately raises
:exc:`UnsupportedOperation`. Subclasses that override this method should
return an object that resembles a :class:`~os.stat_result`; it should at
least have ``st_mode``, ``st_dev`` and ``st_ino`` attributes.

.. method:: resolve(strict=False)

Resolves symlinks and eliminates ``..`` path components. If supported,
make the path absolute.

The default implementation of this method first calls
``absolute()``, but suppresses any resulting :exc:`UnsupportedOperation`
exception; this allows paths to be resolved on filesystems that lack
a notion of a working directory. It calls ``stat()`` on each ancestor
path, and ``readlink()`` when a stat result indicates a symlink.
:exc:`OSError` is raised if more than 40 symlinks are encountered while
resolving a path; this is taken to indicate a loop.

.. method:: is_junction()

Returns ``True`` if the path points to a junction.

The default implementation of this method returns ``False`` rather than
raising :exc:`UnsupportedOperation`, because junctions are almost never
available in virtual filesystems.

.. versionadded:: 3.13


Correspondence to tools in the :mod:`os` module
-----------------------------------------------

Expand Down
6 changes: 6 additions & 0 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,12 @@ os
pathlib
-------

* Add :class:`pathlib.PurePathBase` and :class:`~pathlib.PathBase` abstract
base classes. Users can subclass :class:`~pathlib.PathBase` to implement
*virtual paths*: objects representing paths in archive files, on remote
storage systems, and so forth.
(Contributed by Barney Gale in :gh:`110109`.)

* Add :exc:`pathlib.UnsupportedOperation`, which is raised instead of
:exc:`NotImplementedError` when a path operation isn't supported.
(Contributed by Barney Gale in :gh:`89812`.)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Add :class:`pathlib.PurePathBase` and :class:`~pathlib.PathBase` abstract
base classes. Users can subclass :class:`pathlib.PathBase` to implement
*virtual paths*: objects that represent paths in archive files, remote
storage systems, disc images, etc.