mirror of https://github.com/python/cpython
bpo-39950: add `pathlib.Path.hardlink_to()` method that supersedes `link_to()` (GH-18909)
The argument order of `link_to()` is reversed compared to what one may expect, so: a.link_to(b) Might be expected to create *a* as a link to *b*, in fact it creates *b* as a link to *a*, making it function more like a "link from". This doesn't match `symlink_to()` nor the documentation and doesn't seem to be the original author's intent. This PR deprecates `link_to()` and introduces `hardlink_to()`, which has the same argument order as `symlink_to()`.
This commit is contained in:
parent
e047239eaf
commit
f24e2e5464
|
@ -1140,6 +1140,15 @@ call fails (for example because the path doesn't exist).
|
||||||
The order of arguments (link, target) is the reverse
|
The order of arguments (link, target) is the reverse
|
||||||
of :func:`os.symlink`'s.
|
of :func:`os.symlink`'s.
|
||||||
|
|
||||||
|
.. method:: Path.hardlink_to(target)
|
||||||
|
|
||||||
|
Make this path a hard link to the same file as *target*.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
The order of arguments (link, target) is the reverse
|
||||||
|
of :func:`os.link`'s.
|
||||||
|
|
||||||
|
.. versionadded:: 3.10
|
||||||
|
|
||||||
.. method:: Path.link_to(target)
|
.. method:: Path.link_to(target)
|
||||||
|
|
||||||
|
@ -1149,11 +1158,17 @@ call fails (for example because the path doesn't exist).
|
||||||
|
|
||||||
This function does not make this path a hard link to *target*, despite
|
This function does not make this path a hard link to *target*, despite
|
||||||
the implication of the function and argument names. The argument order
|
the implication of the function and argument names. The argument order
|
||||||
(target, link) is the reverse of :func:`Path.symlink_to`, but matches
|
(target, link) is the reverse of :func:`Path.symlink_to` and
|
||||||
that of :func:`os.link`.
|
:func:`Path.hardlink_to`, but matches that of :func:`os.link`.
|
||||||
|
|
||||||
.. versionadded:: 3.8
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
.. deprecated:: 3.10
|
||||||
|
|
||||||
|
This method is deprecated in favor of :meth:`Path.hardlink_to`, as the
|
||||||
|
argument order of :meth:`Path.link_to` does not match that of
|
||||||
|
:meth:`Path.symlink_to`.
|
||||||
|
|
||||||
|
|
||||||
.. method:: Path.touch(mode=0o666, exist_ok=True)
|
.. method:: Path.touch(mode=0o666, exist_ok=True)
|
||||||
|
|
||||||
|
@ -1246,7 +1261,7 @@ Below is a table mapping various :mod:`os` functions to their corresponding
|
||||||
:func:`os.path.isdir` :meth:`Path.is_dir`
|
:func:`os.path.isdir` :meth:`Path.is_dir`
|
||||||
:func:`os.path.isfile` :meth:`Path.is_file`
|
:func:`os.path.isfile` :meth:`Path.is_file`
|
||||||
:func:`os.path.islink` :meth:`Path.is_symlink`
|
:func:`os.path.islink` :meth:`Path.is_symlink`
|
||||||
:func:`os.link` :meth:`Path.link_to`
|
:func:`os.link` :meth:`Path.hardlink_to`
|
||||||
:func:`os.symlink` :meth:`Path.symlink_to`
|
:func:`os.symlink` :meth:`Path.symlink_to`
|
||||||
:func:`os.readlink` :meth:`Path.readlink`
|
:func:`os.readlink` :meth:`Path.readlink`
|
||||||
:func:`os.path.relpath` :meth:`Path.relative_to` [#]_
|
:func:`os.path.relpath` :meth:`Path.relative_to` [#]_
|
||||||
|
|
|
@ -1007,6 +1007,11 @@ Added negative indexing support to :attr:`PurePath.parents
|
||||||
<pathlib.PurePath.parents>`.
|
<pathlib.PurePath.parents>`.
|
||||||
(Contributed by Yaroslav Pankovych in :issue:`21041`)
|
(Contributed by Yaroslav Pankovych in :issue:`21041`)
|
||||||
|
|
||||||
|
Added :meth:`Path.hardlink_to <pathlib.Path.hardlink_to>` method that
|
||||||
|
supersedes :meth:`~pathlib.Path.link_to`. The new method has the same argument
|
||||||
|
order as :meth:`~pathlib.Path.symlink_to`.
|
||||||
|
(Contributed by Barney Gale in :issue:`39950`.)
|
||||||
|
|
||||||
platform
|
platform
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
@ -1363,6 +1368,10 @@ Deprecated
|
||||||
|
|
||||||
(Contributed by Jelle Zijlstra in :issue:`21574`.)
|
(Contributed by Jelle Zijlstra in :issue:`21574`.)
|
||||||
|
|
||||||
|
* :meth:`pathlib.Path.link_to` is deprecated and slated for removal in
|
||||||
|
Python 3.12. Use :meth:`pathlib.Path.hardlink_to` instead.
|
||||||
|
(Contributed by Barney Gale in :issue:`39950`.)
|
||||||
|
|
||||||
|
|
||||||
Removed
|
Removed
|
||||||
=======
|
=======
|
||||||
|
|
|
@ -6,6 +6,7 @@ import os
|
||||||
import posixpath
|
import posixpath
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
import warnings
|
||||||
from _collections_abc import Sequence
|
from _collections_abc import Sequence
|
||||||
from errno import EINVAL, ENOENT, ENOTDIR, EBADF, ELOOP
|
from errno import EINVAL, ENOENT, ENOTDIR, EBADF, ELOOP
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
|
@ -1306,6 +1307,14 @@ class Path(PurePath):
|
||||||
"""
|
"""
|
||||||
self._accessor.symlink(target, self, target_is_directory)
|
self._accessor.symlink(target, self, target_is_directory)
|
||||||
|
|
||||||
|
def hardlink_to(self, target):
|
||||||
|
"""
|
||||||
|
Make this path a hard link pointing to the same file as *target*.
|
||||||
|
|
||||||
|
Note the order of arguments (self, target) is the reverse of os.link's.
|
||||||
|
"""
|
||||||
|
self._accessor.link(target, self)
|
||||||
|
|
||||||
def link_to(self, target):
|
def link_to(self, target):
|
||||||
"""
|
"""
|
||||||
Make the target path a hard link pointing to this path.
|
Make the target path a hard link pointing to this path.
|
||||||
|
@ -1315,7 +1324,13 @@ class Path(PurePath):
|
||||||
of arguments (target, link) is the reverse of Path.symlink_to, but
|
of arguments (target, link) is the reverse of Path.symlink_to, but
|
||||||
matches that of os.link.
|
matches that of os.link.
|
||||||
|
|
||||||
|
Deprecated since Python 3.10 and scheduled for removal in Python 3.12.
|
||||||
|
Use `hardlink_to()` instead.
|
||||||
"""
|
"""
|
||||||
|
warnings.warn("pathlib.Path.link_to() is deprecated and is scheduled "
|
||||||
|
"for removal in Python 3.12. "
|
||||||
|
"Use pathlib.Path.hardlink_to() instead.",
|
||||||
|
DeprecationWarning)
|
||||||
self._accessor.link(self, target)
|
self._accessor.link(self, target)
|
||||||
|
|
||||||
# Convenience functions for querying the stat results
|
# Convenience functions for querying the stat results
|
||||||
|
|
|
@ -1925,7 +1925,8 @@ class _BasePathTest(object):
|
||||||
# linking to another path.
|
# linking to another path.
|
||||||
q = P / 'dirA' / 'fileAA'
|
q = P / 'dirA' / 'fileAA'
|
||||||
try:
|
try:
|
||||||
p.link_to(q)
|
with self.assertWarns(DeprecationWarning):
|
||||||
|
p.link_to(q)
|
||||||
except PermissionError as e:
|
except PermissionError as e:
|
||||||
self.skipTest('os.link(): %s' % e)
|
self.skipTest('os.link(): %s' % e)
|
||||||
self.assertEqual(q.stat().st_size, size)
|
self.assertEqual(q.stat().st_size, size)
|
||||||
|
@ -1937,6 +1938,24 @@ class _BasePathTest(object):
|
||||||
self.assertEqual(os.stat(r).st_size, size)
|
self.assertEqual(os.stat(r).st_size, size)
|
||||||
self.assertTrue(q.stat)
|
self.assertTrue(q.stat)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(os, "link"), "os.link() is not present")
|
||||||
|
def test_hardlink_to(self):
|
||||||
|
P = self.cls(BASE)
|
||||||
|
target = P / 'fileA'
|
||||||
|
size = target.stat().st_size
|
||||||
|
# linking to another path.
|
||||||
|
link = P / 'dirA' / 'fileAA'
|
||||||
|
link.hardlink_to(target)
|
||||||
|
self.assertEqual(link.stat().st_size, size)
|
||||||
|
self.assertTrue(os.path.samefile(target, link))
|
||||||
|
self.assertTrue(target.exists())
|
||||||
|
# Linking to a str of a relative path.
|
||||||
|
link2 = P / 'dirA' / 'fileAAA'
|
||||||
|
target2 = rel_join('fileA')
|
||||||
|
link2.hardlink_to(target2)
|
||||||
|
self.assertEqual(os.stat(target2).st_size, size)
|
||||||
|
self.assertTrue(link2.exists())
|
||||||
|
|
||||||
@unittest.skipIf(hasattr(os, "link"), "os.link() is present")
|
@unittest.skipIf(hasattr(os, "link"), "os.link() is present")
|
||||||
def test_link_to_not_implemented(self):
|
def test_link_to_not_implemented(self):
|
||||||
P = self.cls(BASE)
|
P = self.cls(BASE)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Add `pathlib.Path.hardlink_to()` method that supersedes `link_to()`. The new
|
||||||
|
method has the same argument order as `symlink_to()`.
|
Loading…
Reference in New Issue