diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index 3db55e646c4..42fe27b9e1e 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -521,6 +521,27 @@ Path objects are traversable using the ``/`` operator or ``joinpath``. Return ``True`` if the current context references a file or directory in the zip file. +.. data:: Path.suffix + + The file extension of the final component. + + .. versionadded:: 3.11 + Added :data:`Path.suffix` property. + +.. data:: Path.stem + + The final path component, without its suffix. + + .. versionadded:: 3.11 + Added :data:`Path.stem` property. + +.. data:: Path.suffixes + + A list of the path’s file extensions. + + .. versionadded:: 3.11 + Added :data:`Path.suffixes` property. + .. method:: Path.read_text(*, **) Read the current file as unicode text. Positional and diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index bfc981c0d15..f559be790bb 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -3093,6 +3093,64 @@ class TestPath(unittest.TestCase): root = zipfile.Path(alpharep) assert root.name == 'alpharep.zip' == root.filename.name + @pass_alpharep + def test_suffix(self, alpharep): + """ + The suffix of the root should be the suffix of the zipfile. + The suffix of each nested file is the final component's last suffix, if any. + Includes the leading period, just like pathlib.Path. + """ + root = zipfile.Path(alpharep) + assert root.suffix == '.zip' == root.filename.suffix + + b = root / "b.txt" + assert b.suffix == ".txt" + + c = root / "c" / "filename.tar.gz" + assert c.suffix == ".gz" + + d = root / "d" + assert d.suffix == "" + + @pass_alpharep + def test_suffixes(self, alpharep): + """ + The suffix of the root should be the suffix of the zipfile. + The suffix of each nested file is the final component's last suffix, if any. + Includes the leading period, just like pathlib.Path. + """ + root = zipfile.Path(alpharep) + assert root.suffixes == ['.zip'] == root.filename.suffixes + + b = root / 'b.txt' + assert b.suffixes == ['.txt'] + + c = root / 'c' / 'filename.tar.gz' + assert c.suffixes == ['.tar', '.gz'] + + d = root / 'd' + assert d.suffixes == [] + + e = root / '.hgrc' + assert e.suffixes == [] + + @pass_alpharep + def test_stem(self, alpharep): + """ + The final path component, without its suffix + """ + root = zipfile.Path(alpharep) + assert root.stem == 'alpharep' == root.filename.stem + + b = root / "b.txt" + assert b.stem == "b" + + c = root / "c" / "filename.tar.gz" + assert c.stem == "filename.tar" + + d = root / "d" + assert d.stem == "d" + @pass_alpharep def test_root_parent(self, alpharep): root = zipfile.Path(alpharep) diff --git a/Lib/zipfile.py b/Lib/zipfile.py index d99c0d76977..b83e2c187eb 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -2342,6 +2342,18 @@ class Path: def name(self): return pathlib.Path(self.at).name or self.filename.name + @property + def suffix(self): + return pathlib.Path(self.at).suffix or self.filename.suffix + + @property + def suffixes(self): + return pathlib.Path(self.at).suffixes or self.filename.suffixes + + @property + def stem(self): + return pathlib.Path(self.at).stem or self.filename.stem + @property def filename(self): return pathlib.Path(self.root.filename).joinpath(self.at) diff --git a/Misc/NEWS.d/next/Library/2021-05-14-16-06-02.bpo-44095.v_pLwY.rst b/Misc/NEWS.d/next/Library/2021-05-14-16-06-02.bpo-44095.v_pLwY.rst new file mode 100644 index 00000000000..ee03e933f35 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-05-14-16-06-02.bpo-44095.v_pLwY.rst @@ -0,0 +1,2 @@ +:class:`zipfile.Path` now supports :attr:`zipfile.Path.stem`, +:attr:`zipfile.Path.suffixes`, and :attr:`zipfile.Path.suffix` attributes.