from pprint import pprint
from sidekick import fn
from .utils.text import safe_repr, first_line
#
# Printing
#
[docs]@fn
def info(obj, log=print, full=False):
"""
Display detailed information about object.
"""
log("=" * 60)
log("Object:", obj)
# Print object state
try:
dic = obj.__dict__
except (AttributeError, TypeError):
pass
else:
log("\nDict")
if full:
pprint(dic)
else:
_log_values(log, dic)
# Print information about methods
methods = []
for attr, method in public_methods(obj):
doc = method.__doc__ or ""
if doc:
methods.append(f"* {attr}: {first_line(doc)}")
else:
methods.append(f"* {attr}")
if methods:
log("\nMethods:")
print("\n".join(methods))
log("-" * 60)
def _log_values(log, values):
# First print public values
for k, v in values.items():
if not k.startswith("_"):
log(f"* {k}:", safe_repr(v, max_length=50))
# Then the private ones (only types)
for k, v in values.items():
if k.startswith("_"):
log(f"* {k} ({v.__class__.__name__})")
#
# Tracing
#
[docs]def set_trace():
raise NotImplementedError
[docs]def embed():
raise NotImplementedError
#
# Integration
#
def namespace():
"""
Return a namespace of useful debug functions.
"""
import boogie.debug as dbg
return {
"info": info,
"log": print,
"pprint": pprint,
"set_trace": set_trace,
"embed": embed,
"dbg": dbg,
}
[docs]def enable_debugging(auto=False):
"""
Register debugging function to builtins.
"""
import builtins
# Checks if debugging should be enabled.
if auto:
pass
# Configure environment in "debug" mode.
for k, v in namespace().items():
if not hasattr(builtins, k):
setattr(builtins, k, v)
#
# Utility
#
def public_dir(obj):
return (attr for attr in dir(obj) if not attr.startswith("_"))
def public_vars(obj):
for attr in public_dir(obj):
try:
yield attr, getattr(obj, attr)
except AttributeError:
pass
def public_methods(obj):
for attr, method in public_vars(obj):
if callable(method):
yield attr, method