pathlib ABCs: raise UnsupportedOperation directly. (#114776)

Raise `UnsupportedOperation` directly, rather than via an `_unsupported()`
helper, to give human readers and IDEs/typecheckers/etc a bigger hint that
these methods are abstract.
This commit is contained in:
Barney Gale 2024-01-31 00:38:01 +00:00 committed by GitHub
parent a06b606462
commit 1667c28686
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 33 deletions

View file

@ -514,9 +514,8 @@ class Path(_abc.PathBase, PurePath):
as_uri = PurePath.as_uri as_uri = PurePath.as_uri
@classmethod @classmethod
def _unsupported(cls, method_name): def _unsupported_msg(cls, attribute):
msg = f"{cls.__name__}.{method_name}() is unsupported on this system" return f"{cls.__name__}.{attribute} is unsupported on this system"
raise UnsupportedOperation(msg)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
if kwargs: if kwargs:

View file

@ -149,39 +149,39 @@ class PathModuleBase:
""" """
@classmethod @classmethod
def _unsupported(cls, attr): def _unsupported_msg(cls, attribute):
raise UnsupportedOperation(f"{cls.__name__}.{attr} is unsupported") return f"{cls.__name__}.{attribute} is unsupported"
@property @property
def sep(self): def sep(self):
"""The character used to separate path components.""" """The character used to separate path components."""
self._unsupported('sep') raise UnsupportedOperation(self._unsupported_msg('sep'))
def join(self, path, *paths): def join(self, path, *paths):
"""Join path segments.""" """Join path segments."""
self._unsupported('join()') raise UnsupportedOperation(self._unsupported_msg('join()'))
def split(self, path): def split(self, path):
"""Split the path into a pair (head, tail), where *head* is everything """Split the path into a pair (head, tail), where *head* is everything
before the final path separator, and *tail* is everything after. before the final path separator, and *tail* is everything after.
Either part may be empty. Either part may be empty.
""" """
self._unsupported('split()') raise UnsupportedOperation(self._unsupported_msg('split()'))
def splitdrive(self, path): def splitdrive(self, path):
"""Split the path into a 2-item tuple (drive, tail), where *drive* is """Split the path into a 2-item tuple (drive, tail), where *drive* is
a device name or mount point, and *tail* is everything after the a device name or mount point, and *tail* is everything after the
drive. Either part may be empty.""" drive. Either part may be empty."""
self._unsupported('splitdrive()') raise UnsupportedOperation(self._unsupported_msg('splitdrive()'))
def normcase(self, path): def normcase(self, path):
"""Normalize the case of the path.""" """Normalize the case of the path."""
self._unsupported('normcase()') raise UnsupportedOperation(self._unsupported_msg('normcase()'))
def isabs(self, path): def isabs(self, path):
"""Returns whether the path is absolute, i.e. unaffected by the """Returns whether the path is absolute, i.e. unaffected by the
current directory or drive.""" current directory or drive."""
self._unsupported('isabs()') raise UnsupportedOperation(self._unsupported_msg('isabs()'))
class PurePathBase: class PurePathBase:
@ -505,16 +505,15 @@ class PathBase(PurePathBase):
_max_symlinks = 40 _max_symlinks = 40
@classmethod @classmethod
def _unsupported(cls, method_name): def _unsupported_msg(cls, attribute):
msg = f"{cls.__name__}.{method_name}() is unsupported" return f"{cls.__name__}.{attribute} is unsupported"
raise UnsupportedOperation(msg)
def stat(self, *, follow_symlinks=True): def stat(self, *, follow_symlinks=True):
""" """
Return the result of the stat() system call on this path, like Return the result of the stat() system call on this path, like
os.stat() does. os.stat() does.
""" """
self._unsupported("stat") raise UnsupportedOperation(self._unsupported_msg('stat()'))
def lstat(self): def lstat(self):
""" """
@ -703,7 +702,7 @@ class PathBase(PurePathBase):
Open the file pointed by this path and return a file object, as Open the file pointed by this path and return a file object, as
the built-in open() function does. the built-in open() function does.
""" """
self._unsupported("open") raise UnsupportedOperation(self._unsupported_msg('open()'))
def read_bytes(self): def read_bytes(self):
""" """
@ -744,7 +743,7 @@ class PathBase(PurePathBase):
The children are yielded in arbitrary order, and the The children are yielded in arbitrary order, and the
special entries '.' and '..' are not included. special entries '.' and '..' are not included.
""" """
self._unsupported("iterdir") raise UnsupportedOperation(self._unsupported_msg('iterdir()'))
def _scandir(self): def _scandir(self):
# Emulate os.scandir(), which returns an object that can be used as a # Emulate os.scandir(), which returns an object that can be used as a
@ -871,7 +870,7 @@ class PathBase(PurePathBase):
Use resolve() to resolve symlinks and remove '..' segments. Use resolve() to resolve symlinks and remove '..' segments.
""" """
self._unsupported("absolute") raise UnsupportedOperation(self._unsupported_msg('absolute()'))
@classmethod @classmethod
def cwd(cls): def cwd(cls):
@ -886,7 +885,7 @@ class PathBase(PurePathBase):
""" Return a new path with expanded ~ and ~user constructs """ Return a new path with expanded ~ and ~user constructs
(as returned by os.path.expanduser) (as returned by os.path.expanduser)
""" """
self._unsupported("expanduser") raise UnsupportedOperation(self._unsupported_msg('expanduser()'))
@classmethod @classmethod
def home(cls): def home(cls):
@ -898,7 +897,7 @@ class PathBase(PurePathBase):
""" """
Return the path to which the symbolic link points. Return the path to which the symbolic link points.
""" """
self._unsupported("readlink") raise UnsupportedOperation(self._unsupported_msg('readlink()'))
readlink._supported = False readlink._supported = False
def resolve(self, strict=False): def resolve(self, strict=False):
@ -973,7 +972,7 @@ class PathBase(PurePathBase):
Make this path a symlink pointing to the target path. Make this path a symlink pointing to the target path.
Note the order of arguments (link, target) is the reverse of os.symlink. Note the order of arguments (link, target) is the reverse of os.symlink.
""" """
self._unsupported("symlink_to") raise UnsupportedOperation(self._unsupported_msg('symlink_to()'))
def hardlink_to(self, target): def hardlink_to(self, target):
""" """
@ -981,19 +980,19 @@ class PathBase(PurePathBase):
Note the order of arguments (self, target) is the reverse of os.link's. Note the order of arguments (self, target) is the reverse of os.link's.
""" """
self._unsupported("hardlink_to") raise UnsupportedOperation(self._unsupported_msg('hardlink_to()'))
def touch(self, mode=0o666, exist_ok=True): def touch(self, mode=0o666, exist_ok=True):
""" """
Create this file with the given access mode, if it doesn't exist. Create this file with the given access mode, if it doesn't exist.
""" """
self._unsupported("touch") raise UnsupportedOperation(self._unsupported_msg('touch()'))
def mkdir(self, mode=0o777, parents=False, exist_ok=False): def mkdir(self, mode=0o777, parents=False, exist_ok=False):
""" """
Create a new directory at this given path. Create a new directory at this given path.
""" """
self._unsupported("mkdir") raise UnsupportedOperation(self._unsupported_msg('mkdir()'))
def rename(self, target): def rename(self, target):
""" """
@ -1005,7 +1004,7 @@ class PathBase(PurePathBase):
Returns the new Path instance pointing to the target path. Returns the new Path instance pointing to the target path.
""" """
self._unsupported("rename") raise UnsupportedOperation(self._unsupported_msg('rename()'))
def replace(self, target): def replace(self, target):
""" """
@ -1017,13 +1016,13 @@ class PathBase(PurePathBase):
Returns the new Path instance pointing to the target path. Returns the new Path instance pointing to the target path.
""" """
self._unsupported("replace") raise UnsupportedOperation(self._unsupported_msg('replace()'))
def chmod(self, mode, *, follow_symlinks=True): def chmod(self, mode, *, follow_symlinks=True):
""" """
Change the permissions of the path, like os.chmod(). Change the permissions of the path, like os.chmod().
""" """
self._unsupported("chmod") raise UnsupportedOperation(self._unsupported_msg('chmod()'))
def lchmod(self, mode): def lchmod(self, mode):
""" """
@ -1037,31 +1036,31 @@ class PathBase(PurePathBase):
Remove this file or link. Remove this file or link.
If the path is a directory, use rmdir() instead. If the path is a directory, use rmdir() instead.
""" """
self._unsupported("unlink") raise UnsupportedOperation(self._unsupported_msg('unlink()'))
def rmdir(self): def rmdir(self):
""" """
Remove this directory. The directory must be empty. Remove this directory. The directory must be empty.
""" """
self._unsupported("rmdir") raise UnsupportedOperation(self._unsupported_msg('rmdir()'))
def owner(self, *, follow_symlinks=True): def owner(self, *, follow_symlinks=True):
""" """
Return the login name of the file owner. Return the login name of the file owner.
""" """
self._unsupported("owner") raise UnsupportedOperation(self._unsupported_msg('owner()'))
def group(self, *, follow_symlinks=True): def group(self, *, follow_symlinks=True):
""" """
Return the group name of the file gid. Return the group name of the file gid.
""" """
self._unsupported("group") raise UnsupportedOperation(self._unsupported_msg('group()'))
@classmethod @classmethod
def from_uri(cls, uri): def from_uri(cls, uri):
"""Return a new path from the given 'file' URI.""" """Return a new path from the given 'file' URI."""
cls._unsupported("from_uri") raise UnsupportedOperation(cls._unsupported_msg('from_uri()'))
def as_uri(self): def as_uri(self):
"""Return the path as a URI.""" """Return the path as a URI."""
self._unsupported("as_uri") raise UnsupportedOperation(self._unsupported_msg('as_uri()'))