diff options
Diffstat (limited to 'src/snakeoil/cli/tool.py')
-rw-r--r-- | src/snakeoil/cli/tool.py | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/src/snakeoil/cli/tool.py b/src/snakeoil/cli/tool.py index 2a142b72..d00b3cf2 100644 --- a/src/snakeoil/cli/tool.py +++ b/src/snakeoil/cli/tool.py @@ -36,14 +36,14 @@ class Tool: if not sys.stdout.isatty() and sys.stdout == sys.__stdout__: # if redirecting/piping stdout use line buffering, skip if # stdout has been set to some non-standard object - outfile = os.fdopen(sys.stdout.fileno(), 'w', 1) + outfile = os.fdopen(sys.stdout.fileno(), "w", 1) else: outfile = sys.stdout if errfile is None: errfile = sys.stderr out_fd = err_fd = None - if hasattr(outfile, 'fileno') and hasattr(errfile, 'fileno'): + if hasattr(outfile, "fileno") and hasattr(errfile, "fileno"): # annoyingly, fileno can exist but through unsupport try: out_fd, err_fd = outfile.fileno(), errfile.fileno() @@ -52,9 +52,11 @@ class Tool: if out_fd is not None and err_fd is not None: out_stat, err_stat = os.fstat(out_fd), os.fstat(err_fd) - if out_stat.st_dev == err_stat.st_dev \ - and out_stat.st_ino == err_stat.st_ino and \ - not errfile.isatty(): + if ( + out_stat.st_dev == err_stat.st_dev + and out_stat.st_ino == err_stat.st_ino + and not errfile.isatty() + ): # they're the same underlying fd. thus # point the handles at the same so we don't # get intermixed buffering issues. @@ -64,7 +66,7 @@ class Tool: self._errfile = errfile self.out = self.parser.out = formatters.PlainTextFormatter(outfile) self.err = self.parser.err = formatters.PlainTextFormatter(errfile) - self.out.verbosity = self.err.verbosity = getattr(self.parser, 'verbosity', 0) + self.out.verbosity = self.err.verbosity = getattr(self.parser, "verbosity", 0) def __call__(self, args=None): """Run the utility. @@ -98,19 +100,21 @@ class Tool: try: self.pre_parse(args, namespace) options = self.parser.parse_args(args=args, namespace=namespace) - main_func = options.pop('main_func', None) + main_func = options.pop("main_func", None) if main_func is None: raise RuntimeError("argparser missing main method") # reconfigure formatters for colored output if enabled - if getattr(options, 'color', True): + if getattr(options, "color", True): formatter_factory = partial( - formatters.get_formatter, force_color=getattr(options, 'color', False)) + formatters.get_formatter, + force_color=getattr(options, "color", False), + ) self.out = formatter_factory(self._outfile) self.err = formatter_factory(self._errfile) # reconfigure formatters with properly parsed output verbosity - self.out.verbosity = self.err.verbosity = getattr(options, 'verbosity', 0) + self.out.verbosity = self.err.verbosity = getattr(options, "verbosity", 0) if logging.root.handlers: # Remove the default handler. @@ -138,13 +142,13 @@ class Tool: exc = find_user_exception(e) if exc is not None: # allow exception attribute to override user verbosity level - if getattr(exc, '_verbosity', None) is not None: + if getattr(exc, "_verbosity", None) is not None: verbosity = exc._verbosity else: - verbosity = getattr(self.parser, 'verbosity', 0) + verbosity = getattr(self.parser, "verbosity", 0) # output verbose error message if it exists if verbosity > 0: - msg = exc.msg(verbosity).strip('\n') + msg = exc.msg(verbosity).strip("\n") if msg: self.err.write(msg) raise SystemExit @@ -166,15 +170,17 @@ class Tool: try: with suppress_warnings: - self.options, func = self.parse_args(args=self.args, namespace=self.options) + self.options, func = self.parse_args( + args=self.args, namespace=self.options + ) exitstatus = func(self.options, self.out, self.err) except SystemExit as e: # handle argparse or other third party modules using sys.exit internally exitstatus = e.code except KeyboardInterrupt: - self._errfile.write('keyboard interrupted- exiting') + self._errfile.write("keyboard interrupted- exiting") if self.parser.debug: - self._errfile.write('\n') + self._errfile.write("\n") traceback.print_exc() signal(SIGINT, SIG_DFL) os.killpg(os.getpgid(0), SIGINT) @@ -187,9 +193,9 @@ class Tool: if self.options is not None: # set terminal title on exit if exitstatus: - self.out.title(f'{self.options.prog} failed') + self.out.title(f"{self.options.prog} failed") else: - self.out.title(f'{self.options.prog} succeeded') + self.out.title(f"{self.options.prog} succeeded") return exitstatus @@ -204,18 +210,25 @@ class FormattingHandler(logging.Handler): def emit(self, record): if record.levelno >= logging.ERROR: - color = 'red' + color = "red" elif record.levelno >= logging.WARNING: - color = 'yellow' + color = "yellow" else: - color = 'cyan' - first_prefix = (self.out.fg(color), self.out.bold, record.levelname, - self.out.reset, ' ', record.name, ': ') - later_prefix = (len(record.levelname) + len(record.name)) * ' ' + ' : ' + color = "cyan" + first_prefix = ( + self.out.fg(color), + self.out.bold, + record.levelname, + self.out.reset, + " ", + record.name, + ": ", + ) + later_prefix = (len(record.levelname) + len(record.name)) * " " + " : " self.out.first_prefix.extend(first_prefix) self.out.later_prefix.append(later_prefix) try: - for line in self.format(record).split('\n'): + for line in self.format(record).split("\n"): self.out.write(line, wrap=True) except Exception: self.handleError(record) |