]> arthur.barton.de Git - bup.git/blob - lib/bup/io.py
Update base_version to 0.34~ for 0.34 development
[bup.git] / lib / bup / io.py
1
2 import mmap as py_mmap
3
4 from bup.compat import pending_raise
5
6
7 def byte_stream(file):
8     return file.buffer
9
10 def path_msg(x):
11     """Return a string representation of a path."""
12     # FIXME: configurability (might git-config quotePath be involved?)
13     return x.decode(errors='backslashreplace')
14
15
16 assert not hasattr(py_mmap.mmap, '__del__')
17 if hasattr(py_mmap.mmap, '__enter__'):
18     assert hasattr(py_mmap.mmap, '__exit__')
19
20 class mmap(py_mmap.mmap):
21     '''mmap.mmap wrapper that detects and complains about any instances
22     that aren't explicitly closed.
23
24     '''
25     def __new__(cls, *args, **kwargs):
26         result = super().__new__(cls, *args, **kwargs)
27         result._bup_closed = True  # supports __del__
28         return result
29
30     def __init__(self, *args, **kwargs):
31         # Silence deprecation warnings.  mmap's current parent is
32         # object, which accepts no params and as of at least 2.7
33         # warns about them.
34         if py_mmap.mmap.__init__ is not object.__init__:
35             super().__init__(self, *args, **kwargs)
36         self._bup_closed = False
37
38     def close(self):
39         self._bup_closed = True
40         super(mmap, self).close()
41
42     if hasattr(py_mmap.mmap, '__enter__'):
43         def __enter__(self):
44             super(mmap, self).__enter__()
45             return self
46         def __exit__(self, type, value, traceback):
47             # Don't call self.close() when the parent has its own __exit__;
48             # defer to it.
49             self._bup_closed = True
50             result = super(mmap, self).__exit__(type, value, traceback)
51             return result
52     else:
53         def __enter__(self):
54             return self
55         def __exit__(self, type, value, traceback):
56             with pending_raise(value, rethrow=False):
57                 self.close()
58
59     def __del__(self):
60         assert self._bup_closed