fixes issue with wrong-chars in string items of CallingMap by its representation, additionally don't calculate values implicitly (may be unexpected for some constellations resp. too slow in DEBUG)

pull/2171/head
sebres 2018-06-29 18:33:24 +02:00
parent 2f5059ebfb
commit 79350e916e
3 changed files with 36 additions and 10 deletions

View File

@ -83,6 +83,8 @@ class CallingMap(MutableMapping, object):
The dictionary data which can be accessed to obtain items uncalled
"""
CM_REPR_ITEMS = ()
# immutable=True saves content between actions, without interim copying (save original on demand, recoverable via reset)
__slots__ = ('data', 'storage', 'immutable', '__org_data')
def __init__(self, *args, **kwargs):
@ -98,14 +100,29 @@ class CallingMap(MutableMapping, object):
pass
self.immutable = immutable
def __repr__(self):
return "%s(%r)" % (self.__class__.__name__, self._asdict())
def _asrepr(self, calculated=False):
# be sure it is suitable as string, so use str as checker:
return "%s(%r)" % (self.__class__.__name__, self._asdict(calculated, str))
def _asdict(self):
__repr__ = _asrepr
def _asdict(self, calculated=False, checker=None):
d = dict(self.data, **self.storage)
if not calculated:
return dict((n,v) for n,v in d.iteritems() \
if not callable(v) or n in self.CM_REPR_ITEMS)
for n,v in d.items():
if callable(v):
try:
return dict(self)
except:
return dict(self.data, **self.storage)
# calculate:
v = self.__getitem__(n)
# convert if needed:
if checker: checker(v)
# store calculated:
d[n] = v
except: # can't calculate - just ignore it
pass
return d
def getRawItem(self, key):
try:

View File

@ -290,6 +290,8 @@ class Actions(JailThread, Mapping):
class ActionInfo(CallingMap):
CM_REPR_ITEMS = ("fid", "raw-ticket")
AI_DICT = {
"ip": lambda self: self.__ticket.getIP(),
"family": lambda self: self['ip'].familyStr,
@ -307,7 +309,9 @@ class Actions(JailThread, Mapping):
"ipmatches": lambda self: "\n".join(self._mi4ip(True).getMatches()),
"ipjailmatches": lambda self: "\n".join(self._mi4ip().getMatches()),
"ipfailures": lambda self: self._mi4ip(True).getAttempt(),
"ipjailfailures": lambda self: self._mi4ip().getAttempt()
"ipjailfailures": lambda self: self._mi4ip().getAttempt(),
# raw ticket info:
"raw-ticket": lambda self: repr(self.__ticket)
}
__slots__ = CallingMap.__slots__ + ('__ticket', '__jail', '__mi4ip')

View File

@ -567,13 +567,18 @@ class CommandActionTest(LogCaptureTestCase):
'b': lambda self: self['a'] + 6,
'c': ''
})
s = repr(m)
s = repr(m); # only stored values (no calculated)
self.assertNotIn("'a': ", s)
self.assertNotIn("'b': ", s)
self.assertIn("'c': ''", s)
s = m._asrepr(True) # all values (including calculated)
self.assertIn("'a': 5", s)
self.assertIn("'b': 11", s)
self.assertIn("'c': ''", s)
m['c'] = lambda self: self['xxx'] + 7; # unresolvable
s = repr(m)
s = m._asrepr(True)
self.assertIn("'a': 5", s)
self.assertIn("'b': 11", s)
self.assertIn("'c': ", s) # presents as callable