GH-73991: Add pathlib.Path.copy_into() and move_into() (#123314)

These two methods accept an *existing* directory path, onto which we join
the source path's base name to form the final target path.

A possible alternative implementation is to check for directories in
`copy()` and `move()` and adjust the target path, which is done in several
`shutil` functions. This behaviour is helpful in a shell context, but
less so in a stored program that explicitly specifies destinations. For
example, a user that calls `Path('foo.py').copy('bar.py')` might not
imagine that `bar.py/foo.py` would be created, but under the alternative
implementation this will happen if `bar.py` is an existing directory.
This commit is contained in:
Barney Gale 2024-08-26 14:14:23 +01:00 committed by GitHub
parent dbc1752d41
commit c68a93c582
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 96 additions and 4 deletions

View file

@ -2072,6 +2072,20 @@ class DummyPathTest(DummyPurePathTest):
self.assertTrue(target2.joinpath('link').is_symlink())
self.assertEqual(target2.joinpath('link').readlink(), self.cls('nonexistent'))
def test_copy_into(self):
base = self.cls(self.base)
source = base / 'fileA'
target_dir = base / 'dirA'
result = source.copy_into(target_dir)
self.assertEqual(result, target_dir / 'fileA')
self.assertTrue(result.exists())
self.assertEqual(source.read_text(), result.read_text())
def test_copy_into_empty_name(self):
source = self.cls('')
target_dir = self.base
self.assertRaises(ValueError, source.copy_into, target_dir)
def test_move_file(self):
base = self.cls(self.base)
source = base / 'fileA'
@ -2191,6 +2205,22 @@ class DummyPathTest(DummyPurePathTest):
self.assertTrue(target.is_symlink())
self.assertEqual(source_readlink, target.readlink())
def test_move_into(self):
base = self.cls(self.base)
source = base / 'fileA'
source_text = source.read_text()
target_dir = base / 'dirA'
result = source.move_into(target_dir)
self.assertEqual(result, target_dir / 'fileA')
self.assertFalse(source.exists())
self.assertTrue(result.exists())
self.assertEqual(source_text, result.read_text())
def test_move_into_empty_name(self):
source = self.cls('')
target_dir = self.base
self.assertRaises(ValueError, source.move_into, target_dir)
def test_iterdir(self):
P = self.cls
p = P(self.base)