Skip to content

Commit b8baa33

Browse files
[3.6] bpo-33753: Refactor creating temporary files in test_fileinput. (GH-7377). (GH-7431)
(cherry picked from commit 5f48e26)
1 parent 194a5c0 commit b8baa33

File tree

1 file changed

+88
-126
lines changed

1 file changed

+88
-126
lines changed

Lib/test/test_fileinput.py

Lines changed: 88 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import fileinput
99
import collections
1010
import builtins
11+
import tempfile
1112
import unittest
1213

1314
try:
@@ -32,20 +33,15 @@
3233
# all the work, and a few functions (input, etc.) that use a global _state
3334
# variable.
3435

35-
# Write lines (a list of lines) to temp file number i, and return the
36-
# temp file's name.
37-
def writeTmp(i, lines, mode='w'): # opening in text mode is the default
38-
name = TESTFN + str(i)
39-
f = open(name, mode)
40-
for line in lines:
41-
f.write(line)
42-
f.close()
43-
return name
44-
45-
def remove_tempfiles(*names):
46-
for name in names:
47-
if name:
48-
safe_unlink(name)
36+
class BaseTests:
37+
# Write a content (str or bytes) to temp file, and return the
38+
# temp file's name.
39+
def writeTmp(self, content, *, mode='w'): # opening in text mode is the default
40+
fd, name = tempfile.mkstemp()
41+
self.addCleanup(support.unlink, name)
42+
with open(fd, mode) as f:
43+
f.write(content)
44+
return name
4945

5046
class LineReader:
5147

@@ -83,23 +79,19 @@ def readlines(self, hint=-1):
8379
def close(self):
8480
pass
8581

86-
class BufferSizesTests(unittest.TestCase):
82+
class BufferSizesTests(BaseTests, unittest.TestCase):
8783
def test_buffer_sizes(self):
8884
# First, run the tests with default and teeny buffer size.
8985
for round, bs in (0, 0), (1, 30):
90-
t1 = t2 = t3 = t4 = None
91-
try:
92-
t1 = writeTmp(1, ["Line %s of file 1\n" % (i+1) for i in range(15)])
93-
t2 = writeTmp(2, ["Line %s of file 2\n" % (i+1) for i in range(10)])
94-
t3 = writeTmp(3, ["Line %s of file 3\n" % (i+1) for i in range(5)])
95-
t4 = writeTmp(4, ["Line %s of file 4\n" % (i+1) for i in range(1)])
96-
if bs:
97-
with self.assertWarns(DeprecationWarning):
98-
self.buffer_size_test(t1, t2, t3, t4, bs, round)
99-
else:
86+
t1 = self.writeTmp(''.join("Line %s of file 1\n" % (i+1) for i in range(15)))
87+
t2 = self.writeTmp(''.join("Line %s of file 2\n" % (i+1) for i in range(10)))
88+
t3 = self.writeTmp(''.join("Line %s of file 3\n" % (i+1) for i in range(5)))
89+
t4 = self.writeTmp(''.join("Line %s of file 4\n" % (i+1) for i in range(1)))
90+
if bs:
91+
with self.assertWarns(DeprecationWarning):
10092
self.buffer_size_test(t1, t2, t3, t4, bs, round)
101-
finally:
102-
remove_tempfiles(t1, t2, t3, t4)
93+
else:
94+
self.buffer_size_test(t1, t2, t3, t4, bs, round)
10395

10496
def buffer_size_test(self, t1, t2, t3, t4, bs=0, round=0):
10597
pat = re.compile(r'LINE (\d+) OF FILE (\d+)')
@@ -186,74 +178,59 @@ def __call__(self, *args, **kwargs):
186178
self.invoked = True
187179
raise self.exception_type()
188180

189-
class FileInputTests(unittest.TestCase):
181+
class FileInputTests(BaseTests, unittest.TestCase):
190182

191183
def test_zero_byte_files(self):
192-
t1 = t2 = t3 = t4 = None
193-
try:
194-
t1 = writeTmp(1, [""])
195-
t2 = writeTmp(2, [""])
196-
t3 = writeTmp(3, ["The only line there is.\n"])
197-
t4 = writeTmp(4, [""])
198-
fi = FileInput(files=(t1, t2, t3, t4))
199-
200-
line = fi.readline()
201-
self.assertEqual(line, 'The only line there is.\n')
202-
self.assertEqual(fi.lineno(), 1)
203-
self.assertEqual(fi.filelineno(), 1)
204-
self.assertEqual(fi.filename(), t3)
205-
206-
line = fi.readline()
207-
self.assertFalse(line)
208-
self.assertEqual(fi.lineno(), 1)
209-
self.assertEqual(fi.filelineno(), 0)
210-
self.assertEqual(fi.filename(), t4)
211-
fi.close()
212-
finally:
213-
remove_tempfiles(t1, t2, t3, t4)
184+
t1 = self.writeTmp("")
185+
t2 = self.writeTmp("")
186+
t3 = self.writeTmp("The only line there is.\n")
187+
t4 = self.writeTmp("")
188+
fi = FileInput(files=(t1, t2, t3, t4))
189+
190+
line = fi.readline()
191+
self.assertEqual(line, 'The only line there is.\n')
192+
self.assertEqual(fi.lineno(), 1)
193+
self.assertEqual(fi.filelineno(), 1)
194+
self.assertEqual(fi.filename(), t3)
195+
196+
line = fi.readline()
197+
self.assertFalse(line)
198+
self.assertEqual(fi.lineno(), 1)
199+
self.assertEqual(fi.filelineno(), 0)
200+
self.assertEqual(fi.filename(), t4)
201+
fi.close()
214202

215203
def test_files_that_dont_end_with_newline(self):
216-
t1 = t2 = None
217-
try:
218-
t1 = writeTmp(1, ["A\nB\nC"])
219-
t2 = writeTmp(2, ["D\nE\nF"])
220-
fi = FileInput(files=(t1, t2))
221-
lines = list(fi)
222-
self.assertEqual(lines, ["A\n", "B\n", "C", "D\n", "E\n", "F"])
223-
self.assertEqual(fi.filelineno(), 3)
224-
self.assertEqual(fi.lineno(), 6)
225-
finally:
226-
remove_tempfiles(t1, t2)
204+
t1 = self.writeTmp("A\nB\nC")
205+
t2 = self.writeTmp("D\nE\nF")
206+
fi = FileInput(files=(t1, t2))
207+
lines = list(fi)
208+
self.assertEqual(lines, ["A\n", "B\n", "C", "D\n", "E\n", "F"])
209+
self.assertEqual(fi.filelineno(), 3)
210+
self.assertEqual(fi.lineno(), 6)
227211

228212
## def test_unicode_filenames(self):
229213
## # XXX A unicode string is always returned by writeTmp.
230214
## # So is this needed?
231-
## try:
232-
## t1 = writeTmp(1, ["A\nB"])
233-
## encoding = sys.getfilesystemencoding()
234-
## if encoding is None:
235-
## encoding = 'ascii'
236-
## fi = FileInput(files=str(t1, encoding))
237-
## lines = list(fi)
238-
## self.assertEqual(lines, ["A\n", "B"])
239-
## finally:
240-
## remove_tempfiles(t1)
215+
## t1 = self.writeTmp("A\nB")
216+
## encoding = sys.getfilesystemencoding()
217+
## if encoding is None:
218+
## encoding = 'ascii'
219+
## fi = FileInput(files=str(t1, encoding))
220+
## lines = list(fi)
221+
## self.assertEqual(lines, ["A\n", "B"])
241222

242223
def test_fileno(self):
243-
t1 = t2 = None
244-
try:
245-
t1 = writeTmp(1, ["A\nB"])
246-
t2 = writeTmp(2, ["C\nD"])
247-
fi = FileInput(files=(t1, t2))
248-
self.assertEqual(fi.fileno(), -1)
249-
line =next( fi)
250-
self.assertNotEqual(fi.fileno(), -1)
251-
fi.nextfile()
252-
self.assertEqual(fi.fileno(), -1)
253-
line = list(fi)
254-
self.assertEqual(fi.fileno(), -1)
255-
finally:
256-
remove_tempfiles(t1, t2)
224+
t1 = self.writeTmp("A\nB")
225+
t2 = self.writeTmp("C\nD")
226+
fi = FileInput(files=(t1, t2))
227+
self.assertEqual(fi.fileno(), -1)
228+
line = next(fi)
229+
self.assertNotEqual(fi.fileno(), -1)
230+
fi.nextfile()
231+
self.assertEqual(fi.fileno(), -1)
232+
line = list(fi)
233+
self.assertEqual(fi.fileno(), -1)
257234

258235
def test_opening_mode(self):
259236
try:
@@ -262,17 +239,13 @@ def test_opening_mode(self):
262239
self.fail("FileInput should reject invalid mode argument")
263240
except ValueError:
264241
pass
265-
t1 = None
266-
try:
267-
# try opening in universal newline mode
268-
t1 = writeTmp(1, [b"A\nB\r\nC\rD"], mode="wb")
269-
with check_warnings(('', DeprecationWarning)):
270-
fi = FileInput(files=t1, mode="U")
271-
with check_warnings(('', DeprecationWarning)):
272-
lines = list(fi)
273-
self.assertEqual(lines, ["A\n", "B\n", "C\n", "D"])
274-
finally:
275-
remove_tempfiles(t1)
242+
# try opening in universal newline mode
243+
t1 = self.writeTmp(b"A\nB\r\nC\rD", mode="wb")
244+
with check_warnings(('', DeprecationWarning)):
245+
fi = FileInput(files=t1, mode="U")
246+
with check_warnings(('', DeprecationWarning)):
247+
lines = list(fi)
248+
self.assertEqual(lines, ["A\n", "B\n", "C\n", "D"])
276249

277250
def test_stdin_binary_mode(self):
278251
with mock.patch('sys.stdin') as m_stdin:
@@ -313,8 +286,7 @@ def __call__(self, *args):
313286
self.invoked = True
314287
return open(*args)
315288

316-
t = writeTmp(1, ["\n"])
317-
self.addCleanup(remove_tempfiles, t)
289+
t = self.writeTmp("\n")
318290
custom_open_hook = CustomOpenHook()
319291
with FileInput([t], openhook=custom_open_hook) as fi:
320292
fi.readline()
@@ -357,27 +329,22 @@ def test_readline_binary_mode(self):
357329
self.assertEqual(fi.readline(), b'')
358330

359331
def test_context_manager(self):
360-
try:
361-
t1 = writeTmp(1, ["A\nB\nC"])
362-
t2 = writeTmp(2, ["D\nE\nF"])
363-
with FileInput(files=(t1, t2)) as fi:
364-
lines = list(fi)
365-
self.assertEqual(lines, ["A\n", "B\n", "C", "D\n", "E\n", "F"])
366-
self.assertEqual(fi.filelineno(), 3)
367-
self.assertEqual(fi.lineno(), 6)
368-
self.assertEqual(fi._files, ())
369-
finally:
370-
remove_tempfiles(t1, t2)
332+
t1 = self.writeTmp("A\nB\nC")
333+
t2 = self.writeTmp("D\nE\nF")
334+
with FileInput(files=(t1, t2)) as fi:
335+
lines = list(fi)
336+
self.assertEqual(lines, ["A\n", "B\n", "C", "D\n", "E\n", "F"])
337+
self.assertEqual(fi.filelineno(), 3)
338+
self.assertEqual(fi.lineno(), 6)
339+
self.assertEqual(fi._files, ())
371340

372341
def test_close_on_exception(self):
342+
t1 = self.writeTmp("")
373343
try:
374-
t1 = writeTmp(1, [""])
375344
with FileInput(files=t1) as fi:
376345
raise OSError
377346
except OSError:
378347
self.assertEqual(fi._files, ())
379-
finally:
380-
remove_tempfiles(t1)
381348

382349
def test_empty_files_list_specified_to_constructor(self):
383350
with FileInput(files=[]) as fi:
@@ -386,8 +353,7 @@ def test_empty_files_list_specified_to_constructor(self):
386353
def test__getitem__(self):
387354
"""Tests invoking FileInput.__getitem__() with the current
388355
line number"""
389-
t = writeTmp(1, ["line1\n", "line2\n"])
390-
self.addCleanup(remove_tempfiles, t)
356+
t = self.writeTmp("line1\nline2\n")
391357
with FileInput(files=[t]) as fi:
392358
retval1 = fi[0]
393359
self.assertEqual(retval1, "line1\n")
@@ -397,8 +363,7 @@ def test__getitem__(self):
397363
def test__getitem__invalid_key(self):
398364
"""Tests invoking FileInput.__getitem__() with an index unequal to
399365
the line number"""
400-
t = writeTmp(1, ["line1\n", "line2\n"])
401-
self.addCleanup(remove_tempfiles, t)
366+
t = self.writeTmp("line1\nline2\n")
402367
with FileInput(files=[t]) as fi:
403368
with self.assertRaises(RuntimeError) as cm:
404369
fi[1]
@@ -407,8 +372,7 @@ def test__getitem__invalid_key(self):
407372
def test__getitem__eof(self):
408373
"""Tests invoking FileInput.__getitem__() with the line number but at
409374
end-of-input"""
410-
t = writeTmp(1, [])
411-
self.addCleanup(remove_tempfiles, t)
375+
t = self.writeTmp('')
412376
with FileInput(files=[t]) as fi:
413377
with self.assertRaises(IndexError) as cm:
414378
fi[0]
@@ -422,8 +386,8 @@ def test_nextfile_oserror_deleting_backup(self):
422386
os_unlink_orig = os.unlink
423387
os_unlink_replacement = UnconditionallyRaise(OSError)
424388
try:
425-
t = writeTmp(1, ["\n"])
426-
self.addCleanup(remove_tempfiles, t)
389+
t = self.writeTmp("\n")
390+
self.addCleanup(support.unlink, t + '.bak')
427391
with FileInput(files=[t], inplace=True) as fi:
428392
next(fi) # make sure the file is opened
429393
os.unlink = os_unlink_replacement
@@ -442,8 +406,7 @@ def test_readline_os_fstat_raises_OSError(self):
442406
os_fstat_orig = os.fstat
443407
os_fstat_replacement = UnconditionallyRaise(OSError)
444408
try:
445-
t = writeTmp(1, ["\n"])
446-
self.addCleanup(remove_tempfiles, t)
409+
t = self.writeTmp("\n")
447410
with FileInput(files=[t], inplace=True) as fi:
448411
os.fstat = os_fstat_replacement
449412
fi.readline()
@@ -462,8 +425,7 @@ def test_readline_os_chmod_raises_OSError(self):
462425
os_chmod_orig = os.chmod
463426
os_chmod_replacement = UnconditionallyRaise(OSError)
464427
try:
465-
t = writeTmp(1, ["\n"])
466-
self.addCleanup(remove_tempfiles, t)
428+
t = self.writeTmp("\n")
467429
with FileInput(files=[t], inplace=True) as fi:
468430
os.chmod = os_chmod_replacement
469431
fi.readline()
@@ -482,8 +444,7 @@ def fileno(self):
482444
self.__call__()
483445

484446
unconditionally_raise_ValueError = FilenoRaisesValueError()
485-
t = writeTmp(1, ["\n"])
486-
self.addCleanup(remove_tempfiles, t)
447+
t = self.writeTmp("\n")
487448
with FileInput(files=[t]) as fi:
488449
file_backup = fi._file
489450
try:
@@ -530,6 +491,7 @@ def test_iteration_buffering(self):
530491
self.assertRaises(StopIteration, next, fi)
531492
self.assertEqual(src.linesread, [])
532493

494+
533495
class MockFileInput:
534496
"""A class that mocks out fileinput.FileInput for use during unit tests"""
535497

0 commit comments

Comments
 (0)