dfdf
This commit is contained in:
@@ -5,6 +5,8 @@ import inspect
|
||||
import threading
|
||||
from pathlib import Path
|
||||
|
||||
from rich_display import console_for
|
||||
|
||||
_DEBUG_ENABLED = False
|
||||
_thread_local = threading.local()
|
||||
|
||||
@@ -56,6 +58,80 @@ def debug(*args, **kwargs) -> None:
|
||||
# Use the same logic as log()
|
||||
log(*args, **kwargs)
|
||||
|
||||
|
||||
def debug_inspect(
|
||||
obj,
|
||||
*,
|
||||
title: str | None = None,
|
||||
file=None,
|
||||
methods: bool = False,
|
||||
docs: bool = False,
|
||||
private: bool = False,
|
||||
dunder: bool = False,
|
||||
sort: bool = True,
|
||||
all: bool = False,
|
||||
value: bool = True,
|
||||
) -> None:
|
||||
"""Rich-inspect an object when debug logging is enabled.
|
||||
|
||||
Uses the same stream / quiet-mode behavior as `debug()` and prepends a
|
||||
`[file.function]` prefix when debug is enabled.
|
||||
"""
|
||||
if not _DEBUG_ENABLED:
|
||||
return
|
||||
|
||||
# Mirror debug() quiet-mode guard.
|
||||
try:
|
||||
stderr_name = getattr(sys.stderr, "name", "")
|
||||
if "nul" in str(stderr_name).lower() or "/dev/null" in str(stderr_name):
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Resolve destination stream.
|
||||
stream = get_thread_stream()
|
||||
if stream is not None:
|
||||
file = stream
|
||||
elif file is None:
|
||||
file = sys.stderr
|
||||
|
||||
# Compute caller prefix (same as log()).
|
||||
prefix = None
|
||||
frame = inspect.currentframe()
|
||||
if frame is not None and frame.f_back is not None:
|
||||
caller_frame = frame.f_back
|
||||
try:
|
||||
file_name = Path(caller_frame.f_code.co_filename).stem
|
||||
func_name = caller_frame.f_code.co_name
|
||||
prefix = f"[{file_name}.{func_name}]"
|
||||
finally:
|
||||
del caller_frame
|
||||
if frame is not None:
|
||||
del frame
|
||||
|
||||
# Render.
|
||||
from rich import inspect as rich_inspect
|
||||
|
||||
console = console_for(file)
|
||||
# If the caller provides a title, treat it as authoritative.
|
||||
# Only fall back to the automatic [file.func] prefix when no title is supplied.
|
||||
effective_title = title
|
||||
if not effective_title and prefix:
|
||||
effective_title = prefix
|
||||
|
||||
rich_inspect(
|
||||
obj,
|
||||
console=console,
|
||||
title=effective_title,
|
||||
methods=methods,
|
||||
docs=docs,
|
||||
private=private,
|
||||
dunder=dunder,
|
||||
sort=sort,
|
||||
all=all,
|
||||
value=value,
|
||||
)
|
||||
|
||||
def log(*args, **kwargs) -> None:
|
||||
"""Print with automatic file.function prefix.
|
||||
|
||||
@@ -71,12 +147,18 @@ def log(*args, **kwargs) -> None:
|
||||
# Get the calling frame
|
||||
frame = inspect.currentframe()
|
||||
if frame is None:
|
||||
print(*args, **kwargs)
|
||||
file = kwargs.pop("file", sys.stdout)
|
||||
sep = kwargs.pop("sep", " ")
|
||||
end = kwargs.pop("end", "\n")
|
||||
console_for(file).print(*args, sep=sep, end=end)
|
||||
return
|
||||
|
||||
caller_frame = frame.f_back
|
||||
if caller_frame is None:
|
||||
print(*args, **kwargs)
|
||||
file = kwargs.pop("file", sys.stdout)
|
||||
sep = kwargs.pop("sep", " ")
|
||||
end = kwargs.pop("end", "\n")
|
||||
console_for(file).print(*args, sep=sep, end=end)
|
||||
return
|
||||
|
||||
try:
|
||||
@@ -93,12 +175,15 @@ def log(*args, **kwargs) -> None:
|
||||
# Set default to stdout if not specified
|
||||
elif 'file' not in kwargs:
|
||||
kwargs['file'] = sys.stdout
|
||||
|
||||
|
||||
file = kwargs.pop("file", sys.stdout)
|
||||
sep = kwargs.pop("sep", " ")
|
||||
end = kwargs.pop("end", "\n")
|
||||
if add_prefix:
|
||||
prefix = f"[{file_name}.{func_name}]"
|
||||
print(prefix, *args, **kwargs)
|
||||
console_for(file).print(prefix, *args, sep=sep, end=end)
|
||||
else:
|
||||
print(*args, **kwargs)
|
||||
console_for(file).print(*args, sep=sep, end=end)
|
||||
finally:
|
||||
del frame
|
||||
del caller_frame
|
||||
|
||||
Reference in New Issue
Block a user