mirror of
https://github.com/cool-RR/PySnooper.git
synced 2026-07-20 01:44:10 +00:00
Add automatic exploded_variables
This commit is contained in:
parent
fb62a57a52
commit
97dc802ee6
3 changed files with 37 additions and 8 deletions
|
|
@ -39,7 +39,7 @@ def get_write_and_truncate_functions(output):
|
|||
return (write, truncate)
|
||||
|
||||
|
||||
def snoop(output=None, variables=(), depth=1, prefix='', overwrite=False):
|
||||
def snoop(output=None, variables=(), exploded_variables=(), depth=1, prefix='', overwrite=False):
|
||||
'''
|
||||
Snoop on the function, writing everything it's doing to stderr.
|
||||
|
||||
|
|
@ -75,7 +75,8 @@ def snoop(output=None, variables=(), depth=1, prefix='', overwrite=False):
|
|||
target_code_object = function.__code__
|
||||
tracer = Tracer(target_code_object=target_code_object, write=write,
|
||||
truncate=truncate, variables=variables, depth=depth,
|
||||
prefix=prefix, overwrite=overwrite)
|
||||
prefix=prefix, overwrite=overwrite,
|
||||
exploded_variables=exploded_variables)
|
||||
|
||||
def inner(function_, *args, **kwargs):
|
||||
with tracer:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import collections
|
|||
import datetime as datetime_module
|
||||
import itertools
|
||||
|
||||
from .variables import Variable
|
||||
from .variables import CommonVariable, Exploded, BaseVariable
|
||||
from .third_party import six
|
||||
from .utils import get_shortish_repr, ensure_tuple
|
||||
|
||||
|
|
@ -99,13 +99,16 @@ def get_source_from_frame(frame):
|
|||
|
||||
class Tracer:
|
||||
def __init__(self, target_code_object, write, truncate, variables=(),
|
||||
depth=1, prefix='', overwrite=False):
|
||||
exploded_variables=(), depth=1, prefix='', overwrite=False):
|
||||
self.target_code_object = target_code_object
|
||||
self._write = write
|
||||
self.truncate = truncate
|
||||
self.variables = [
|
||||
v if isinstance(v, Variable) else Variable(v)
|
||||
v if isinstance(v, BaseVariable) else CommonVariable(v)
|
||||
for v in ensure_tuple(variables)
|
||||
] + [
|
||||
v if isinstance(v, BaseVariable) else Exploded(v)
|
||||
for v in ensure_tuple(exploded_variables)
|
||||
]
|
||||
self.frame_to_old_local_reprs = collections.defaultdict(lambda: {})
|
||||
self.frame_to_local_reprs = collections.defaultdict(lambda: {})
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from copy import deepcopy
|
|||
from .utils import get_shortish_repr, ensure_tuple
|
||||
|
||||
|
||||
class Variable(object):
|
||||
class BaseVariable(object):
|
||||
def __init__(self, source, exclude=()):
|
||||
self.source = source
|
||||
self.exclude = ensure_tuple(exclude)
|
||||
|
|
@ -15,6 +15,14 @@ class Variable(object):
|
|||
main_value = eval(self.code, frame.f_globals, frame.f_locals)
|
||||
except Exception:
|
||||
return ()
|
||||
return self._items(main_value)
|
||||
|
||||
def _items(self, key):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class CommonVariable(BaseVariable):
|
||||
def _items(self, main_value):
|
||||
result = [(self.source, get_shortish_repr(main_value))]
|
||||
for key in self._safe_keys(main_value):
|
||||
if key in self.exclude:
|
||||
|
|
@ -46,7 +54,7 @@ class Variable(object):
|
|||
raise NotImplementedError()
|
||||
|
||||
|
||||
class Attrs(Variable):
|
||||
class Attrs(CommonVariable):
|
||||
def _keys(self, main_value):
|
||||
return itertools.chain(
|
||||
getattr(main_value, '__dict__', ()),
|
||||
|
|
@ -60,7 +68,7 @@ class Attrs(Variable):
|
|||
return getattr(main_value, key)
|
||||
|
||||
|
||||
class Keys(Variable):
|
||||
class Keys(CommonVariable):
|
||||
def _keys(self, main_value):
|
||||
return main_value.keys()
|
||||
|
||||
|
|
@ -82,3 +90,20 @@ class Indices(Keys):
|
|||
result = deepcopy(self)
|
||||
result._slice = item
|
||||
return result
|
||||
|
||||
|
||||
class Exploded(BaseVariable):
|
||||
def _items(self, main_value):
|
||||
typ = main_value.__class__
|
||||
|
||||
def has_method(name):
|
||||
return callable(getattr(typ, name, None))
|
||||
|
||||
cls = Attrs
|
||||
if has_method('__getitem__'):
|
||||
if has_method('keys'):
|
||||
cls = Keys
|
||||
elif has_method('__len__'):
|
||||
cls = Indices
|
||||
|
||||
return cls(self.source, self.exclude)._items(main_value)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue