From 4228d600f3497122282bcb177b0da749dfaac807 Mon Sep 17 00:00:00 2001 From: uriyyo <1998uriyyo@gmail.com> Date: Sat, 18 Apr 2020 17:48:48 +0300 Subject: [PATCH 01/10] bpo-29847: Fix bug when Path takes and ignores **kwargs --- Lib/pathlib.py | 3 +++ Lib/test/test_pathlib.py | 15 +++++++++++++++ Misc/ACKS | 1 + .../2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst | 1 + 4 files changed, 20 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst diff --git a/Lib/pathlib.py b/Lib/pathlib.py index f98d69eb04ac31..68b446f0f64619 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1071,6 +1071,9 @@ def __new__(cls, *args, **kwargs): self._init() return self + def __init__(self, *_): + pass # bpo-29847 + def _init(self, # Private non-constructor arguments template=None, diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 1589282886b6b8..30b995ede2e0e5 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -2312,6 +2312,21 @@ def test_concrete_class(self): self.assertIs(type(p), pathlib.WindowsPath if os.name == 'nt' else pathlib.PosixPath) + def test_kwargs(self): + with self.assertRaisesRegex(TypeError, 'got an unexpected keyword argument'): + self.cls(arg=None) + + def test_subclass_kwargs(self): + class _PathSubclass(self.cls): + _flavour = self.cls()._flavour + + def __init__(self, *args, **kwargs): + self.kwargs = kwargs + + _kwargs = {"a": 1, "b": 2} + p = _PathSubclass(**_kwargs) + self.assertEqual(p.kwargs, _kwargs) + def test_unsupported_flavour(self): if os.name == 'nt': self.assertRaises(NotImplementedError, pathlib.PosixPath) diff --git a/Misc/ACKS b/Misc/ACKS index 8cb95dc0cf8635..97e72e00d49999 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -844,6 +844,7 @@ Jan Kanis Rafe Kaplan Jacob Kaplan-Moss Allison Kaptur +Yurii Karabas Janne Karila Per Øyvind Karlsen Anton Kasyanov diff --git a/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst b/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst new file mode 100644 index 00000000000000..58f218a83186a1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst @@ -0,0 +1 @@ +Fix bug when Path takes and ignores **kwargs From 72ffd2464174752f17e69e4b44f015e53e29f990 Mon Sep 17 00:00:00 2001 From: Yurii Karabas <1998uriyyo@gmail.com> Date: Tue, 21 Apr 2020 13:20:17 +0300 Subject: [PATCH 02/10] Update Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Rémi Lapeyre --- .../next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst b/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst index 58f218a83186a1..d07fd3792f7a61 100644 --- a/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst +++ b/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst @@ -1 +1 @@ -Fix bug when Path takes and ignores **kwargs +Fix bug where :class:`pathlib.Path` and its subclasses take and ignore `**kwargs`. Patch provided by Yurii Karabas. From fc740ec145fdf25c7e087f6acb99b390cf082fad Mon Sep 17 00:00:00 2001 From: uriyyo <1998uriyyo@gmail.com> Date: Tue, 21 Apr 2020 14:11:22 +0300 Subject: [PATCH 03/10] Move tests from PathTest to _BasePathTest class --- Lib/test/test_pathlib.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 30b995ede2e0e5..c36526b114f7fa 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -2300,18 +2300,6 @@ def test_complex_symlinks_relative(self): def test_complex_symlinks_relative_dot_dot(self): self._check_complex_symlinks(os.path.join('dirA', '..')) - -class PathTest(_BasePathTest, unittest.TestCase): - cls = pathlib.Path - - def test_class_getitem(self): - self.assertIs(self.cls[str], self.cls) - - def test_concrete_class(self): - p = self.cls('a') - self.assertIs(type(p), - pathlib.WindowsPath if os.name == 'nt' else pathlib.PosixPath) - def test_kwargs(self): with self.assertRaisesRegex(TypeError, 'got an unexpected keyword argument'): self.cls(arg=None) @@ -2327,6 +2315,18 @@ def __init__(self, *args, **kwargs): p = _PathSubclass(**_kwargs) self.assertEqual(p.kwargs, _kwargs) + +class PathTest(_BasePathTest, unittest.TestCase): + cls = pathlib.Path + + def test_class_getitem(self): + self.assertIs(self.cls[str], self.cls) + + def test_concrete_class(self): + p = self.cls('a') + self.assertIs(type(p), + pathlib.WindowsPath if os.name == 'nt' else pathlib.PosixPath) + def test_unsupported_flavour(self): if os.name == 'nt': self.assertRaises(NotImplementedError, pathlib.PosixPath) From 7dab30d6e602b0ece4b38980f710ccbdc6ec38b8 Mon Sep 17 00:00:00 2001 From: uriyyo <1998uriyyo@gmail.com> Date: Thu, 21 May 2020 17:43:23 +0300 Subject: [PATCH 04/10] Fix bug when PurePath takes and ignores **kwargs --- Lib/pathlib.py | 8 ++++---- Lib/test/test_pathlib.py | 30 +++++++++++++++--------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 68b446f0f64619..a976440ce84ac8 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -650,7 +650,7 @@ class PurePath(object): '_str', '_hash', '_pparts', '_cached_cparts', ) - def __new__(cls, *args): + def __new__(cls, *args, **kwargs): """Construct a PurePath from one or several strings and or existing PurePath objects. The strings and path objects are combined so as to yield a canonicalized path, which is incorporated into the @@ -660,6 +660,9 @@ def __new__(cls, *args): cls = PureWindowsPath if os.name == 'nt' else PurePosixPath return cls._from_parts(args) + def __init__(self, *_): + pass # bpo-29847 + def __reduce__(self): # Using the parts tuple helps share interned path parts # when pickling related paths. @@ -1071,9 +1074,6 @@ def __new__(cls, *args, **kwargs): self._init() return self - def __init__(self, *_): - pass # bpo-29847 - def _init(self, # Private non-constructor arguments template=None, diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index c36526b114f7fa..77dcbd558f7d45 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -681,6 +681,21 @@ def test_pickling_common(self): self.assertEqual(hash(pp), hash(p)) self.assertEqual(str(pp), str(p)) + def test_kwargs(self): + with self.assertRaisesRegex(TypeError, 'got an unexpected keyword argument'): + self.cls(arg=None) + + def test_subclass_kwargs(self): + class _PathSubclass(self.cls): + _flavour = self.cls()._flavour + + def __init__(self, *args, **kwargs): + self.kwargs = kwargs + + _kwargs = {"a": 1, "b": 2} + p = _PathSubclass(**_kwargs) + self.assertEqual(p.kwargs, _kwargs) + class PurePosixPathTest(_BasePurePathTest, unittest.TestCase): cls = pathlib.PurePosixPath @@ -2300,21 +2315,6 @@ def test_complex_symlinks_relative(self): def test_complex_symlinks_relative_dot_dot(self): self._check_complex_symlinks(os.path.join('dirA', '..')) - def test_kwargs(self): - with self.assertRaisesRegex(TypeError, 'got an unexpected keyword argument'): - self.cls(arg=None) - - def test_subclass_kwargs(self): - class _PathSubclass(self.cls): - _flavour = self.cls()._flavour - - def __init__(self, *args, **kwargs): - self.kwargs = kwargs - - _kwargs = {"a": 1, "b": 2} - p = _PathSubclass(**_kwargs) - self.assertEqual(p.kwargs, _kwargs) - class PathTest(_BasePathTest, unittest.TestCase): cls = pathlib.Path From 53c4b586f5dd5fbf9adc6a8f2006b032ac21e3c3 Mon Sep 17 00:00:00 2001 From: Yurii Karabas <1998uriyyo@gmail.com> Date: Fri, 22 May 2020 09:56:18 +0300 Subject: [PATCH 05/10] Update Lib/test/test_pathlib.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Rémi Lapeyre --- Lib/test/test_pathlib.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 77dcbd558f7d45..5c5d4c897efcc7 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -686,6 +686,7 @@ def test_kwargs(self): self.cls(arg=None) def test_subclass_kwargs(self): + # See bpo-29847 class _PathSubclass(self.cls): _flavour = self.cls()._flavour From 7bbc2a39d42b195c841977ed01a64d078919fcad Mon Sep 17 00:00:00 2001 From: Yurii Karabas <1998uriyyo@gmail.com> Date: Fri, 22 May 2020 09:56:24 +0300 Subject: [PATCH 06/10] Update Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Rémi Lapeyre --- .../next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst b/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst index d07fd3792f7a61..166bf1e94d0df8 100644 --- a/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst +++ b/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst @@ -1 +1 @@ -Fix bug where :class:`pathlib.Path` and its subclasses take and ignore `**kwargs`. Patch provided by Yurii Karabas. +Fix bug where :class:`pathlib.PurePath` and its subclasses take and ignore `**kwargs`. Patch provided by Yurii Karabas. From 3311d75c3924542fa9d8ab5f12d4016dbc1e4e98 Mon Sep 17 00:00:00 2001 From: Yurii Karabas <1998uriyyo@gmail.com> Date: Sat, 17 Dec 2022 10:31:36 +0200 Subject: [PATCH 07/10] Update Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst Co-authored-by: Brett Cannon --- .../next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst b/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst index 166bf1e94d0df8..f5607668787836 100644 --- a/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst +++ b/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst @@ -1 +1 @@ -Fix bug where :class:`pathlib.PurePath` and its subclasses take and ignore `**kwargs`. Patch provided by Yurii Karabas. +Fix bug where :class:`pathlib.Path` accepted and ignored keyword arguments. Patch provided by Yurii Karabas. From f021d2b716b1f5af7859fb5e2e7035a03ed3560e Mon Sep 17 00:00:00 2001 From: Yurii Karabas <1998uriyyo@gmail.com> Date: Sat, 17 Dec 2022 10:46:34 +0200 Subject: [PATCH 08/10] Remove kwargs from pathlib.Path; Remove redundant subclass test --- Lib/pathlib.py | 7 ++----- Lib/test/test_pathlib.py | 12 ------------ 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index af2d6996a391f2..f8655330e704c1 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -390,7 +390,7 @@ class PurePath(object): '_str', '_hash', '_pparts', '_cached_cparts', ) - def __new__(cls, *args, **kwargs): + def __new__(cls, *args): """Construct a PurePath from one or several strings and or existing PurePath objects. The strings and path objects are combined so as to yield a canonicalized path, which is incorporated into the @@ -400,9 +400,6 @@ def __new__(cls, *args, **kwargs): cls = PureWindowsPath if os.name == 'nt' else PurePosixPath return cls._from_parts(args) - def __init__(self, *_): - pass # bpo-29847 - def __reduce__(self): # Using the parts tuple helps share interned path parts # when pickling related paths. @@ -788,7 +785,7 @@ class Path(PurePath): """ __slots__ = () - def __new__(cls, *args, **kwargs): + def __new__(cls, *args): if cls is Path: cls = WindowsPath if os.name == 'nt' else PosixPath self = cls._from_parts(args) diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 52ce1f715de57b..ad504b9a813f45 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -745,18 +745,6 @@ def test_kwargs(self): with self.assertRaisesRegex(TypeError, 'got an unexpected keyword argument'): self.cls(arg=None) - def test_subclass_kwargs(self): - # See bpo-29847 - class _PathSubclass(self.cls): - _flavour = self.cls()._flavour - - def __init__(self, *args, **kwargs): - self.kwargs = kwargs - - _kwargs = {"a": 1, "b": 2} - p = _PathSubclass(**_kwargs) - self.assertEqual(p.kwargs, _kwargs) - class PurePosixPathTest(_BasePurePathTest, unittest.TestCase): cls = pathlib.PurePosixPath From 6fa22de33c3563724e232bb1b1fc5ecbb46b8fcd Mon Sep 17 00:00:00 2001 From: Yurii Karabas <1998uriyyo@gmail.com> Date: Sat, 24 Dec 2022 10:51:02 +0200 Subject: [PATCH 09/10] Add deprecation warning when calling Path with **kwargs --- Lib/pathlib.py | 6 +++++- Lib/test/test_pathlib.py | 9 +++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index f8655330e704c1..9b81c7693e889f 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -785,7 +785,11 @@ class Path(PurePath): """ __slots__ = () - def __new__(cls, *args): + def __new__(cls, *args, **kwargs): + if kwargs: + msg = ("support for supplying keyword arguments to pathlib.PurePath " + "is deprecated and scheduled for removal in Python {remove}") + warnings._deprecated("pathlib.PurePath(**kwargs)", msg, remove=(3, 14)) if cls is Path: cls = WindowsPath if os.name == 'nt' else PosixPath self = cls._from_parts(args) diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index ad504b9a813f45..1a2fede54fb046 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -741,10 +741,6 @@ def test_pickling_common(self): self.assertEqual(hash(pp), hash(p)) self.assertEqual(str(pp), str(p)) - def test_kwargs(self): - with self.assertRaisesRegex(TypeError, 'got an unexpected keyword argument'): - self.cls(arg=None) - class PurePosixPathTest(_BasePurePathTest, unittest.TestCase): cls = pathlib.PurePosixPath @@ -2574,6 +2570,11 @@ def test_complex_symlinks_relative(self): def test_complex_symlinks_relative_dot_dot(self): self._check_complex_symlinks(os.path.join('dirA', '..')) + def test_passing_kwargs_deprecated(self): + with self.assertWarns(DeprecationWarning): + self.cls(foo="bar") + + class WalkTests(unittest.TestCase): def setUp(self): From c654ddae2b4dff268c3ddf7dc9a7b5fb462231bb Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 13 Jan 2023 15:40:18 -0800 Subject: [PATCH 10/10] Update Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst --- .../next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst b/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst index f5607668787836..010d775a0d98ee 100644 --- a/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst +++ b/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst @@ -1 +1 @@ -Fix bug where :class:`pathlib.Path` accepted and ignored keyword arguments. Patch provided by Yurii Karabas. +Fix a bug where :class:`pathlib.Path` accepted and ignored keyword arguments. Patch provided by Yurii Karabas.