From 4c69be22df3852f17873a74d015528d9a8ae92d6 Mon Sep 17 00:00:00 2001 From: aiudirog Date: Thu, 8 Aug 2019 01:41:10 -0400 Subject: [PATCH] bpo-34775: Return NotImplemented in PurePath division. (GH-9509) --- Lib/pathlib.py | 10 ++++- Lib/test/test_pathlib.py | 41 +++++++++++++++++++ .../2018-09-23-03-18-52.bpo-34775.vHeuHk.rst | 3 ++ 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-09-23-03-18-52.bpo-34775.vHeuHk.rst diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 6369c4b221..6355ae8641 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -907,10 +907,16 @@ class PurePath(object): return self._make_child(args) def __truediv__(self, key): - return self._make_child((key,)) + try: + return self._make_child((key,)) + except TypeError: + return NotImplemented def __rtruediv__(self, key): - return self._from_parts([key] + self._parts) + try: + return self._from_parts([key] + self._parts) + except TypeError: + return NotImplemented @property def parent(self): diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 069467a845..f74524d992 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -2329,5 +2329,46 @@ class WindowsPathTest(_BasePathTest, unittest.TestCase): check() +class CompatiblePathTest(unittest.TestCase): + """ + Test that a type can be made compatible with PurePath + derivatives by implementing division operator overloads. + """ + + class CompatPath: + """ + Minimum viable class to test PurePath compatibility. + Simply uses the division operator to join a given + string and the string value of another object with + a forward slash. + """ + def __init__(self, string): + self.string = string + + def __truediv__(self, other): + return type(self)(f"{self.string}/{other}") + + def __rtruediv__(self, other): + return type(self)(f"{other}/{self.string}") + + def test_truediv(self): + result = pathlib.PurePath("test") / self.CompatPath("right") + self.assertIsInstance(result, self.CompatPath) + self.assertEqual(result.string, "test/right") + + with self.assertRaises(TypeError): + # Verify improper operations still raise a TypeError + pathlib.PurePath("test") / 10 + + def test_rtruediv(self): + result = self.CompatPath("left") / pathlib.PurePath("test") + self.assertIsInstance(result, self.CompatPath) + self.assertEqual(result.string, "left/test") + + with self.assertRaises(TypeError): + # Verify improper operations still raise a TypeError + 10 / pathlib.PurePath("test") + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2018-09-23-03-18-52.bpo-34775.vHeuHk.rst b/Misc/NEWS.d/next/Library/2018-09-23-03-18-52.bpo-34775.vHeuHk.rst new file mode 100644 index 0000000000..f99bf5b39f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-09-23-03-18-52.bpo-34775.vHeuHk.rst @@ -0,0 +1,3 @@ +Division handling of PurePath now returns NotImplemented instead of raising +a TypeError when passed something other than an instance of str or PurePath. +Patch by Roger Aiudi. -- 2.40.0