# This file is part of the pyMOR project (http://www.pymor.org).
# Copyright 2013-2020 pyMOR developers and contributors. All rights reserved.
# License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
import inspect
import textwrap
import numpy as np
from pymor.core.defaults import defaults
def _format_generic(obj, max_width, verbosity, override={}):
init_sig = inspect.signature(obj.__init__)
keys, vals = [], []
for arg, description in init_sig.parameters.items():
if verbosity < 2 and description.default == description.empty:
key = ''
else:
key = f'{arg}='
if arg == 'self':
continue
if arg in override:
val = override[arg]
if val is None:
continue
vals.append(override[arg])
else:
val = getattr(obj, arg, '??')
try:
if verbosity < 3 and val == description.default:
continue
except (ValueError, TypeError): # comparison of numpy arrays, NGSolve FESpaces
pass
vals.append(_recurse(val, max_width - len(key) - 4, verbosity))
keys.append(key)
if verbosity > 0 and (sum(len(k) + len(v) + 2 for k, v in zip(keys, vals)) + len(type(obj).__name__) > max_width
or any('\n' in v for v in vals)):
args = [f' {k}{indent_value(v, len(k) + 4)}' for k, v in zip(keys, vals)]
args = ",\n".join(args)
return f'''{type(obj).__name__}(
{args})'''
else:
args = [f'{k}{v}' for k, v in zip(keys, vals)]
return f'{type(obj).__name__}({", ".join(args)})'
def _format_list_tuple(val, max_width, verbosity):
brackets = '()' if type(val) is tuple else '[]'
reprs = [repr(v) for v in val]
if verbosity > 0 and (any('\n' in r for r in reprs) or sum(len(r) + 2 for r in reprs) + 2 > max_width):
reprs = ',\n '.join(indent_value(r, 1) for r in reprs)
return brackets[0] + reprs + brackets[1]
else:
return brackets[0] + ', '.join(reprs) + brackets[1]
def _format_dict(val, max_width, verbosity):
if not val:
return '{}'
keys, vals = zip(*val.items())
reprs = [repr(v) for v in vals]
if verbosity > 0 and (any('\n' in r for r in reprs)
or sum(len(k) + len(r) + 4 for k, r in zip(keys, reprs)) + 2 > max_width):
reprs = ',\n '.join(indent_value(f'{k}: {r}', 1) for k, r in zip(keys, reprs))
return '{' + reprs + '}'
else:
return '{' + ', '.join(f'{k}: {r}' for k, r in zip(keys, reprs)) + '}'
def _format_array(val, max_width, verbosity):
r = repr(val)
if len(r) <= max_width * 3 and '\n' in r:
r_one_line = ' '.join(rr.strip() for rr in r.split('\n'))
if len(r_one_line) <= max_width:
return r_one_line
else:
return r
else:
return r
_format_handlers = {}
register_format_handler(list, _format_list_tuple)
register_format_handler(tuple, _format_list_tuple)
register_format_handler(dict, _format_dict)
register_format_handler(np.ndarray, _format_array)
def _recurse(obj, max_width, verbosity):
if hasattr(obj, '_format_repr'):
return obj._format_repr(max_width, verbosity)
handler = None
for cls in type(obj).__mro__:
try:
handler = _format_handlers[cls]
except KeyError:
pass
if handler:
return handler(obj, max_width, verbosity)
else:
return repr(obj)
[docs]def indent_value(val, indent):
if '\n' in val:
return textwrap.indent(val, ' ' * indent)[indent:]
else:
return val