diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2021-10-20 14:25:10 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-20 23:25:10 +0200 |
commit | d33fae7105aaea7c376b5455fd1f8de802ca2542 (patch) | |
tree | e30370a7331a0ea70977ab1b37288fd60d5c35d8 | |
parent | 427ab124b3e9a54602b6f1d073a8e073159c0b51 (diff) | |
download | cpython-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.py | 4 | ||||
-rw-r--r-- | Lib/test/test_tempfile.py | 19 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2021-09-14-15-52-47.bpo-45192.DjA-BI.rst | 5 |
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. |