From 7d0bddde5caca7abf41aa3d8763bc99ad8aa8798 Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Mon, 30 Nov 2009 00:08:56 +0000 Subject: #6077: on Windows, fix truncation of a tempfile.TemporaryFile opened in "wt+" mode: files opened with os.open() stop on the first \x1a (Ctrl-Z) unless os.O_BINARY is used. Will backport to 3.1 --- Lib/tempfile.py | 13 +++---------- Lib/test/test_tempfile.py | 12 ++++++++++-- Misc/NEWS | 3 +++ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 93405a8..049cdaa 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -169,7 +169,6 @@ def _get_default_tempdir(): namer = _RandomNameSequence() dirlist = _candidate_tempdir_list() - flags = _text_openflags for dir in dirlist: if dir != _os.curdir: @@ -179,7 +178,7 @@ def _get_default_tempdir(): name = next(namer) filename = _os.path.join(dir, name) try: - fd = _os.open(filename, flags, 0o600) + fd = _os.open(filename, _bin_openflags, 0o600) fp = _io.open(fd, 'wb') fp.write(b'blat') fp.close() @@ -434,10 +433,7 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, if dir is None: dir = gettempdir() - if 'b' in mode: - flags = _bin_openflags - else: - flags = _text_openflags + flags = _bin_openflags # Setting O_TEMPORARY in the flags causes the OS to delete # the file when it is closed. This is only supported by Windows. @@ -475,10 +471,7 @@ else: if dir is None: dir = gettempdir() - if 'b' in mode: - flags = _bin_openflags - else: - flags = _text_openflags + flags = _bin_openflags (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) try: diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index a1bafc2..403dd93 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -309,8 +309,12 @@ class test__mkstemp_inner(TC): if not has_textmode: return # ugh, can't use SkipTest. - self.do_create(bin=0).write(b"blat\n") - # XXX should test that the file really is a text file + # A text file is truncated at the first Ctrl+Z byte + f = self.do_create(bin=0) + f.write(b"blat\x1a") + f.write(b"extra\n") + os.lseek(f.fd, 0, os.SEEK_SET) + self.assertEquals(os.read(f.fd, 20), b"blat") test_classes.append(test__mkstemp_inner) @@ -761,6 +765,10 @@ class test_SpooledTemporaryFile(TC): f.write("xyzzy\n") f.seek(0) self.assertEqual(f.read(), "abc\ndef\nxyzzy\n") + # Check that Ctrl+Z doesn't truncate the file + f.write("foo\x1abar\n") + f.seek(0) + self.assertEqual(f.read(), "abc\ndef\nxyzzy\nfoo\x1abar\n") def test_text_newline_and_encoding(self): f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, diff --git a/Misc/NEWS b/Misc/NEWS index 96fbbce..d3da7b9 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,9 @@ What's New in Python 3.2 Alpha 1? Core and Builtins ----------------- +- Issue #6077: On Windows, files opened with tempfile.TemporaryFile in "wt+" + mode would appear truncated on the first '0x1a' byte (aka. Ctrl+Z). + - Issue #7085: Fix crash when importing some extensions in a thread on MacOSX 10.6. -- cgit v0.12