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
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: