Skip to content

Commit 8c117dd

Browse files
committed
Added __repr__ and a helper function
1 parent 0b66357 commit 8c117dd

File tree

1 file changed

+61
-1
lines changed

1 file changed

+61
-1
lines changed

kaitaistruct.py

+61-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import itertools
2-
import sys
2+
import sys, threading
33
import struct
44
from struct import unpack
55
from io import BytesIO # noqa
@@ -15,6 +15,56 @@
1515
#
1616
__version__ = '0.8'
1717

18+
# https://github.com/KOLANICH/RecursionSafe.py inlined
19+
from collections import defaultdict
20+
from functools import wraps
21+
class RecursionSafe:
22+
__slots__=("visiting")
23+
class Lock:
24+
__slots__=("obj", "safe", "locked")
25+
def __init__(self, safe, obj):
26+
self.safe=safe
27+
self.obj=obj
28+
self.locked=False
29+
def __enter__(self):
30+
i=id(self.obj)
31+
if i not in self.safe.visiting:
32+
#print("locking ", i)
33+
self.locked=True
34+
self.safe.visiting[i]+=1
35+
return self.obj
36+
else:
37+
return ...
38+
def __exit__(self, *args, **kwargs):
39+
if self.locked:
40+
i=id(self.obj)
41+
#print("unlocking ", i)
42+
self.safe.visiting[i]-=1
43+
if not self.safe.visiting[i]:
44+
del(self.safe.visiting[i])
45+
self.locked=False
46+
def __init__(self):
47+
self.visiting=defaultdict(int)
48+
def __call__(self, obj):
49+
return self.__class__.Lock(self, obj)
50+
def wrap(self, f):
51+
@wraps(f)
52+
def wrapped(firstArg, *args, **kwargs):
53+
with self(firstArg):
54+
return f(firstArg, *args, **kwargs)
55+
return wrapped
56+
57+
thread_local=threading.local()
58+
thread_local.rec_safe=RecursionSafe()
59+
60+
@thread_local.rec_safe.wrap
61+
def repr_generator_for_all_props(self):
62+
"""Generator to use in own __repr__ functions."""
63+
return (
64+
"".join(( str(k), "=", repr(getattr(self, k)) ))
65+
for k in dir(self)
66+
if k[0] != "_" and not hasattr(KaitaiStruct, k) and not isinstance(getattr(self, k), type)
67+
)
1868

1969
class KaitaiStruct(object):
2070
def __init__(self, stream):
@@ -26,6 +76,16 @@ def __enter__(self):
2676
def __exit__(self, *args, **kwargs):
2777
self.close()
2878

79+
def __repr__(self):
80+
return "".join(
81+
(
82+
self.__class__.__name__,
83+
"(",
84+
", ".join( repr_generator_for_all_props(self) ),
85+
")"
86+
)
87+
)
88+
2989
def close(self):
3090
self._io.close()
3191

0 commit comments

Comments
 (0)