Added get_exception() and try_and_print()
* try_and_print needs the format_..() functions finished before it can be used * Raised minimum Python version to 3.7 * Probably could go with 3.6 but meh
This commit is contained in:
parent
36e2ad8522
commit
ff4e371b32
2 changed files with 105 additions and 10 deletions
|
|
@ -16,18 +16,12 @@ from wk import sw
|
||||||
|
|
||||||
|
|
||||||
# Check env
|
# Check env
|
||||||
if sys.version_info < (3, 5):
|
if sys.version_info < (3, 7):
|
||||||
# Unsupported
|
# Unsupported
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
'This package is unsupported on Python {major}.{minor}'.format(
|
'This package is unsupported on Python {major}.{minor}'.format(
|
||||||
**sys.version_info,
|
**sys.version_info,
|
||||||
))
|
))
|
||||||
if sys.version_info < (3, 7):
|
|
||||||
# Untested
|
|
||||||
raise UserWarning(
|
|
||||||
'Python {major}.{minor} is untested for this package'.format(
|
|
||||||
**sys.version_info,
|
|
||||||
))
|
|
||||||
|
|
||||||
# Init
|
# Init
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
'''WizardKit: Standard Functions'''
|
'''WizardKit: Standard Functions'''
|
||||||
# vim: sts=2 sw=2 ts=2
|
# vim: sts=2 sw=2 ts=2
|
||||||
|
#TODO Replace .format()s with f-strings
|
||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -12,15 +13,15 @@ import sys
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from wk.cfg.main import CRASH_SERVER, ENABLED_UPLOAD_DATA, SUPPORT_MESSAGE
|
|
||||||
from wk.cfg.main import INDENT, WIDTH
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from termios import tcflush, TCIOFLUSH
|
from termios import tcflush, TCIOFLUSH
|
||||||
except ImportError:
|
except ImportError:
|
||||||
if os.name == 'posix':
|
if os.name == 'posix':
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
from wk.cfg.main import CRASH_SERVER, ENABLED_UPLOAD_DATA, SUPPORT_MESSAGE
|
||||||
|
from wk.cfg.main import INDENT, WIDTH
|
||||||
|
|
||||||
|
|
||||||
# STATIC VARIABLES
|
# STATIC VARIABLES
|
||||||
COLORS = {
|
COLORS = {
|
||||||
|
|
@ -157,6 +158,27 @@ def clear_screen():
|
||||||
os.system('clear')
|
os.system('clear')
|
||||||
|
|
||||||
|
|
||||||
|
def format_exception_message(_exception, indent=INDENT, width=WIDTH):
|
||||||
|
"""TODO"""
|
||||||
|
return 'TODO'
|
||||||
|
|
||||||
|
|
||||||
|
def format_function_output(output, indent=INDENT, width=WIDTH):
|
||||||
|
"""TODO"""
|
||||||
|
return 'TODO'
|
||||||
|
|
||||||
|
|
||||||
|
def get_exception(name):
|
||||||
|
"""Get exception by name, returns exception object."""
|
||||||
|
LOG.debug('Getting exception: %s', name)
|
||||||
|
try:
|
||||||
|
obj = getattr(sys.modules[__name__], name)
|
||||||
|
except AttributeError:
|
||||||
|
# Try builtin classes
|
||||||
|
obj = getattr(sys.modules['builtins'], name)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
def get_log_filepath():
|
def get_log_filepath():
|
||||||
"""Get the log filepath from the root logger, returns pathlib.Path obj.
|
"""Get the log filepath from the root logger, returns pathlib.Path obj.
|
||||||
|
|
||||||
|
|
@ -385,6 +407,85 @@ def strip_colors(string):
|
||||||
return string
|
return string
|
||||||
|
|
||||||
|
|
||||||
|
def try_and_print(
|
||||||
|
message, function, *args,
|
||||||
|
msg_good='CS', msg_bad='NS', indent=INDENT, width=WIDTH,
|
||||||
|
w_exceptions=None, e_exceptions=None,
|
||||||
|
catch_all=True, print_return=False, verbose=False,
|
||||||
|
**kwargs):
|
||||||
|
# pylint: disable=catching-non-exception,unused-argument,too-many-locals
|
||||||
|
"""Run a function and print the results, returns results as dict.
|
||||||
|
|
||||||
|
If catch_all is True then (nearly) all exceptions will be caught.
|
||||||
|
Otherwise if an exception occurs that wasn't specified it will be
|
||||||
|
re-raised.
|
||||||
|
|
||||||
|
If print_return is True then the output from the function will be used
|
||||||
|
instead of msg_good, msg_bad, or exception text. The output should be
|
||||||
|
a list or a subprocess.CompletedProcess object.
|
||||||
|
|
||||||
|
If verbose is True then exception names or messages will be used for
|
||||||
|
the result message. Otherwise it will simply be set to result_bad.
|
||||||
|
|
||||||
|
If specified w_exceptions and e_exceptions should be lists of
|
||||||
|
exception class names. Details from the excceptions will be used to
|
||||||
|
format more clear result messages.
|
||||||
|
"""
|
||||||
|
LOG.debug('function: %s.%s', function.__module__, function.__name__)
|
||||||
|
LOG.debug('args: %s', args)
|
||||||
|
LOG.debug('kwargs: %s', kwargs)
|
||||||
|
LOG.debug('w_exceptions: %s', w_exceptions)
|
||||||
|
LOG.debug('e_exceptions: %s', e_exceptions)
|
||||||
|
LOG.debug(
|
||||||
|
'catch_all: %s, print_return: %s, verbose: %s',
|
||||||
|
catch_all,
|
||||||
|
print_return,
|
||||||
|
verbose,
|
||||||
|
)
|
||||||
|
f_exception = None
|
||||||
|
output = None
|
||||||
|
result_msg = 'UNKNOWN'
|
||||||
|
w_exceptions = tuple(get_exception(e) for e in w_exceptions)
|
||||||
|
e_exceptions = tuple(get_exception(e) for e in e_exceptions)
|
||||||
|
|
||||||
|
# Run function and catch exceptions
|
||||||
|
print(f'{" "*indent}{message:<{width}}', end='', flush=True)
|
||||||
|
LOG.info('Running function: %s.%s', function.__module__, function.__name__)
|
||||||
|
try:
|
||||||
|
output = function(*args, **kwargs)
|
||||||
|
if print_return:
|
||||||
|
result_msg = format_function_output(output, indent, width)
|
||||||
|
else:
|
||||||
|
result_msg = msg_good
|
||||||
|
print_success(result_msg)
|
||||||
|
except w_exceptions as _exception:
|
||||||
|
result_msg = format_exception_message(_exception, indent, width)
|
||||||
|
print_warning(result_msg)
|
||||||
|
f_exception = _exception
|
||||||
|
except e_exceptions as _exception:
|
||||||
|
result_msg = format_exception_message(_exception, indent, width)
|
||||||
|
print_error(result_msg)
|
||||||
|
f_exception = _exception
|
||||||
|
except Exception as _exception: # pylint: disable=broad-except
|
||||||
|
if verbose:
|
||||||
|
result_msg = format_exception_message(_exception, indent, width)
|
||||||
|
else:
|
||||||
|
result_msg = msg_bad
|
||||||
|
print_error(result_msg)
|
||||||
|
f_exception = _exception
|
||||||
|
|
||||||
|
# Re-raise error if necessary
|
||||||
|
if f_exception and not catch_all:
|
||||||
|
raise #pylint: disable=misplaced-bare-raise
|
||||||
|
|
||||||
|
# Done
|
||||||
|
return {
|
||||||
|
'Failed': bool(f_exception),
|
||||||
|
'Exception': f_exception,
|
||||||
|
'Output': output,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def upload_debug_report(report, compress=True, reason='DEBUG'):
|
def upload_debug_report(report, compress=True, reason='DEBUG'):
|
||||||
"""Upload debug report to CRASH_SERVER as specified in wk.cfg.main."""
|
"""Upload debug report to CRASH_SERVER as specified in wk.cfg.main."""
|
||||||
LOG.info('Uploading debug report to %s', CRASH_SERVER.get('Name', '?'))
|
LOG.info('Uploading debug report to %s', CRASH_SERVER.get('Name', '?'))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue