aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--Lib/pathlib/_abc.py8
-rw-r--r--Lib/pathlib/_local.py29
-rw-r--r--Misc/NEWS.d/next/Library/2025-02-16-18-13-40.gh-issue-128520.iZtOMz.rst5
3 files changed, 24 insertions, 18 deletions
diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py
index 33e963c944f..115e120572d 100644
--- a/Lib/pathlib/_abc.py
+++ b/Lib/pathlib/_abc.py
@@ -192,7 +192,7 @@ class JoinablePath(ABC):
Return True if this path matches the given glob-style pattern. The
pattern is matched against the entire path.
"""
- if not isinstance(pattern, JoinablePath):
+ if not hasattr(pattern, 'with_segments'):
pattern = self.with_segments(pattern)
if case_sensitive is None:
case_sensitive = self.parser.normcase('Aa') == 'Aa'
@@ -286,7 +286,7 @@ class ReadablePath(JoinablePath):
"""Iterate over this subtree and yield all existing files (of any
kind, including directories) matching the given relative pattern.
"""
- if not isinstance(pattern, JoinablePath):
+ if not hasattr(pattern, 'with_segments'):
pattern = self.with_segments(pattern)
anchor, parts = _explode_path(pattern)
if anchor:
@@ -348,7 +348,7 @@ class ReadablePath(JoinablePath):
"""
Recursively copy this file or directory tree to the given destination.
"""
- if not hasattr(target, '_copy_writer'):
+ if not hasattr(target, 'with_segments'):
target = self.with_segments(target)
# Delegate to the target path's CopyWriter object.
@@ -366,7 +366,7 @@ class ReadablePath(JoinablePath):
name = self.name
if not name:
raise ValueError(f"{self!r} has an empty name")
- elif hasattr(target_dir, '_copy_writer'):
+ elif hasattr(target_dir, 'with_segments'):
target = target_dir / name
else:
target = self.with_segments(target_dir, name)
diff --git a/Lib/pathlib/_local.py b/Lib/pathlib/_local.py
index bd1e871ebcf..9b2738652e9 100644
--- a/Lib/pathlib/_local.py
+++ b/Lib/pathlib/_local.py
@@ -475,7 +475,7 @@ class PurePath:
The *walk_up* parameter controls whether `..` may be used to resolve
the path.
"""
- if not isinstance(other, PurePath):
+ if not hasattr(other, 'with_segments'):
other = self.with_segments(other)
for step, path in enumerate(chain([other], other.parents)):
if path == self or path in self.parents:
@@ -492,7 +492,7 @@ class PurePath:
def is_relative_to(self, other):
"""Return True if the path is relative to another path or False.
"""
- if not isinstance(other, PurePath):
+ if not hasattr(other, 'with_segments'):
other = self.with_segments(other)
return other == self or other in self.parents
@@ -545,7 +545,7 @@ class PurePath:
Return True if this path matches the given glob-style pattern. The
pattern is matched against the entire path.
"""
- if not isinstance(pattern, PurePath):
+ if not hasattr(pattern, 'with_segments'):
pattern = self.with_segments(pattern)
if case_sensitive is None:
case_sensitive = self.parser is posixpath
@@ -564,7 +564,7 @@ class PurePath:
is matched. The recursive wildcard '**' is *not* supported by this
method.
"""
- if not isinstance(path_pattern, PurePath):
+ if not hasattr(path_pattern, 'with_segments'):
path_pattern = self.with_segments(path_pattern)
if case_sensitive is None:
case_sensitive = self.parser is posixpath
@@ -1064,7 +1064,9 @@ class Path(PurePath):
Returns the new Path instance pointing to the target path.
"""
os.rename(self, target)
- return self.with_segments(target)
+ if not hasattr(target, 'with_segments'):
+ target = self.with_segments(target)
+ return target
def replace(self, target):
"""
@@ -1077,7 +1079,9 @@ class Path(PurePath):
Returns the new Path instance pointing to the target path.
"""
os.replace(self, target)
- return self.with_segments(target)
+ if not hasattr(target, 'with_segments'):
+ target = self.with_segments(target)
+ return target
_copy_writer = property(LocalCopyWriter)
@@ -1086,7 +1090,7 @@ class Path(PurePath):
"""
Recursively copy this file or directory tree to the given destination.
"""
- if not hasattr(target, '_copy_writer'):
+ if not hasattr(target, 'with_segments'):
target = self.with_segments(target)
# Delegate to the target path's CopyWriter object.
@@ -1104,7 +1108,7 @@ class Path(PurePath):
name = self.name
if not name:
raise ValueError(f"{self!r} has an empty name")
- elif hasattr(target_dir, '_copy_writer'):
+ elif hasattr(target_dir, 'with_segments'):
target = target_dir / name
else:
target = self.with_segments(target_dir, name)
@@ -1118,16 +1122,13 @@ class Path(PurePath):
"""
# Use os.replace() if the target is os.PathLike and on the same FS.
try:
- target_str = os.fspath(target)
+ target = self.with_segments(target)
except TypeError:
pass
else:
- if not hasattr(target, '_copy_writer'):
- target = self.with_segments(target_str)
ensure_different_files(self, target)
try:
- os.replace(self, target_str)
- return target
+ return self.replace(target)
except OSError as err:
if err.errno != EXDEV:
raise
@@ -1143,7 +1144,7 @@ class Path(PurePath):
name = self.name
if not name:
raise ValueError(f"{self!r} has an empty name")
- elif hasattr(target_dir, '_copy_writer'):
+ elif hasattr(target_dir, 'with_segments'):
target = target_dir / name
else:
target = self.with_segments(target_dir, name)
diff --git a/Misc/NEWS.d/next/Library/2025-02-16-18-13-40.gh-issue-128520.iZtOMz.rst b/Misc/NEWS.d/next/Library/2025-02-16-18-13-40.gh-issue-128520.iZtOMz.rst
new file mode 100644
index 00000000000..15de99e8bbd
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-02-16-18-13-40.gh-issue-128520.iZtOMz.rst
@@ -0,0 +1,5 @@
+Apply type conversion consistently in :class:`pathlib.PurePath` and
+:class:`~pathlib.Path` methods can accept a path object as an argument, such
+as :meth:`~pathlib.PurePath.match` and :meth:`~pathlib.Path.rename`. The
+argument is now converted to path object if it lacks a
+:meth:`~pathlib.PurePath.with_segments` attribute, and not otherwise.