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:])

`