GH-128520: pathlib ABCs: improve protocol for 'openable' objects (#134101)

Rename `pathlib._os.magic_open()` to `vfsopen()`. The new name is a bit
less abstract, and it aligns with the `vfspath()` method added in 5dbd27d.

Per discussion on discourse[^1], adjust `vfsopen()` so that the following
methods may be called:

- `__open_reader__()`
- `__open_writer__(mode)`
- `__open_updater__(mode)`

These three methods return readable, writable, and full duplex file objects
respectively. In the 'writer' method, *mode* is either 'a', 'w' or 'x'. In
the 'updater' method, *mode* is either 'r' or 'w'.

In the pathlib ABCs, replace `ReadablePath.__open_rb__()` with
`__open_reader__()`, and replace `WritablePath.__open_wb__()` with
`__open_writer__()`.

[^1]: https://discuss.python.org/t/open-able-objects/90238

Co-authored-by: Petr Viktorin <encukou@gmail.com>
This commit is contained in:
Barney Gale 2025-09-12 22:25:18 +01:00 committed by GitHub
parent 2e8f64c931
commit 805e3368d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 114 additions and 64 deletions

View file

@ -264,13 +264,13 @@ def info(self):
tree = self.zip_file.filelist.tree
return tree.resolve(vfspath(self), follow_symlinks=False)
def __open_rb__(self, buffering=-1):
def __open_reader__(self):
info = self.info.resolve()
if not info.exists():
raise FileNotFoundError(errno.ENOENT, "File not found", self)
elif info.is_dir():
raise IsADirectoryError(errno.EISDIR, "Is a directory", self)
return self.zip_file.open(info.zip_info, 'r')
return self.zip_file.open(info.zip_info)
def iterdir(self):
info = self.info.resolve()
@ -320,8 +320,8 @@ def __repr__(self):
def with_segments(self, *pathsegments):
return type(self)(*pathsegments, zip_file=self.zip_file)
def __open_wb__(self, buffering=-1):
return self.zip_file.open(vfspath(self), 'w')
def __open_writer__(self, mode):
return self.zip_file.open(vfspath(self), mode)
def mkdir(self, mode=0o777):
zinfo = zipfile.ZipInfo(vfspath(self) + '/')