summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2021-10-20 14:25:10 -0700
committerGitHub <noreply@github.com>2021-10-20 23:25:10 +0200
commitd33fae7105aaea7c376b5455fd1f8de802ca2542 (patch)
treee30370a7331a0ea70977ab1b37288fd60d5c35d8
parent427ab124b3e9a54602b6f1d073a8e073159c0b51 (diff)
downloadcpython-git-d33fae7105aaea7c376b5455fd1f8de802ca2542.tar.gz
bpo-45192: Fix a bug that infers the type of an os.PathLike[bytes] object as str (GH-28323) (GH-29112)
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@gmail.com>
-rw-r--r--Lib/tempfile.py4
-rw-r--r--Lib/test/test_tempfile.py19
-rw-r--r--Misc/NEWS.d/next/Library/2021-09-14-15-52-47.bpo-45192.DjA-BI.rst5
3 files changed, 28 insertions, 0 deletions
diff --git a/Lib/tempfile.py b/Lib/tempfile.py
index 770f72c252..eafce6f25b 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 7dbbf9b7e5..8ad1bb98e8 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -60,6 +60,25 @@ class TestLowLevelInternals(unittest.TestCase):
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 0000000000..7dd9795aaa
--- /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.