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
18 """Return hex string (not bytes as with hexlify) representation of b."""
22 raise ex.with_traceback(sys.exc_info()[2])
24 # These three functions (add_ex_tb, add_ex_ctx, and pending_raise) are
25 # vestigial, and code that uses them can probably be rewritten more
26 # simply now that we require Python versions that automatically
27 # populate the tracebacks and automatically chain pending exceptions.
30 """Do nothing (already handled by Python 3 infrastructure)."""
33 def add_ex_ctx(ex, context_ex):
34 """Do nothing (already handled by Python 3 infrastructure)."""
38 """If rethrow is true, rethrow ex (if any), unless the body throws.
40 (Supports Python 2 compatibility.)
43 # This is completely vestigial, and should be removed
44 def __init__(self, ex, rethrow=True):
47 self.rethrow = rethrow
50 def __exit__(self, exc_type, exc_value, traceback):
52 if not exc_type and self.ex and self.rethrow:
61 """Return the original bytes passed to main() for an argv argument."""
64 def bytes_from_uint(i):
67 def bytes_from_byte(b): # python > 2: b[3] returns ord('x'), not b'x'
70 byte_int = lambda x: x
72 def buffer(object, offset=None, size=None):
74 assert offset is not None
75 return memoryview(object)[offset:offset + size]
77 return memoryview(object)[offset:]
78 return memoryview(object)
81 return fsencode(os.getcwd())
86 except ModuleNotFoundError:
91 "Return a new list containing the current process argv bytes."
92 return bup_main.argv()
94 "Return a new list containing the current process argv strings."
95 return [x.decode(errors='surrogateescape') for x in bup_main.argv()]
98 raise Exception('get_argvb requires the bup_main module');
100 raise Exception('get_argv requires the bup_main module');
103 """Run main() and raise a SystemExit with the return value if it
104 returns, pass along any SystemExit it raises, convert
105 KeyboardInterrupts into exit(130), and print a Python 3 style
106 contextual backtrace for other exceptions in both Python 2 and
110 except KeyboardInterrupt as ex: