11import itertools
2- import sys
2+ import sys , threading
33import struct
44from struct import unpack
55from io import BytesIO # noqa
1515#
1616__version__ = '0.8'
1717
18+ # https://github.com/KOLANICH/RecursionSafe.py inlined
19+ from functools import wraps
20+ class RecursionSafe :
21+ __slots__ = ("visiting" )
22+
23+ class Lock :
24+ __slots__ = ("obj" , "safe" )
25+ def __init__ (self , safe , obj ):
26+ self .safe = safe
27+ self .obj = obj
28+
29+ def __enter__ (self ):
30+ i = id (self .obj )
31+ if i not in self .safe .visiting :
32+ self .safe .visiting .add (i )
33+ return self .obj
34+ else :
35+ return ...
36+
37+ def __exit__ (self , * args , ** kwargs ):
38+ i = id (self .obj )
39+ if i in self .safe .visiting :
40+ self .safe .visiting .remove (i )
41+
42+ def __init__ (self ):
43+ self .visiting = set ()
44+
45+ def __call__ (self , obj ):
46+ return self .__class__ .Lock (self , obj )
47+
48+ def wrap (self , f ):
49+ @wraps (f )
50+ def wrapped (firstArg , * args , ** kwargs ):
51+ with self (firstArg ) as firstArg :
52+ return f (firstArg , * args , ** kwargs )
53+ return wrapped
54+
55+
56+ thread_local = threading .local ()
57+ thread_local .rec_safe = RecursionSafe ()
58+
59+ @thread_local .rec_safe .wrap
60+ def repr_generator_for_all_props (self ):
61+ """Generator to use in own __repr__ functions."""
62+ return (
63+ "" .join (( str (k ), "=" , repr (getattr (self , k )) ))
64+ for k in dir (self )
65+ if k [0 ] != "_" and not hasattr (KaitaiStruct , k ) and not isinstance (getattr (self , k ), type )
66+ )
1867
1968class KaitaiStruct (object ):
2069 def __init__ (self , stream ):
@@ -26,6 +75,16 @@ def __enter__(self):
2675 def __exit__ (self , * args , ** kwargs ):
2776 self .close ()
2877
78+ def __repr__ (self ):
79+ return "" .join (
80+ (
81+ self .__class__ .__name__ ,
82+ "(" ,
83+ ", " .join ( repr_generator_for_all_props (self ) ),
84+ ")"
85+ )
86+ )
87+
2988 def close (self ):
3089 self ._io .close ()
3190
0 commit comments