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+ 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+ )
1860
1961class KaitaiStruct (object ):
2062 def __init__ (self , stream ):
@@ -26,6 +68,16 @@ def __enter__(self):
2668 def __exit__ (self , * args , ** kwargs ):
2769 self .close ()
2870
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+
2981 def close (self ):
3082 self ._io .close ()
3183
0 commit comments