Source code for pymor.tools.formatrepr

# 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


[docs]def register_format_handler(cls, handler): _format_handlers[cls] = handler
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]@defaults('max_width', 'verbosity') def format_repr(obj, max_width=120, verbosity=1): return _recurse(obj, max_width, verbosity)
[docs]def indent_value(val, indent): if '\n' in val: return textwrap.indent(val, ' ' * indent)[indent:] else: return val