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
17 """Return hex string (not bytes as with hexlify) representation of b."""
21 raise ex.with_traceback(sys.exc_info()[2])
23 # These three functions (add_ex_tb, add_ex_ctx, and pending_raise) are
24 # vestigial, and code that uses them can probably be rewritten more
25 # simply now that we require Python versions that automatically
26 # populate the tracebacks and automatically chain pending exceptions.
29 """Do nothing (already handled by Python 3 infrastructure)."""
32 def add_ex_ctx(ex, context_ex):
33 """Do nothing (already handled by Python 3 infrastructure)."""
37 """If rethrow is true, rethrow ex (if any), unless the body throws.
39 (Supports Python 2 compatibility.)
42 # This is completely vestigial, and should be removed
43 def __init__(self, ex, rethrow=True):
46 self.rethrow = rethrow
49 def __exit__(self, exc_type, exc_value, traceback):
51 if not exc_type and self.ex and self.rethrow:
60 """Return the original bytes passed to main() for an argv argument."""
63 def bytes_from_uint(i):
66 def bytes_from_byte(b): # python > 2: b[3] returns ord('x'), not b'x'
69 byte_int = lambda x: x
71 def buffer(object, offset=None, size=None):
73 assert offset is not None
74 return memoryview(object)[offset:offset + size]
76 return memoryview(object)[offset:]
77 return memoryview(object)
80 return fsencode(os.getcwd())
85 except ModuleNotFoundError:
90 "Return a new list containing the current process argv bytes."
91 return bup_main.argv()
93 "Return a new list containing the current process argv strings."
94 return [x.decode(errors='surrogateescape') for x in bup_main.argv()]
97 raise Exception('get_argvb requires the bup_main module');
99 raise Exception('get_argv requires the bup_main module');
102 """Run main() and raise a SystemExit with the return value if it
103 returns, pass along any SystemExit it raises, convert
104 KeyboardInterrupts into exit(130), and print a Python 3 style
105 contextual backtrace for other exceptions in both Python 2 and
109 except KeyboardInterrupt as ex: