diff options
Diffstat (limited to 'Lib/test/test_mmap.py')
| -rw-r--r-- | Lib/test/test_mmap.py | 523 |
1 files changed, 264 insertions, 259 deletions
diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 0701b96..28b52a9 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -1,8 +1,13 @@ -from test.test_support import (TESTFN, run_unittest, import_module, unlink, - requires, _2G, _4G) +from test.support import (TESTFN, run_unittest, import_module, unlink, + requires, _2G, _4G) import unittest -import os, re, itertools, socket, sys +import os +import re +import itertools +import socket +import sys +# Skip test if we can't import mmap. mmap = import_module('mmap') PAGESIZE = mmap.PAGESIZE @@ -23,222 +28,212 @@ class MmapTests(unittest.TestCase): # Test mmap module on Unix systems and Windows # Create a file to be mmap'ed. - f = open(TESTFN, 'w+') + f = open(TESTFN, 'bw+') try: # Write 2 pages worth of data to the file - f.write('\0'* PAGESIZE) - f.write('foo') - f.write('\0'* (PAGESIZE-3) ) + f.write(b'\0'* PAGESIZE) + f.write(b'foo') + f.write(b'\0'* (PAGESIZE-3) ) f.flush() m = mmap.mmap(f.fileno(), 2 * PAGESIZE) + finally: f.close() - # Simple sanity checks + # Simple sanity checks - tp = str(type(m)) # SF bug 128713: segfaulted on Linux - self.assertEqual(m.find('foo'), PAGESIZE) + tp = str(type(m)) # SF bug 128713: segfaulted on Linux + self.assertEqual(m.find(b'foo'), PAGESIZE) - self.assertEqual(len(m), 2*PAGESIZE) + self.assertEqual(len(m), 2*PAGESIZE) - self.assertEqual(m[0], '\0') - self.assertEqual(m[0:3], '\0\0\0') + self.assertEqual(m[0], 0) + self.assertEqual(m[0:3], b'\0\0\0') - # Shouldn't crash on boundary (Issue #5292) - self.assertRaises(IndexError, m.__getitem__, len(m)) - self.assertRaises(IndexError, m.__setitem__, len(m), '\0') + # Shouldn't crash on boundary (Issue #5292) + self.assertRaises(IndexError, m.__getitem__, len(m)) + self.assertRaises(IndexError, m.__setitem__, len(m), b'\0') - # Modify the file's content - m[0] = '3' - m[PAGESIZE +3: PAGESIZE +3+3] = 'bar' + # Modify the file's content + m[0] = b'3'[0] + m[PAGESIZE +3: PAGESIZE +3+3] = b'bar' - # Check that the modification worked - self.assertEqual(m[0], '3') - self.assertEqual(m[0:3], '3\0\0') - self.assertEqual(m[PAGESIZE-1 : PAGESIZE + 7], '\0foobar\0') + # Check that the modification worked + self.assertEqual(m[0], b'3'[0]) + self.assertEqual(m[0:3], b'3\0\0') + self.assertEqual(m[PAGESIZE-1 : PAGESIZE + 7], b'\0foobar\0') - m.flush() + m.flush() - # Test doing a regular expression match in an mmap'ed file - match = re.search('[A-Za-z]+', m) - if match is None: - self.fail('regex match on mmap failed!') - else: - start, end = match.span(0) - length = end - start + # Test doing a regular expression match in an mmap'ed file + match = re.search(b'[A-Za-z]+', m) + if match is None: + self.fail('regex match on mmap failed!') + else: + start, end = match.span(0) + length = end - start - self.assertEqual(start, PAGESIZE) - self.assertEqual(end, PAGESIZE + 6) + self.assertEqual(start, PAGESIZE) + self.assertEqual(end, PAGESIZE + 6) - # test seeking around (try to overflow the seek implementation) - m.seek(0,0) - self.assertEqual(m.tell(), 0) - m.seek(42,1) - self.assertEqual(m.tell(), 42) - m.seek(0,2) - self.assertEqual(m.tell(), len(m)) + # test seeking around (try to overflow the seek implementation) + m.seek(0,0) + self.assertEqual(m.tell(), 0) + m.seek(42,1) + self.assertEqual(m.tell(), 42) + m.seek(0,2) + self.assertEqual(m.tell(), len(m)) - # Try to seek to negative position... - self.assertRaises(ValueError, m.seek, -1) + # Try to seek to negative position... + self.assertRaises(ValueError, m.seek, -1) - # Try to seek beyond end of mmap... - self.assertRaises(ValueError, m.seek, 1, 2) + # Try to seek beyond end of mmap... + self.assertRaises(ValueError, m.seek, 1, 2) - # Try to seek to negative position... - self.assertRaises(ValueError, m.seek, -len(m)-1, 2) + # Try to seek to negative position... + self.assertRaises(ValueError, m.seek, -len(m)-1, 2) - # Try resizing map + # Try resizing map + try: + m.resize(512) + except SystemError: + # resize() not supported + # No messages are printed, since the output of this test suite + # would then be different across platforms. + pass + else: + # resize() is supported + self.assertEqual(len(m), 512) + # Check that we can no longer seek beyond the new size. + self.assertRaises(ValueError, m.seek, 513, 0) + + # Check that the underlying file is truncated too + # (bug #728515) + f = open(TESTFN, 'rb') try: - m.resize(512) - except SystemError: - # resize() not supported - # No messages are printed, since the output of this test suite - # would then be different across platforms. - pass - else: - # resize() is supported - self.assertEqual(len(m), 512) - # Check that we can no longer seek beyond the new size. - self.assertRaises(ValueError, m.seek, 513, 0) - - # Check that the underlying file is truncated too - # (bug #728515) - f = open(TESTFN) f.seek(0, 2) self.assertEqual(f.tell(), 512) + finally: f.close() - self.assertEqual(m.size(), 512) - - m.close() + self.assertEqual(m.size(), 512) - finally: - try: - f.close() - except OSError: - pass + m.close() def test_access_parameter(self): # Test for "access" keyword parameter mapsize = 10 - open(TESTFN, "wb").write("a"*mapsize) - f = open(TESTFN, "rb") - m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_READ) - self.assertEqual(m[:], 'a'*mapsize, "Readonly memory map data incorrect.") + with open(TESTFN, "wb") as fp: + fp.write(b"a"*mapsize) + with open(TESTFN, "rb") as f: + m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_READ) + self.assertEqual(m[:], b'a'*mapsize, "Readonly memory map data incorrect.") - # Ensuring that readonly mmap can't be slice assigned - try: - m[:] = 'b'*mapsize - except TypeError: - pass - else: - self.fail("Able to write to readonly memory map") + # Ensuring that readonly mmap can't be slice assigned + try: + m[:] = b'b'*mapsize + except TypeError: + pass + else: + self.fail("Able to write to readonly memory map") - # Ensuring that readonly mmap can't be item assigned - try: - m[0] = 'b' - except TypeError: - pass - else: - self.fail("Able to write to readonly memory map") + # Ensuring that readonly mmap can't be item assigned + try: + m[0] = b'b' + except TypeError: + pass + else: + self.fail("Able to write to readonly memory map") - # Ensuring that readonly mmap can't be write() to - try: - m.seek(0,0) - m.write('abc') - except TypeError: - pass - else: - self.fail("Able to write to readonly memory map") + # Ensuring that readonly mmap can't be write() to + try: + m.seek(0,0) + m.write(b'abc') + except TypeError: + pass + else: + self.fail("Able to write to readonly memory map") - # Ensuring that readonly mmap can't be write_byte() to - try: - m.seek(0,0) - m.write_byte('d') - except TypeError: - pass - else: - self.fail("Able to write to readonly memory map") + # Ensuring that readonly mmap can't be write_byte() to + try: + m.seek(0,0) + m.write_byte(b'd') + except TypeError: + pass + else: + self.fail("Able to write to readonly memory map") - # Ensuring that readonly mmap can't be resized - try: - m.resize(2*mapsize) - except SystemError: # resize is not universally supported - pass - except TypeError: - pass - else: - self.fail("Able to resize readonly memory map") - f.close() - del m, f - self.assertEqual(open(TESTFN, "rb").read(), 'a'*mapsize, - "Readonly memory map data file was modified") + # Ensuring that readonly mmap can't be resized + try: + m.resize(2*mapsize) + except SystemError: # resize is not universally supported + pass + except TypeError: + pass + else: + self.fail("Able to resize readonly memory map") + with open(TESTFN, "rb") as fp: + self.assertEqual(fp.read(), b'a'*mapsize, + "Readonly memory map data file was modified") # Opening mmap with size too big - import sys - f = open(TESTFN, "r+b") - try: - m = mmap.mmap(f.fileno(), mapsize+1) - except ValueError: - # we do not expect a ValueError on Windows - # CAUTION: This also changes the size of the file on disk, and - # later tests assume that the length hasn't changed. We need to - # repair that. + with open(TESTFN, "r+b") as f: + try: + m = mmap.mmap(f.fileno(), mapsize+1) + except ValueError: + # we do not expect a ValueError on Windows + # CAUTION: This also changes the size of the file on disk, and + # later tests assume that the length hasn't changed. We need to + # repair that. + if sys.platform.startswith('win'): + self.fail("Opening mmap with size+1 should work on Windows.") + else: + # we expect a ValueError on Unix, but not on Windows + if not sys.platform.startswith('win'): + self.fail("Opening mmap with size+1 should raise ValueError.") + m.close() if sys.platform.startswith('win'): - self.fail("Opening mmap with size+1 should work on Windows.") - else: - # we expect a ValueError on Unix, but not on Windows - if not sys.platform.startswith('win'): - self.fail("Opening mmap with size+1 should raise ValueError.") - m.close() - f.close() - if sys.platform.startswith('win'): - # Repair damage from the resizing test. - f = open(TESTFN, 'r+b') - f.truncate(mapsize) - f.close() + # Repair damage from the resizing test. + with open(TESTFN, 'r+b') as f: + f.truncate(mapsize) # Opening mmap with access=ACCESS_WRITE - f = open(TESTFN, "r+b") - m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_WRITE) - # Modifying write-through memory map - m[:] = 'c'*mapsize - self.assertEqual(m[:], 'c'*mapsize, - "Write-through memory map memory not updated properly.") - m.flush() - m.close() - f.close() - f = open(TESTFN, 'rb') - stuff = f.read() - f.close() - self.assertEqual(stuff, 'c'*mapsize, + with open(TESTFN, "r+b") as f: + m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_WRITE) + # Modifying write-through memory map + m[:] = b'c'*mapsize + self.assertEqual(m[:], b'c'*mapsize, + "Write-through memory map memory not updated properly.") + m.flush() + m.close() + with open(TESTFN, 'rb') as f: + stuff = f.read() + self.assertEqual(stuff, b'c'*mapsize, "Write-through memory map data file not updated properly.") # Opening mmap with access=ACCESS_COPY - f = open(TESTFN, "r+b") - m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_COPY) - # Modifying copy-on-write memory map - m[:] = 'd'*mapsize - self.assertEqual(m[:], 'd' * mapsize, - "Copy-on-write memory map data not written correctly.") - m.flush() - self.assertEqual(open(TESTFN, "rb").read(), 'c'*mapsize, - "Copy-on-write test data file should not be modified.") - # Ensuring copy-on-write maps cannot be resized - self.assertRaises(TypeError, m.resize, 2*mapsize) - f.close() - del m, f + with open(TESTFN, "r+b") as f: + m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_COPY) + # Modifying copy-on-write memory map + m[:] = b'd'*mapsize + self.assertEqual(m[:], b'd' * mapsize, + "Copy-on-write memory map data not written correctly.") + m.flush() + with open(TESTFN, "rb") as fp: + self.assertEqual(fp.read(), b'c'*mapsize, + "Copy-on-write test data file should not be modified.") + # Ensuring copy-on-write maps cannot be resized + self.assertRaises(TypeError, m.resize, 2*mapsize) + m.close() # Ensuring invalid access parameter raises exception - f = open(TESTFN, "r+b") - self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize, access=4) - f.close() + with open(TESTFN, "r+b") as f: + self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize, access=4) if os.name == "posix": # Try incompatible flags, prot and access parameters. - f = open(TESTFN, "r+b") - self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize, - flags=mmap.MAP_PRIVATE, - prot=mmap.PROT_READ, access=mmap.ACCESS_WRITE) - f.close() + with open(TESTFN, "r+b") as f: + self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize, + flags=mmap.MAP_PRIVATE, + prot=mmap.PROT_READ, access=mmap.ACCESS_WRITE) # Try writing with PROT_EXEC and without PROT_WRITE prot = mmap.PROT_READ | getattr(mmap, 'PROT_EXEC', 0) @@ -255,66 +250,65 @@ class MmapTests(unittest.TestCase): def test_tougher_find(self): # Do a tougher .find() test. SF bug 515943 pointed out that, in 2.2, # searching for data with embedded \0 bytes didn't work. - f = open(TESTFN, 'w+') + with open(TESTFN, 'wb+') as f: - data = 'aabaac\x00deef\x00\x00aa\x00' - n = len(data) - f.write(data) - f.flush() - m = mmap.mmap(f.fileno(), n) - f.close() + data = b'aabaac\x00deef\x00\x00aa\x00' + n = len(data) + f.write(data) + f.flush() + m = mmap.mmap(f.fileno(), n) for start in range(n+1): for finish in range(start, n+1): slice = data[start : finish] self.assertEqual(m.find(slice), data.find(slice)) - self.assertEqual(m.find(slice + 'x'), -1) + self.assertEqual(m.find(slice + b'x'), -1) m.close() def test_find_end(self): # test the new 'end' parameter works as expected - f = open(TESTFN, 'w+') - data = 'one two ones' + f = open(TESTFN, 'wb+') + data = b'one two ones' n = len(data) f.write(data) f.flush() m = mmap.mmap(f.fileno(), n) f.close() - self.assertEqual(m.find('one'), 0) - self.assertEqual(m.find('ones'), 8) - self.assertEqual(m.find('one', 0, -1), 0) - self.assertEqual(m.find('one', 1), 8) - self.assertEqual(m.find('one', 1, -1), 8) - self.assertEqual(m.find('one', 1, -2), -1) + self.assertEqual(m.find(b'one'), 0) + self.assertEqual(m.find(b'ones'), 8) + self.assertEqual(m.find(b'one', 0, -1), 0) + self.assertEqual(m.find(b'one', 1), 8) + self.assertEqual(m.find(b'one', 1, -1), 8) + self.assertEqual(m.find(b'one', 1, -2), -1) def test_rfind(self): # test the new 'end' parameter works as expected - f = open(TESTFN, 'w+') - data = 'one two ones' + f = open(TESTFN, 'wb+') + data = b'one two ones' n = len(data) f.write(data) f.flush() m = mmap.mmap(f.fileno(), n) f.close() - self.assertEqual(m.rfind('one'), 8) - self.assertEqual(m.rfind('one '), 0) - self.assertEqual(m.rfind('one', 0, -1), 8) - self.assertEqual(m.rfind('one', 0, -2), 0) - self.assertEqual(m.rfind('one', 1, -1), 8) - self.assertEqual(m.rfind('one', 1, -2), -1) + self.assertEqual(m.rfind(b'one'), 8) + self.assertEqual(m.rfind(b'one '), 0) + self.assertEqual(m.rfind(b'one', 0, -1), 8) + self.assertEqual(m.rfind(b'one', 0, -2), 0) + self.assertEqual(m.rfind(b'one', 1, -1), 8) + self.assertEqual(m.rfind(b'one', 1, -2), -1) def test_double_close(self): # make sure a double close doesn't crash on Solaris (Bug# 665913) - f = open(TESTFN, 'w+') + f = open(TESTFN, 'wb+') - f.write(2**16 * 'a') # Arbitrary character + f.write(2**16 * b'a') # Arbitrary character f.close() - f = open(TESTFN) + f = open(TESTFN, 'rb') mf = mmap.mmap(f.fileno(), 2**16, access=mmap.ACCESS_READ) mf.close() mf.close() @@ -323,15 +317,15 @@ class MmapTests(unittest.TestCase): def test_entire_file(self): # test mapping of entire file by passing 0 for map length if hasattr(os, "stat"): - f = open(TESTFN, "w+") + f = open(TESTFN, "wb+") - f.write(2**16 * 'm') # Arbitrary character + f.write(2**16 * b'm') # Arbitrary character f.close() f = open(TESTFN, "rb+") mf = mmap.mmap(f.fileno(), 0) self.assertEqual(len(mf), 2**16, "Map size should equal file size.") - self.assertEqual(mf.read(2**16), 2**16 * "m") + self.assertEqual(mf.read(2**16), 2**16 * b"m") mf.close() f.close() @@ -346,11 +340,8 @@ class MmapTests(unittest.TestCase): f.write((65536 * 2) * b'm') # Arbitrary character with open(TESTFN, "rb") as f: - mf = mmap.mmap(f.fileno(), 0, offset=65536, access=mmap.ACCESS_READ) - try: + with mmap.mmap(f.fileno(), 0, offset=65536, access=mmap.ACCESS_READ) as mf: self.assertRaises(IndexError, mf.__getitem__, 80000) - finally: - mf.close() def test_length_0_large_offset(self): # Issue #10959: test mapping of a file by passing 0 for @@ -367,19 +358,19 @@ class MmapTests(unittest.TestCase): def test_move(self): # make move works everywhere (64-bit format problem earlier) - f = open(TESTFN, 'w+') + f = open(TESTFN, 'wb+') - f.write("ABCDEabcde") # Arbitrary character + f.write(b"ABCDEabcde") # Arbitrary character f.flush() mf = mmap.mmap(f.fileno(), 10) mf.move(5, 0, 5) - self.assertEqual(mf[:], "ABCDEABCDE", "Map move should have duplicated front 5") + self.assertEqual(mf[:], b"ABCDEABCDE", "Map move should have duplicated front 5") mf.close() f.close() # more excessive test - data = "0123456789" + data = b"0123456789" for dest in range(len(data)): for src in range(len(data)): for count in range(len(data) - max(dest, src)): @@ -417,16 +408,18 @@ class MmapTests(unittest.TestCase): def test_anonymous(self): # anonymous mmap.mmap(-1, PAGE) m = mmap.mmap(-1, PAGESIZE) - for x in xrange(PAGESIZE): - self.assertEqual(m[x], '\0', "anonymously mmap'ed contents should be zero") + for x in range(PAGESIZE): + self.assertEqual(m[x], 0, + "anonymously mmap'ed contents should be zero") - for x in xrange(PAGESIZE): - m[x] = ch = chr(x & 255) - self.assertEqual(m[x], ch) + for x in range(PAGESIZE): + b = x & 0xff + m[x] = b + self.assertEqual(m[x], b) def test_extended_getslice(self): # Test extended slicing by comparing with list slicing. - s = "".join(chr(c) for c in reversed(range(256))) + s = bytes(reversed(range(256))) m = mmap.mmap(-1, len(s)) m[:] = s self.assertEqual(m[:], s) @@ -440,7 +433,7 @@ class MmapTests(unittest.TestCase): def test_extended_set_del_slice(self): # Test extended slicing by comparing with list slicing. - s = "".join(chr(c) for c in reversed(range(256))) + s = bytes(reversed(range(256))) m = mmap.mmap(-1, len(s)) indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300) for start in indices: @@ -453,16 +446,16 @@ class MmapTests(unittest.TestCase): # Make sure we have a slice of exactly the right length, # but with different data. data = L[start:stop:step] - data = "".join(reversed(data)) + data = bytes(reversed(data)) L[start:stop:step] = data m[start:stop:step] = data - self.assertEqual(m[:], "".join(L)) + self.assertEqual(m[:], bytes(L)) def make_mmap_file (self, f, halfsize): # Write 2 pages worth of data to the file - f.write ('\0' * halfsize) - f.write ('foo') - f.write ('\0' * (halfsize - 3)) + f.write (b'\0' * halfsize) + f.write (b'foo') + f.write (b'\0' * (halfsize - 3)) f.flush () return mmap.mmap (f.fileno(), 0) @@ -470,14 +463,10 @@ class MmapTests(unittest.TestCase): f = open (TESTFN, 'w+b') f.close() with open(TESTFN, "rb") as f : - try: - m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) - m.close() - self.fail("should not have been able to mmap empty file") - except ValueError as e: - self.assertEqual(e.message, "cannot mmap an empty file") - except: - self.fail("unexpected exception: " + str(e)) + self.assertRaisesRegex(ValueError, + "cannot mmap an empty file", + mmap.mmap, f.fileno(), 0, + access=mmap.ACCESS_READ) def test_offset (self): f = open (TESTFN, 'w+b') @@ -504,7 +493,7 @@ class MmapTests(unittest.TestCase): # Try valid offset, hopefully 8192 works on all OSes f = open(TESTFN, "r+b") m = mmap.mmap(f.fileno(), mapsize - halfsize, offset=halfsize) - self.assertEqual(m[0:3], 'foo') + self.assertEqual(m[0:3], b'foo') f.close() # Try resizing map @@ -518,10 +507,10 @@ class MmapTests(unittest.TestCase): # Check that we can no longer seek beyond the new size. self.assertRaises(ValueError, m.seek, 513, 0) # Check that the content is not changed - self.assertEqual(m[0:3], 'foo') + self.assertEqual(m[0:3], b'foo') # Check that the underlying file is truncated too - f = open(TESTFN) + f = open(TESTFN, 'rb') f.seek(0, 2) self.assertEqual(f.tell(), halfsize + 512) f.close() @@ -546,7 +535,8 @@ class MmapTests(unittest.TestCase): if not hasattr(mmap, 'PROT_READ'): return mapsize = 10 - open(TESTFN, "wb").write("a"*mapsize) + with open(TESTFN, "wb") as fp: + fp.write(b"a"*mapsize) f = open(TESTFN, "rb") m = mmap.mmap(f.fileno(), mapsize, prot=mmap.PROT_READ) self.assertRaises(TypeError, m.write, "foo") @@ -557,41 +547,51 @@ class MmapTests(unittest.TestCase): self.assertIn("mmap.error", str(mmap.error)) def test_io_methods(self): - data = "0123456789" - open(TESTFN, "wb").write("x"*len(data)) + data = b"0123456789" + with open(TESTFN, "wb") as fp: + fp.write(b"x"*len(data)) f = open(TESTFN, "r+b") m = mmap.mmap(f.fileno(), len(data)) f.close() # Test write_byte() - for i in xrange(len(data)): + for i in range(len(data)): self.assertEqual(m.tell(), i) m.write_byte(data[i]) self.assertEqual(m.tell(), i+1) - self.assertRaises(ValueError, m.write_byte, "x") + self.assertRaises(ValueError, m.write_byte, b"x"[0]) self.assertEqual(m[:], data) # Test read_byte() m.seek(0) - for i in xrange(len(data)): + for i in range(len(data)): self.assertEqual(m.tell(), i) self.assertEqual(m.read_byte(), data[i]) self.assertEqual(m.tell(), i+1) self.assertRaises(ValueError, m.read_byte) # Test read() m.seek(3) - self.assertEqual(m.read(3), "345") + self.assertEqual(m.read(3), b"345") self.assertEqual(m.tell(), 6) # Test write() m.seek(3) - m.write("bar") + m.write(b"bar") self.assertEqual(m.tell(), 6) - self.assertEqual(m[:], "012bar6789") + self.assertEqual(m[:], b"012bar6789") m.seek(8) - self.assertRaises(ValueError, m.write, "bar") + self.assertRaises(ValueError, m.write, b"bar") + + def test_non_ascii_byte(self): + for b in (129, 200, 255): # > 128 + m = mmap.mmap(-1, 1) + m.write_byte(b) + self.assertEqual(m[0], b) + m.seek(0) + self.assertEqual(m.read_byte(), b) + m.close() if os.name == 'nt': def test_tagname(self): - data1 = "0123456789" - data2 = "abcdefghij" + data1 = b"0123456789" + data2 = b"abcdefghij" assert len(data1) == len(data2) # Test same tag @@ -624,7 +624,8 @@ class MmapTests(unittest.TestCase): m.close() # Should not crash (Issue 5385) - open(TESTFN, "wb").write("x"*10) + with open(TESTFN, "wb") as fp: + fp.write(b"x"*10) f = open(TESTFN, "r+b") m = mmap.mmap(f.fileno(), 0) f.close() @@ -649,6 +650,19 @@ class MmapTests(unittest.TestCase): finally: s.close() + def test_context_manager(self): + with mmap.mmap(-1, 10) as m: + self.assertFalse(m.closed) + self.assertTrue(m.closed) + + def test_context_manager_exception(self): + # Test that the IOError gets passed through + with self.assertRaises(Exception) as exc: + with mmap.mmap(-1, 10) as m: + raise IOError + self.assertIsInstance(exc.exception, IOError, + "wrong exception raised in context manager") + self.assertTrue(m.closed, "context manager failed") class LargeMmapTests(unittest.TestCase): @@ -674,19 +688,13 @@ class LargeMmapTests(unittest.TestCase): def test_large_offset(self): with self._make_test_file(0x14FFFFFFF, b" ") as f: - m = mmap.mmap(f.fileno(), 0, offset=0x140000000, access=mmap.ACCESS_READ) - try: - self.assertEqual(m[0xFFFFFFF], b" ") - finally: - m.close() + with mmap.mmap(f.fileno(), 0, offset=0x140000000, access=mmap.ACCESS_READ) as m: + self.assertEqual(m[0xFFFFFFF], 32) def test_large_filesize(self): with self._make_test_file(0x17FFFFFFF, b" ") as f: - m = mmap.mmap(f.fileno(), 0x10000, access=mmap.ACCESS_READ) - try: + with mmap.mmap(f.fileno(), 0x10000, access=mmap.ACCESS_READ) as m: self.assertEqual(m.size(), 0x180000000) - finally: - m.close() # Issue 11277: mmap() with large (~4GB) sparse files crashes on OS X. @@ -695,11 +703,8 @@ class LargeMmapTests(unittest.TestCase): start = boundary - len(tail) // 2 end = start + len(tail) with self._make_test_file(start, tail) as f: - m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) - try: + with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as m: self.assertEqual(m[start:end], tail) - finally: - m.close() @unittest.skipUnless(sys.maxsize > _4G, "test cannot run on 32-bit systems") def test_around_2GB(self): |
