4 py_maj = sys.version_info.major
7 # pylint: disable=unused-import
8 from contextlib import ExitStack, nullcontext
9 from os import environb as environ
10 from os import fsdecode, fsencode
11 from shlex import quote
12 ModuleNotFoundError = ModuleNotFoundError
19 """Return hex string (not bytes as with hexlify) representation of b."""
23 raise ex.with_traceback(sys.exc_info()[2])
25 # These three functions (add_ex_tb, add_ex_ctx, and pending_raise) are
26 # vestigial, and code that uses them can probably be rewritten more
27 # simply now that we require Python versions that automatically
28 # populate the tracebacks and automatically chain pending exceptions.
31 """Do nothing (already handled by Python 3 infrastructure)."""
34 def add_ex_ctx(ex, context_ex):
35 """Do nothing (already handled by Python 3 infrastructure)."""
39 """If rethrow is true, rethrow ex (if any), unless the body throws.
41 (Supports Python 2 compatibility.)
44 # This is completely vestigial, and should be removed
45 def __init__(self, ex, rethrow=True):
48 self.rethrow = rethrow
51 def __exit__(self, exc_type, exc_value, traceback):
53 if not exc_type and self.ex and self.rethrow:
62 """Return the original bytes passed to main() for an argv argument."""
65 def bytes_from_uint(i):
68 def bytes_from_byte(b): # python > 2: b[3] returns ord('x'), not b'x'
71 byte_int = lambda x: x
73 def buffer(object, offset=None, size=None):
75 assert offset is not None
76 return memoryview(object)[offset:offset + size]
78 return memoryview(object)[offset:]
79 return memoryview(object)
82 return fsencode(os.getcwd())
87 except ModuleNotFoundError:
92 "Return a new list containing the current process argv bytes."
93 return bup_main.argv()
95 "Return a new list containing the current process argv strings."
96 return [x.decode(errors='surrogateescape') for x in bup_main.argv()]
99 raise Exception('get_argvb requires the bup_main module');
101 raise Exception('get_argv requires the bup_main module');
104 """Run main() and raise a SystemExit with the return value if it
105 returns, pass along any SystemExit it raises, convert
106 KeyboardInterrupts into exit(130), and print a Python 3 style
107 contextual backtrace for other exceptions in both Python 2 and
111 except KeyboardInterrupt as ex: