From 27fbde0a74fd055b5c5d99283580d8ab1a47bea1 Mon Sep 17 00:00:00 2001 From: Sven Augustin Date: Mon, 25 Oct 2021 11:30:56 +0200 Subject: [PATCH] added color for the type column; also hide classes; some reference links --- inspector.py | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/inspector.py b/inspector.py index 52253f7..120fe23 100644 --- a/inspector.py +++ b/inspector.py @@ -2,15 +2,17 @@ import inspect import re import types import weakref +from types import SimpleNamespace import ipywidgets - +import numpy as np +from matplotlib.colors import TABLEAU_COLORS HEADER = '
NameTypeSizeValue
' FOOTER = '
' SEP = '' -LINE = '{0}{1}{2}{3}' +LINE = '{0}{1}{2}{3}' IGNORE_NAMES = ("In", "Out", "exit", "quit", "get_ipython") @@ -19,9 +21,32 @@ SNIP = " ...✀... " RE_DIGITS = re.compile("([0-9]+)") +colors = SimpleNamespace(**{ + name.split(":")[1]: color for name, color in TABLEAU_COLORS.items() +}) + + +cmap = { + bool: colors.pink, # bool must be tested first, otherwise it's treated as int + int: colors.purple, + float: colors.cyan, + + str: colors.red, + + list: colors.green, + tuple: colors.olive, + set: colors.orange, + dict: colors.blue, + + np.ndarray: colors.brown +} + + class Singleton(type): + # inspired by https://stackoverflow.com/a/6798042/655404 + def __init__(cls, name, bases, namespace): super().__init__(name, bases, namespace) # creates the class cls.__signature__ = inspect.signature(cls.__init__) # restore the constructor signature (instead of that of __call__ below) @@ -38,6 +63,8 @@ class Singleton(type): class VariableInspector(object, metaclass=Singleton): + # inspired by https://github.com/jupyter-widgets/ipywidgets/blob/7.x/docs/source/examples/Variable%20Inspector.ipynb + def __init__(self, ipython=None): self._box = ipywidgets.Box() self._box.layout.overflow_y = "scroll" @@ -82,14 +109,14 @@ class VariableInspector(object, metaclass=Singleton): def format_line(k, v): - return LINE.format(k, format_type(v), format_size(v), format_value(v)) + return LINE.format(k, format_type(v), format_size(v), format_value(v), *format_colors(v)) def sorted_naturally(iterable, reverse=False): natural = lambda item: [int(c) if c.isdigit() else c.casefold() for c in RE_DIGITS.split(str(item))] return sorted(iterable, key=natural, reverse=reverse) def is_good_entry(k, v): - ignore_types = (VariableInspector, types.ModuleType) + ignore_types = (VariableInspector, types.ModuleType, type) # hide modules and classes return not k.startswith("_") and k not in IGNORE_NAMES and not isinstance(v, ignore_types) def format_type(obj): @@ -122,6 +149,18 @@ def format_value(obj): #TODO: make magic numbers configurable res = res[:50] + SNIP + res[-50:] return res +def format_colors(obj): + bkg = format_bkg_color(obj) + if bkg: + return bkg, "black" # use black font on colored background + return "", "" # use the default colors + +def format_bkg_color(obj): + for typ, col in cmap.items(): + if isinstance(obj, typ): + return col + return None + def typename(obj): return type(obj).__name__