summaryrefslogtreecommitdiffstats
path: root/Lib/pathlib/_local.py
diff options
context:
space:
mode:
authorBarney Gale <barney.gale@gmail.com>2024-05-25 20:01:36 (GMT)
committerGitHub <noreply@github.com>2024-05-25 20:01:36 (GMT)
commite418fc3a6e7bade68ab5dfe72f14ddba28e6acb5 (patch)
tree67662f1eba24dd69bfef714d0a48e1274927b480 /Lib/pathlib/_local.py
parent0c5ebe13e9937c446e9947c44f2570737ecca135 (diff)
downloadcpython-e418fc3a6e7bade68ab5dfe72f14ddba28e6acb5.zip
cpython-e418fc3a6e7bade68ab5dfe72f14ddba28e6acb5.tar.gz
cpython-e418fc3a6e7bade68ab5dfe72f14ddba28e6acb5.tar.bz2
GH-82805: Fix handling of single-dot file extensions in pathlib (#118952)
pathlib now treats "`.`" as a valid file extension (suffix). This brings it in line with `os.path.splitext()`. In the (private) pathlib ABCs, we add a new `ParserBase.splitext()` method that splits a path into a `(root, ext)` pair, like `os.path.splitext()`. This method is called by `PurePathBase.stem`, `suffix`, etc. In a future version of pathlib, we might make these base classes public, and so users will be able to define their own `splitext()` method to control file extension splitting. In `pathlib.PurePath` we add optimised `stem`, `suffix` and `suffixes` properties that don't use `splitext()`, which avoids computing the path base name twice.
Diffstat (limited to 'Lib/pathlib/_local.py')
-rw-r--r--Lib/pathlib/_local.py34
1 files changed, 34 insertions, 0 deletions
diff --git a/Lib/pathlib/_local.py b/Lib/pathlib/_local.py
index f2776b1..49d9f81 100644
--- a/Lib/pathlib/_local.py
+++ b/Lib/pathlib/_local.py
@@ -361,6 +361,40 @@ class PurePath(PurePathBase):
tail[-1] = name
return self._from_parsed_parts(self.drive, self.root, tail)
+ @property
+ def stem(self):
+ """The final path component, minus its last suffix."""
+ name = self.name
+ i = name.rfind('.')
+ if i != -1:
+ stem = name[:i]
+ # Stem must contain at least one non-dot character.
+ if stem.lstrip('.'):
+ return stem
+ return name
+
+ @property
+ def suffix(self):
+ """
+ The final component's last suffix, if any.
+
+ This includes the leading period. For example: '.txt'
+ """
+ name = self.name.lstrip('.')
+ i = name.rfind('.')
+ if i != -1:
+ return name[i:]
+ return ''
+
+ @property
+ def suffixes(self):
+ """
+ A list of the final component's suffixes, if any.
+
+ These include the leading periods. For example: ['.tar', '.gz']
+ """
+ return ['.' + ext for ext in self.name.lstrip('.').split('.')[1:]]
+
def relative_to(self, other, *, walk_up=False):
"""Return the relative path to another path identified by the passed
arguments. If the operation is not possible (because this is not