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 functools import wraps
20
+ class RecursionSafe :
21
+ __slots__ = ("visiting" )
22
+ class Lock :
23
+ __slots__ = ("obj" , "safe" )
24
+ def __init__ (self , safe , obj ):
25
+ self .safe = safe
26
+ self .obj = obj
27
+ def __enter__ (self ):
28
+ i = id (self .obj )
29
+ if i not in self .safe .visiting :
30
+ self .safe .visiting .add (i )
31
+ return self .obj
32
+ else :
33
+ return ...
34
+ def __exit__ (self , * args , ** kwargs ):
35
+ i = id (self .obj )
36
+ if i in self .safe .visiting :
37
+ self .safe .visiting .remove (i )
38
+ def __init__ (self ):
39
+ self .visiting = set ()
40
+ def __call__ (self , obj ):
41
+ return self .__class__ .Lock (self , obj )
42
+ def wrap (self , f ):
43
+ @wraps (f )
44
+ def wrapped (firstArg , * args , ** kwargs ):
45
+ with self (firstArg ) as firstArg :
46
+ return f (firstArg , * args , ** kwargs )
47
+ return wrapped
48
+
49
+ thread_local = threading .local ()
50
+ thread_local .rec_safe = RecursionSafe ()
51
+
52
+ @thread_local .rec_safe .wrap
53
+ def repr_generator_for_all_props (self ):
54
+ """Generator to use in own __repr__ functions."""
55
+ return (
56
+ "" .join (( str (k ), "=" , repr (getattr (self , k )) ))
57
+ for k in dir (self )
58
+ if k [0 ] != "_" and not hasattr (KaitaiStruct , k ) and not isinstance (getattr (self , k ), type )
59
+ )
18
60
19
61
class KaitaiStruct (object ):
20
62
def __init__ (self , stream ):
@@ -26,6 +68,16 @@ def __enter__(self):
26
68
def __exit__ (self , * args , ** kwargs ):
27
69
self .close ()
28
70
71
+ def __repr__ (self ):
72
+ return "" .join (
73
+ (
74
+ self .__class__ .__name__ ,
75
+ "(" ,
76
+ ", " .join ( repr_generator_for_all_props (self ) ),
77
+ ")"
78
+ )
79
+ )
80
+
29
81
def close (self ):
30
82
self ._io .close ()
31
83
0 commit comments