from bup import _helpers
from bup import compat
-from bup.compat import argv_bytes, byte_int, pending_raise
+from bup.compat import argv_bytes, byte_int, nullcontext, pending_raise
from bup.io import byte_stream, path_msg
# This function should really be in helpers, not in bup.options. But we
# want options.py to be standalone so people can include it in other projects.
pass
+def nullcontext_if_not(manager):
+ return manager if manager is not None else nullcontext()
+
+
+@contextmanager
+def finalized(enter_result=None, finalize=None):
+ assert finalize
+ try:
+ yield enter_result
+ except BaseException as ex:
+ with pending_raise(ex):
+ finalize(enter_result)
+ finalize(enter_result)
+
+
sc_page_size = os.sysconf('SC_PAGE_SIZE')
assert(sc_page_size > 0)
if isinstance(x, compat.str_type):
return squote(x)
assert False
+ # some versions of pylint get confused
+ return None
def shstr(cmd):
"""Return a shell quoted string for cmd if it's a sequence, else cmd.
class BaseConn:
def __init__(self, outp):
+ self._base_closed = False
self.outp = outp
def close(self):
- while self._read(65536): pass
+ self._base_closed = True
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_value, tb):
+ with pending_raise(exc_value, rethrow=False):
+ self.close()
+
+ def __del__(self):
+ assert self._base_closed
def _read(self, size):
raise NotImplementedError("Subclasses must implement _read")
# string has all the same behaviour of a zero-length map, ie. it has
# no elements :)
return ''
- map = mmap.mmap(f.fileno(), sz, flags, prot)
+ map = compat.mmap(f.fileno(), sz, flags, prot)
if close:
f.close() # map will persist beyond file close
return map
pos = _fmincore_chunk_size * ci;
msize = min(_fmincore_chunk_size, st.st_size - pos)
try:
- m = mmap.mmap(fd, msize, mmap.MAP_PRIVATE, 0, 0, pos)
+ m = compat.mmap(fd, msize, mmap.MAP_PRIVATE, 0, 0, pos)
except mmap.error as ex:
if ex.errno == errno.EINVAL or ex.errno == errno.ENODEV:
# Perhaps the file was a pipe, i.e. "... | bup split ..."
if exctype == KeyboardInterrupt:
log('\nInterrupted.\n')
else:
- return oldhook(exctype, value, traceback)
+ oldhook(exctype, value, traceback)
sys.excepthook = newhook