Skip to content

Commit 05e8228

Browse files
barneygaleseehwan80
authored andcommitted
pythonGH-130608: Remove dirs_exist_ok argument from pathlib.Path.copy() (python#130610)
This feature isn't sufficiently motivated.
1 parent 1769e27 commit 05e8228

File tree

6 files changed

+13
-40
lines changed

6 files changed

+13
-40
lines changed

Doc/library/pathlib.rst

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,8 +1571,7 @@ Creating files and directories
15711571
Copying, moving and deleting
15721572
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15731573

1574-
.. method:: Path.copy(target, *, follow_symlinks=True, dirs_exist_ok=False, \
1575-
preserve_metadata=False)
1574+
.. method:: Path.copy(target, *, follow_symlinks=True, preserve_metadata=False)
15761575

15771576
Copy this file or directory tree to the given *target*, and return a new
15781577
:class:`!Path` instance pointing to *target*.
@@ -1582,12 +1581,6 @@ Copying, moving and deleting
15821581
default), the symlink's target is copied. Otherwise, the symlink is
15831582
recreated at the destination.
15841583

1585-
If the source is a directory and *dirs_exist_ok* is false (the default), a
1586-
:exc:`FileExistsError` is raised if the target is an existing directory.
1587-
If *dirs_exists_ok* is true, the copying operation will overwrite
1588-
existing files within the destination tree with corresponding files
1589-
from the source tree.
1590-
15911584
If *preserve_metadata* is false (the default), only directory structures
15921585
and file data are guaranteed to be copied. Set *preserve_metadata* to true
15931586
to ensure that file and directory permissions, flags, last access and
@@ -1604,7 +1597,7 @@ Copying, moving and deleting
16041597

16051598

16061599
.. method:: Path.copy_into(target_dir, *, follow_symlinks=True, \
1607-
dirs_exist_ok=False, preserve_metadata=False)
1600+
preserve_metadata=False)
16081601

16091602
Copy this file or directory tree into the given *target_dir*, which should
16101603
be an existing directory. Other arguments are handled identically to

Lib/pathlib/_abc.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -340,19 +340,18 @@ def readlink(self):
340340
"""
341341
raise NotImplementedError
342342

343-
def copy(self, target, follow_symlinks=True, dirs_exist_ok=False,
344-
preserve_metadata=False):
343+
def copy(self, target, follow_symlinks=True, preserve_metadata=False):
345344
"""
346345
Recursively copy this file or directory tree to the given destination.
347346
"""
348347
if not hasattr(target, 'with_segments'):
349348
target = self.with_segments(target)
350349
ensure_distinct_paths(self, target)
351-
copy_file(self, target, follow_symlinks, dirs_exist_ok, preserve_metadata)
350+
copy_file(self, target, follow_symlinks, preserve_metadata)
352351
return target.joinpath() # Empty join to ensure fresh metadata.
353352

354353
def copy_into(self, target_dir, *, follow_symlinks=True,
355-
dirs_exist_ok=False, preserve_metadata=False):
354+
preserve_metadata=False):
356355
"""
357356
Copy this file or directory tree into the given existing directory.
358357
"""
@@ -364,7 +363,6 @@ def copy_into(self, target_dir, *, follow_symlinks=True,
364363
else:
365364
target = self.with_segments(target_dir, name)
366365
return self.copy(target, follow_symlinks=follow_symlinks,
367-
dirs_exist_ok=dirs_exist_ok,
368366
preserve_metadata=preserve_metadata)
369367

370368

Lib/pathlib/_local.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,19 +1093,18 @@ def replace(self, target):
10931093
target = self.with_segments(target)
10941094
return target
10951095

1096-
def copy(self, target, follow_symlinks=True, dirs_exist_ok=False,
1097-
preserve_metadata=False):
1096+
def copy(self, target, follow_symlinks=True, preserve_metadata=False):
10981097
"""
10991098
Recursively copy this file or directory tree to the given destination.
11001099
"""
11011100
if not hasattr(target, 'with_segments'):
11021101
target = self.with_segments(target)
11031102
ensure_distinct_paths(self, target)
1104-
copy_file(self, target, follow_symlinks, dirs_exist_ok, preserve_metadata)
1103+
copy_file(self, target, follow_symlinks, preserve_metadata)
11051104
return target.joinpath() # Empty join to ensure fresh metadata.
11061105

11071106
def copy_into(self, target_dir, *, follow_symlinks=True,
1108-
dirs_exist_ok=False, preserve_metadata=False):
1107+
preserve_metadata=False):
11091108
"""
11101109
Copy this file or directory tree into the given existing directory.
11111110
"""
@@ -1117,7 +1116,6 @@ def copy_into(self, target_dir, *, follow_symlinks=True,
11171116
else:
11181117
target = self.with_segments(target_dir, name)
11191118
return self.copy(target, follow_symlinks=follow_symlinks,
1120-
dirs_exist_ok=dirs_exist_ok,
11211119
preserve_metadata=preserve_metadata)
11221120

11231121
def move(self, target):

Lib/pathlib/_os.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,7 @@ def ensure_different_files(source, target):
242242
raise err
243243

244244

245-
def copy_file(source, target, follow_symlinks=True, dirs_exist_ok=False,
246-
preserve_metadata=False):
245+
def copy_file(source, target, follow_symlinks=True, preserve_metadata=False):
247246
"""
248247
Recursively copy the given source ReadablePath to the given target WritablePath.
249248
"""
@@ -254,10 +253,10 @@ def copy_file(source, target, follow_symlinks=True, dirs_exist_ok=False,
254253
target._write_info(info, follow_symlinks=False)
255254
elif info.is_dir():
256255
children = source.iterdir()
257-
target.mkdir(exist_ok=dirs_exist_ok)
256+
target.mkdir()
258257
for src in children:
259258
dst = target.joinpath(src.name)
260-
copy_file(src, dst, follow_symlinks, dirs_exist_ok, preserve_metadata)
259+
copy_file(src, dst, follow_symlinks, preserve_metadata)
261260
if preserve_metadata:
262261
target._write_info(info)
263262
else:

Lib/test/test_pathlib/test_pathlib_abc.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,23 +1495,6 @@ def test_copy_dir_to_existing_directory(self):
14951495
target.joinpath('dirD').mkdir()
14961496
self.assertRaises(FileExistsError, source.copy, target)
14971497

1498-
def test_copy_dir_to_existing_directory_dirs_exist_ok(self):
1499-
base = self.cls(self.base)
1500-
source = base / 'dirC'
1501-
target = base / 'copyC'
1502-
target.mkdir()
1503-
target.joinpath('dirD').mkdir()
1504-
result = source.copy(target, dirs_exist_ok=True)
1505-
self.assertEqual(result, target)
1506-
self.assertTrue(result.info.is_dir())
1507-
self.assertTrue(result.joinpath('dirD').info.is_dir())
1508-
self.assertTrue(result.joinpath('dirD', 'fileD').info.is_file())
1509-
self.assertEqual(result.joinpath('dirD', 'fileD').read_text(),
1510-
"this is file D\n")
1511-
self.assertTrue(result.joinpath('fileC').info.is_file())
1512-
self.assertTrue(result.joinpath('fileC').read_text(),
1513-
"this is file C\n")
1514-
15151498
def test_copy_dir_to_itself(self):
15161499
base = self.cls(self.base)
15171500
source = base / 'dirC'
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Remove *dirs_exist_ok* argument from :meth:`pathlib.Path.copy` and
2+
:meth:`~pathlib.Path.copy_into`. These methods are new in Python 3.14.

0 commit comments

Comments
 (0)