diff options
author | Eric L <ericzolf@users.noreply.github.com> | 2021-03-03 20:36:22 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-03 20:36:22 (GMT) |
commit | 9c7927400cd8f1d283bf7915b6b33fea81b8655d (patch) | |
tree | a1cfe04df8fd6569f55d8d352b9c5137563c441d /Lib | |
parent | 62e3b6370cf9aa990485d9c7c3ea3f6f150daa47 (diff) | |
download | cpython-9c7927400cd8f1d283bf7915b6b33fea81b8655d.zip cpython-9c7927400cd8f1d283bf7915b6b33fea81b8655d.tar.gz cpython-9c7927400cd8f1d283bf7915b6b33fea81b8655d.tar.bz2 |
bpo-40701: tempfile mixes str and bytes in an inconsistent manner (GH-20442)
The case of tempfile.tempdir variable being bytes is now handled consistently.
The getters return the right type and no more error of mixing str and bytes unless explicitly caused by the user.
Adds a regression test.
Expands the documentation to clarify the behavior.
Co-authored-by: Eric L <ewl+git@lavar.de>
Co-authored-by: Gregory P. Smith <greg@krypto.org>
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/tempfile.py | 24 | ||||
-rw-r--r-- | Lib/test/test_tempfile.py | 57 |
2 files changed, 73 insertions, 8 deletions
diff --git a/Lib/tempfile.py b/Lib/tempfile.py index c3fe61a..dc088d9 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -99,7 +99,11 @@ def _infer_return_type(*args): "path components.") return_type = str if return_type is None: - return str # tempfile APIs return a str by default. + if tempdir is None or isinstance(tempdir, str): + return str # tempfile APIs return a str by default. + else: + # we could check for bytes but it'll fail later on anyway + return bytes return return_type @@ -265,17 +269,17 @@ def _mkstemp_inner(dir, pre, suf, flags, output_type): # User visible interfaces. def gettempprefix(): - """The default prefix for temporary directories.""" - return template + """The default prefix for temporary directories as string.""" + return _os.fsdecode(template) def gettempprefixb(): """The default prefix for temporary directories as bytes.""" - return _os.fsencode(gettempprefix()) + return _os.fsencode(template) tempdir = None -def gettempdir(): - """Accessor for tempfile.tempdir.""" +def _gettempdir(): + """Private accessor for tempfile.tempdir.""" global tempdir if tempdir is None: _once_lock.acquire() @@ -286,9 +290,13 @@ def gettempdir(): _once_lock.release() return tempdir +def gettempdir(): + """Returns tempfile.tempdir as str.""" + return _os.fsdecode(_gettempdir()) + def gettempdirb(): - """A bytes version of tempfile.gettempdir().""" - return _os.fsencode(gettempdir()) + """Returns tempfile.tempdir as bytes.""" + return _os.fsencode(_gettempdir()) def mkstemp(suffix=None, prefix=None, dir=None, text=False): """User-callable function to create and return a unique temporary diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 77d710e..5822c75 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -667,6 +667,37 @@ class TestMkstemp(BaseTestCase): finally: os.rmdir(dir) + def test_for_tempdir_is_bytes_issue40701_api_warts(self): + orig_tempdir = tempfile.tempdir + self.assertIsInstance(tempfile.tempdir, (str, type(None))) + try: + fd, path = tempfile.mkstemp() + os.close(fd) + os.unlink(path) + self.assertIsInstance(path, str) + tempfile.tempdir = tempfile.gettempdirb() + self.assertIsInstance(tempfile.tempdir, bytes) + self.assertIsInstance(tempfile.gettempdir(), str) + self.assertIsInstance(tempfile.gettempdirb(), bytes) + fd, path = tempfile.mkstemp() + os.close(fd) + os.unlink(path) + self.assertIsInstance(path, bytes) + fd, path = tempfile.mkstemp(suffix='.txt') + os.close(fd) + os.unlink(path) + self.assertIsInstance(path, str) + fd, path = tempfile.mkstemp(prefix='test-temp-') + os.close(fd) + os.unlink(path) + self.assertIsInstance(path, str) + fd, path = tempfile.mkstemp(dir=tempfile.gettempdir()) + os.close(fd) + os.unlink(path) + self.assertIsInstance(path, str) + finally: + tempfile.tempdir = orig_tempdir + class TestMkdtemp(TestBadTempdir, BaseTestCase): """Test mkdtemp().""" @@ -775,6 +806,32 @@ class TestMkdtemp(TestBadTempdir, BaseTestCase): dir2 = tempfile.mkdtemp() self.assertTrue(dir2.endswith('bbb')) + def test_for_tempdir_is_bytes_issue40701_api_warts(self): + orig_tempdir = tempfile.tempdir + self.assertIsInstance(tempfile.tempdir, (str, type(None))) + try: + path = tempfile.mkdtemp() + os.rmdir(path) + self.assertIsInstance(path, str) + tempfile.tempdir = tempfile.gettempdirb() + self.assertIsInstance(tempfile.tempdir, bytes) + self.assertIsInstance(tempfile.gettempdir(), str) + self.assertIsInstance(tempfile.gettempdirb(), bytes) + path = tempfile.mkdtemp() + os.rmdir(path) + self.assertIsInstance(path, bytes) + path = tempfile.mkdtemp(suffix='-dir') + os.rmdir(path) + self.assertIsInstance(path, str) + path = tempfile.mkdtemp(prefix='test-mkdtemp-') + os.rmdir(path) + self.assertIsInstance(path, str) + path = tempfile.mkdtemp(dir=tempfile.gettempdir()) + os.rmdir(path) + self.assertIsInstance(path, str) + finally: + tempfile.tempdir = orig_tempdir + class TestMktemp(BaseTestCase): """Test mktemp().""" |