1
1
import itertools
2
- import sys
2
+ import sys , threading
3
3
import struct
4
4
from struct import unpack
5
5
from io import BytesIO # noqa
15
15
#
16
16
__version__ = '0.8'
17
17
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
+ )
18
68
19
69
class KaitaiStruct (object ):
20
70
def __init__ (self , stream ):
@@ -26,6 +76,16 @@ def __enter__(self):
26
76
def __exit__ (self , * args , ** kwargs ):
27
77
self .close ()
28
78
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
+
29
89
def close (self ):
30
90
self ._io .close ()
31
91
0 commit comments