bpo-43012: remove pathlib._Accessor
(GH-25701) · python/cpython@08f8301 (original) (raw)
`@@ -275,93 +275,6 @@ def make_uri(self, path):
`
275
275
`_posix_flavour = _PosixFlavour()
`
276
276
``
277
277
``
278
``
`-
class _Accessor:
`
279
``
`-
"""An accessor implements a particular (system-specific or not) way of
`
280
``
`-
accessing paths on the filesystem."""
`
281
``
-
282
``
-
283
``
`-
class _NormalAccessor(_Accessor):
`
284
``
-
285
``
`-
stat = os.stat
`
286
``
-
287
``
`-
open = io.open
`
288
``
-
289
``
`-
listdir = os.listdir
`
290
``
-
291
``
`-
scandir = os.scandir
`
292
``
-
293
``
`-
chmod = os.chmod
`
294
``
-
295
``
`-
mkdir = os.mkdir
`
296
``
-
297
``
`-
unlink = os.unlink
`
298
``
-
299
``
`-
if hasattr(os, "link"):
`
300
``
`-
link = os.link
`
301
``
`-
else:
`
302
``
`-
def link(self, src, dst):
`
303
``
`-
raise NotImplementedError("os.link() not available on this system")
`
304
``
-
305
``
`-
rmdir = os.rmdir
`
306
``
-
307
``
`-
rename = os.rename
`
308
``
-
309
``
`-
replace = os.replace
`
310
``
-
311
``
`-
if hasattr(os, "symlink"):
`
312
``
`-
symlink = os.symlink
`
313
``
`-
else:
`
314
``
`-
def symlink(self, src, dst, target_is_directory=False):
`
315
``
`-
raise NotImplementedError("os.symlink() not available on this system")
`
316
``
-
317
``
`-
def touch(self, path, mode=0o666, exist_ok=True):
`
318
``
`-
if exist_ok:
`
319
``
`-
First try to bump modification time
`
320
``
`-
Implementation note: GNU touch uses the UTIME_NOW option of
`
321
``
`-
the utimensat() / futimens() functions.
`
322
``
`-
try:
`
323
``
`-
os.utime(path, None)
`
324
``
`-
except OSError:
`
325
``
`-
Avoid exception chaining
`
326
``
`-
pass
`
327
``
`-
else:
`
328
``
`-
return
`
329
``
`-
flags = os.O_CREAT | os.O_WRONLY
`
330
``
`-
if not exist_ok:
`
331
``
`-
flags |= os.O_EXCL
`
332
``
`-
fd = os.open(path, flags, mode)
`
333
``
`-
os.close(fd)
`
334
``
-
335
``
`-
if hasattr(os, "readlink"):
`
336
``
`-
readlink = os.readlink
`
337
``
`-
else:
`
338
``
`-
def readlink(self, path):
`
339
``
`-
raise NotImplementedError("os.readlink() not available on this system")
`
340
``
-
341
``
`-
def owner(self, path):
`
342
``
`-
try:
`
343
``
`-
import pwd
`
344
``
`-
return pwd.getpwuid(self.stat(path).st_uid).pw_name
`
345
``
`-
except ImportError:
`
346
``
`-
raise NotImplementedError("Path.owner() is unsupported on this system")
`
347
``
-
348
``
`-
def group(self, path):
`
349
``
`-
try:
`
350
``
`-
import grp
`
351
``
`-
return grp.getgrgid(self.stat(path).st_gid).gr_name
`
352
``
`-
except ImportError:
`
353
``
`-
raise NotImplementedError("Path.group() is unsupported on this system")
`
354
``
-
355
``
`-
getcwd = os.getcwd
`
356
``
-
357
``
`-
expanduser = staticmethod(os.path.expanduser)
`
358
``
-
359
``
`-
realpath = staticmethod(os.path.realpath)
`
360
``
-
361
``
-
362
``
`-
_normal_accessor = _NormalAccessor()
`
363
``
-
364
``
-
365
278
`#
`
366
279
`# Globbing helpers
`
367
280
`#
`
`@@ -402,7 +315,7 @@ def select_from(self, parent_path):
`
402
315
`path_cls = type(parent_path)
`
403
316
`is_dir = path_cls.is_dir
`
404
317
`exists = path_cls.exists
`
405
``
`-
scandir = parent_path._accessor.scandir
`
``
318
`+
scandir = path_cls._scandir
`
406
319
`if not is_dir(parent_path):
`
407
320
`return iter([])
`
408
321
`return self._select_from(parent_path, is_dir, exists, scandir)
`
`@@ -949,7 +862,6 @@ class Path(PurePath):
`
949
862
` object. You can also instantiate a PosixPath or WindowsPath directly,
`
950
863
` but cannot instantiate a WindowsPath on a POSIX system or vice versa.
`
951
864
` """
`
952
``
`-
_accessor = _normal_accessor
`
953
865
`slots = ()
`
954
866
``
955
867
`def new(cls, *args, **kwargs):
`
`@@ -988,7 +900,7 @@ def cwd(cls):
`
988
900
`"""Return a new path pointing to the current working directory
`
989
901
` (as returned by os.getcwd()).
`
990
902
` """
`
991
``
`-
return cls(cls._accessor.getcwd())
`
``
903
`+
return cls(os.getcwd())
`
992
904
``
993
905
`@classmethod
`
994
906
`def home(cls):
`
`@@ -1005,16 +917,22 @@ def samefile(self, other_path):
`
1005
917
`try:
`
1006
918
`other_st = other_path.stat()
`
1007
919
`except AttributeError:
`
1008
``
`-
other_st = self._accessor.stat(other_path)
`
``
920
`+
other_st = self.class(other_path).stat()
`
1009
921
`return os.path.samestat(st, other_st)
`
1010
922
``
1011
923
`def iterdir(self):
`
1012
924
`"""Iterate over the files in this directory. Does not yield any
`
1013
925
` result for the special paths '.' and '..'.
`
1014
926
` """
`
1015
``
`-
for name in self._accessor.listdir(self):
`
``
927
`+
for name in os.listdir(self):
`
1016
928
`yield self._make_child_relpath(name)
`
1017
929
``
``
930
`+
def _scandir(self):
`
``
931
`+
bpo-24132: a future version of pathlib will support subclassing of
`
``
932
`+
pathlib.Path to customize how the filesystem is accessed. This
`
``
933
`+
includes scandir(), which is used to implement glob().
`
``
934
`+
return os.scandir(self)
`
``
935
+
1018
936
`def glob(self, pattern):
`
1019
937
`"""Iterate over this subtree and yield all existing files (of any
`
1020
938
` kind, including directories) matching the given relative pattern.
`
`@@ -1050,7 +968,7 @@ def absolute(self):
`
1050
968
` """
`
1051
969
`if self.is_absolute():
`
1052
970
`return self
`
1053
``
`-
return self._from_parts([self._accessor.getcwd()] + self._parts)
`
``
971
`+
return self._from_parts([self.cwd()] + self._parts)
`
1054
972
``
1055
973
`def resolve(self, strict=False):
`
1056
974
`"""
`
`@@ -1064,7 +982,7 @@ def check_eloop(e):
`
1064
982
`raise RuntimeError("Symlink loop from %r" % e.filename)
`
1065
983
``
1066
984
`try:
`
1067
``
`-
s = self._accessor.realpath(self, strict=strict)
`
``
985
`+
s = os.path.realpath(self, strict=strict)
`
1068
986
`except OSError as e:
`
1069
987
`check_eloop(e)
`
1070
988
`raise
`
`@@ -1084,19 +1002,28 @@ def stat(self, *, follow_symlinks=True):
`
1084
1002
` Return the result of the stat() system call on this path, like
`
1085
1003
` os.stat() does.
`
1086
1004
` """
`
1087
``
`-
return self._accessor.stat(self, follow_symlinks=follow_symlinks)
`
``
1005
`+
return os.stat(self, follow_symlinks=follow_symlinks)
`
1088
1006
``
1089
1007
`def owner(self):
`
1090
1008
`"""
`
1091
1009
` Return the login name of the file owner.
`
1092
1010
` """
`
1093
``
`-
return self._accessor.owner(self)
`
``
1011
`+
try:
`
``
1012
`+
import pwd
`
``
1013
`+
return pwd.getpwuid(self.stat().st_uid).pw_name
`
``
1014
`+
except ImportError:
`
``
1015
`+
raise NotImplementedError("Path.owner() is unsupported on this system")
`
1094
1016
``
1095
1017
`def group(self):
`
1096
1018
`"""
`
1097
1019
` Return the group name of the file gid.
`
1098
1020
` """
`
1099
``
`-
return self._accessor.group(self)
`
``
1021
+
``
1022
`+
try:
`
``
1023
`+
import grp
`
``
1024
`+
return grp.getgrgid(self.stat().st_gid).gr_name
`
``
1025
`+
except ImportError:
`
``
1026
`+
raise NotImplementedError("Path.group() is unsupported on this system")
`
1100
1027
``
1101
1028
`def open(self, mode='r', buffering=-1, encoding=None,
`
1102
1029
`errors=None, newline=None):
`
`@@ -1106,8 +1033,7 @@ def open(self, mode='r', buffering=-1, encoding=None,
`
1106
1033
` """
`
1107
1034
`if "b" not in mode:
`
1108
1035
`encoding = io.text_encoding(encoding)
`
1109
``
`-
return self._accessor.open(self, mode, buffering, encoding, errors,
`
1110
``
`-
newline)
`
``
1036
`+
return io.open(self, mode, buffering, encoding, errors, newline)
`
1111
1037
``
1112
1038
`def read_bytes(self):
`
1113
1039
`"""
`
`@@ -1148,21 +1074,38 @@ def readlink(self):
`
1148
1074
`"""
`
1149
1075
` Return the path to which the symbolic link points.
`
1150
1076
` """
`
1151
``
`-
path = self._accessor.readlink(self)
`
1152
``
`-
return self._from_parts((path,))
`
``
1077
`+
if not hasattr(os, "readlink"):
`
``
1078
`+
raise NotImplementedError("os.readlink() not available on this system")
`
``
1079
`+
return self._from_parts((os.readlink(self),))
`
1153
1080
``
1154
1081
`def touch(self, mode=0o666, exist_ok=True):
`
1155
1082
`"""
`
1156
1083
` Create this file with the given access mode, if it doesn't exist.
`
1157
1084
` """
`
1158
``
`-
self._accessor.touch(self, mode, exist_ok)
`
``
1085
+
``
1086
`+
if exist_ok:
`
``
1087
`+
First try to bump modification time
`
``
1088
`+
Implementation note: GNU touch uses the UTIME_NOW option of
`
``
1089
`+
the utimensat() / futimens() functions.
`
``
1090
`+
try:
`
``
1091
`+
os.utime(self, None)
`
``
1092
`+
except OSError:
`
``
1093
`+
Avoid exception chaining
`
``
1094
`+
pass
`
``
1095
`+
else:
`
``
1096
`+
return
`
``
1097
`+
flags = os.O_CREAT | os.O_WRONLY
`
``
1098
`+
if not exist_ok:
`
``
1099
`+
flags |= os.O_EXCL
`
``
1100
`+
fd = os.open(self, flags, mode)
`
``
1101
`+
os.close(fd)
`
1159
1102
``
1160
1103
`def mkdir(self, mode=0o777, parents=False, exist_ok=False):
`
1161
1104
`"""
`
1162
1105
` Create a new directory at this given path.
`
1163
1106
` """
`
1164
1107
`try:
`
1165
``
`-
self._accessor.mkdir(self, mode)
`
``
1108
`+
os.mkdir(self, mode)
`
1166
1109
`except FileNotFoundError:
`
1167
1110
`if not parents or self.parent == self:
`
1168
1111
`raise
`
`@@ -1178,7 +1121,7 @@ def chmod(self, mode, *, follow_symlinks=True):
`
1178
1121
`"""
`
1179
1122
` Change the permissions of the path, like os.chmod().
`
1180
1123
` """
`
1181
``
`-
self._accessor.chmod(self, mode, follow_symlinks=follow_symlinks)
`
``
1124
`+
os.chmod(self, mode, follow_symlinks=follow_symlinks)
`
1182
1125
``
1183
1126
`def lchmod(self, mode):
`
1184
1127
`"""
`
`@@ -1193,7 +1136,7 @@ def unlink(self, missing_ok=False):
`
1193
1136
` If the path is a directory, use rmdir() instead.
`
1194
1137
` """
`
1195
1138
`try:
`
1196
``
`-
self._accessor.unlink(self)
`
``
1139
`+
os.unlink(self)
`
1197
1140
`except FileNotFoundError:
`
1198
1141
`if not missing_ok:
`
1199
1142
`raise
`
`@@ -1202,7 +1145,7 @@ def rmdir(self):
`
1202
1145
`"""
`
1203
1146
` Remove this directory. The directory must be empty.
`
1204
1147
` """
`
1205
``
`-
self._accessor.rmdir(self)
`
``
1148
`+
os.rmdir(self)
`
1206
1149
``
1207
1150
`def lstat(self):
`
1208
1151
`"""
`
`@@ -1221,7 +1164,7 @@ def rename(self, target):
`
1221
1164
``
1222
1165
` Returns the new Path instance pointing to the target path.
`
1223
1166
` """
`
1224
``
`-
self._accessor.rename(self, target)
`
``
1167
`+
os.rename(self, target)
`
1225
1168
`return self.class(target)
`
1226
1169
``
1227
1170
`def replace(self, target):
`
`@@ -1234,23 +1177,27 @@ def replace(self, target):
`
1234
1177
``
1235
1178
` Returns the new Path instance pointing to the target path.
`
1236
1179
` """
`
1237
``
`-
self._accessor.replace(self, target)
`
``
1180
`+
os.replace(self, target)
`
1238
1181
`return self.class(target)
`
1239
1182
``
1240
1183
`def symlink_to(self, target, target_is_directory=False):
`
1241
1184
`"""
`
1242
1185
` Make this path a symlink pointing to the target path.
`
1243
1186
` Note the order of arguments (link, target) is the reverse of os.symlink.
`
1244
1187
` """
`
1245
``
`-
self._accessor.symlink(target, self, target_is_directory)
`
``
1188
`+
if not hasattr(os, "symlink"):
`
``
1189
`+
raise NotImplementedError("os.symlink() not available on this system")
`
``
1190
`+
os.symlink(target, self, target_is_directory)
`
1246
1191
``
1247
1192
`def hardlink_to(self, target):
`
1248
1193
`"""
`
1249
1194
` Make this path a hard link pointing to the same file as target.
`
1250
1195
``
1251
1196
` Note the order of arguments (self, target) is the reverse of os.link's.
`
1252
1197
` """
`
1253
``
`-
self._accessor.link(target, self)
`
``
1198
`+
if not hasattr(os, "link"):
`
``
1199
`+
raise NotImplementedError("os.link() not available on this system")
`
``
1200
`+
os.link(target, self)
`
1254
1201
``
1255
1202
`def link_to(self, target):
`
1256
1203
`"""
`
`@@ -1268,7 +1215,7 @@ def link_to(self, target):
`
1268
1215
`"for removal in Python 3.12. "
`
1269
1216
`"Use pathlib.Path.hardlink_to() instead.",
`
1270
1217
`DeprecationWarning, stacklevel=2)
`
1271
``
`-
self._accessor.link(self, target)
`
``
1218
`+
self.class(target).hardlink_to(self)
`
1272
1219
``
1273
1220
`# Convenience functions for querying the stat results
`
1274
1221
``
`@@ -1425,7 +1372,7 @@ def expanduser(self):
`
1425
1372
` """
`
1426
1373
`if (not (self._drv or self._root) and
`
1427
1374
`self._parts and self._parts[0][:1] == '~'):
`
1428
``
`-
homedir = self._accessor.expanduser(self._parts[0])
`
``
1375
`+
homedir = os.path.expanduser(self._parts[0])
`
1429
1376
`if homedir[:1] == "~":
`
1430
1377
`raise RuntimeError("Could not determine home directory.")
`
1431
1378
`return self._from_parts([homedir] + self._parts[1:])
`