[Python-checkins] bpo-45192: Fix a bug that infers the type of an os.PathLike[bytes] object as str (GH-28323) (GH-29111)

ambv webhook-mailer at python.org
Wed Oct 20 17:27:39 EDT 2021


https://github.com/python/cpython/commit/64e83c711eb371d60fce64cae074c4d3311f6ece
commit: 64e83c711eb371d60fce64cae074c4d3311f6ece
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: ambv <lukasz at langa.pl>
date: 2021-10-20T23:27:30+02:00
summary:

bpo-45192: Fix a bug that infers the type of an os.PathLike[bytes] object as str (GH-28323) (GH-29111)

An object implementing the os.PathLike protocol can represent a file
system path as a str or bytes object.
Therefore, _infer_return_type function should infer os.PathLike[str]
object as str type and os.PathLike[bytes] object as bytes type.
(cherry picked from commit 6270d3eeaf17b50abc4f8f4d97790d66179638e4)

Co-authored-by: Kyungmin Lee <rekyungmin at gmail.com>

files:
A Misc/NEWS.d/next/Library/2021-09-14-15-52-47.bpo-45192.DjA-BI.rst
M Lib/tempfile.py
M Lib/test/test_tempfile.py

diff --git a/Lib/tempfile.py b/Lib/tempfile.py
index efcf7a7fb3bbc..7b6821240f2b4 100644
--- a/Lib/tempfile.py
+++ b/Lib/tempfile.py
@@ -88,6 +88,10 @@ def _infer_return_type(*args):
     for arg in args:
         if arg is None:
             continue
+
+        if isinstance(arg, _os.PathLike):
+            arg = _os.fspath(arg)
+
         if isinstance(arg, bytes):
             if return_type is str:
                 raise TypeError("Can't mix bytes and non-bytes in "
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py
index 96946a281a490..2b0ec46a10327 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -62,6 +62,25 @@ def test_infer_return_type_multiples_and_none(self):
     def test_infer_return_type_pathlib(self):
         self.assertIs(str, tempfile._infer_return_type(pathlib.Path('/')))
 
+    def test_infer_return_type_pathlike(self):
+        class Path:
+            def __init__(self, path):
+                self.path = path
+
+            def __fspath__(self):
+                return self.path
+
+        self.assertIs(str, tempfile._infer_return_type(Path('/')))
+        self.assertIs(bytes, tempfile._infer_return_type(Path(b'/')))
+        self.assertIs(str, tempfile._infer_return_type('', Path('')))
+        self.assertIs(bytes, tempfile._infer_return_type(b'', Path(b'')))
+        self.assertIs(bytes, tempfile._infer_return_type(None, Path(b'')))
+        self.assertIs(str, tempfile._infer_return_type(None, Path('')))
+
+        with self.assertRaises(TypeError):
+            tempfile._infer_return_type('', Path(b''))
+        with self.assertRaises(TypeError):
+            tempfile._infer_return_type(b'', Path(''))
 
 # Common functionality.
 
diff --git a/Misc/NEWS.d/next/Library/2021-09-14-15-52-47.bpo-45192.DjA-BI.rst b/Misc/NEWS.d/next/Library/2021-09-14-15-52-47.bpo-45192.DjA-BI.rst
new file mode 100644
index 0000000000000..7dd9795aaa170
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-09-14-15-52-47.bpo-45192.DjA-BI.rst
@@ -0,0 +1,5 @@
+Fix the ``tempfile._infer_return_type`` function so that the ``dir``
+argument of the :mod:`tempfile` functions accepts an object implementing the
+``os.PathLike`` protocol.
+
+Patch by Kyungmin Lee.



More information about the Python-checkins mailing list