11#!/usr/bin/env python3
22"""
3- Step 6: Compare token transaction SDK classes (Step 3) with proto attributes (Step 4)
4- Accurate logging: actual proto attributes, predicted setters, SDK coverage,
5- and SDK-specific extra methods
3+ Step 6 (Fixed Dynamic): Compare *all* token transaction SDK classes with proto attributes.
4+ Now properly finds nested entries like token_burn_transaction.TokenBurnTransaction.
65"""
76
87from pathlib import Path
1312STEP3_FILE = Path (__file__ ).resolve ().parent / "steps_3_token_classes_info_readable.py"
1413STEP4_FILE = Path (__file__ ).resolve ().parent / "steps_4_token_classes_proto_attributes.py"
1514
15+
1616def load_module (file_path : Path , module_name : str ):
1717 if not file_path .exists ():
1818 raise FileNotFoundError (f"File not found: { file_path } " )
@@ -22,39 +22,55 @@ def load_module(file_path: Path, module_name: str):
2222 spec .loader .exec_module (module )
2323 return module
2424
25+
2526def camel_to_snake (name : str ) -> str :
2627 s1 = re .sub ('(.)([A-Z][a-z]+)' , r'\1_\2' , name )
2728 s2 = re .sub ('([a-z0-9])([A-Z])' , r'\1_\2' , s1 )
2829 return s2 .lower ()
2930
31+
3032PROTO_TO_SDK_MAP = {
3133 "token" : "token_id" ,
3234 "tokens" : "token_ids" ,
3335 "serialNumbers" : "serials" ,
3436 "account" : "account_id" ,
35- "set_account" : "set_account_id"
37+ "set_account" : "set_account_id" ,
3638}
3739
40+
3841def map_proto_to_sdk (proto_attr : str ) -> str :
3942 return PROTO_TO_SDK_MAP .get (proto_attr , camel_to_snake (proto_attr ))
4043
44+
4145def predicted_proto_setters (proto_attrs ):
42- """Return predicted setters from actual proto attributes"""
4346 return [f"set_{ map_proto_to_sdk (a )} " for a in proto_attrs ]
4447
45- SDK_MODULE_CLASS_MAP = {
46- "token_burn_transaction" : "TokenBurnTransaction" ,
47- "token_associate_transaction" : "TokenAssociateTransaction" ,
48- "token_dissociate_transaction" : "TokenDissociateTransaction" ,
49- "token_mint_transaction" : "TokenMintTransaction" ,
50- }
5148
52- TRANSACTION_PROTO_MAP = {
53- "TokenBurnTransaction" : "TokenBurnTransactionBody" ,
54- "TokenAssociateTransaction" : "TokenAssociateTransactionBody" ,
55- "TokenDissociateTransaction" : "TokenDissociateTransactionBody" ,
56- "TokenMintTransaction" : "TokenMintTransactionBody" ,
57- }
49+ def find_proto_class_name (sdk_class_name : str , proto_mappings : dict ):
50+ base = sdk_class_name .replace ("Transaction" , "TransactionBody" )
51+ if base in proto_mappings :
52+ return base
53+ for proto_name in proto_mappings .keys ():
54+ if proto_name .lower ().startswith (sdk_class_name .lower ().replace ("transaction" , "" )):
55+ return proto_name
56+ return None
57+
58+
59+ def collect_sdk_classes (step3_module ):
60+ """
61+ Recursively collect dict objects representing SDK classes
62+ from the parsed Step 3 module.
63+ """
64+ sdk_classes = {}
65+ for name , val in vars (step3_module ).items ():
66+ if isinstance (val , dict ) and "attributes" in val and "setters" in val :
67+ sdk_classes [name ] = val
68+ elif isinstance (val , type (step3_module )): # submodule-like object
69+ for subname , subval in vars (val ).items ():
70+ if isinstance (subval , dict ) and "attributes" in subval :
71+ sdk_classes [f"{ name } .{ subname } " ] = subval
72+ return sdk_classes
73+
5874
5975if __name__ == "__main__" :
6076 step3_module = load_module (STEP3_FILE , "step3_token_classes" )
@@ -65,33 +81,32 @@ def predicted_proto_setters(proto_attrs):
6581 for k in sorted (proto_mappings .keys ()):
6682 print (" -" , k )
6783
68- for sdk_module_name , sdk_class_name in SDK_MODULE_CLASS_MAP .items ():
69- sdk_module = getattr (step3_module , sdk_module_name , None )
70- sdk_class_info = getattr (sdk_module , sdk_class_name , None ) if sdk_module else {'attributes' : [], 'setters' : [], 'other_methods' : []}
71- sdk_class_info .setdefault ('other_methods' , [])
84+ sdk_classes = collect_sdk_classes (step3_module )
85+ print (f"\n 🔍 Found { len (sdk_classes )} SDK token transaction classes to compare.\n " )
7286
73- proto_class_name = TRANSACTION_PROTO_MAP .get (sdk_class_name , "" )
74- proto_info = proto_mappings .get (proto_class_name )
75- if proto_info is None :
76- print (f"\n ⚠️ Proto mapping missing for { proto_class_name } (SDK { sdk_class_name } )" )
77- proto_info = {'attributes' : [], 'setters' : []}
87+ for full_cls_name , sdk_class_info in sorted (sdk_classes .items ()):
88+ sdk_class_name = full_cls_name .split ("." )[- 1 ]
89+ proto_class_name = find_proto_class_name (sdk_class_name , proto_mappings )
7890
79- actual_proto_attrs = [map_proto_to_sdk (a ) for a in proto_info ['attributes' ]]
80- predicted_setters = predicted_proto_setters (proto_info ['attributes' ])
91+ if not proto_class_name :
92+ print (f"\n ⚠️ No proto mapping found for SDK class { sdk_class_name } " )
93+ continue
8194
82- sdk_methods = sdk_class_info ['setters' ] + sdk_class_info ['other_methods' ]
95+ proto_info = proto_mappings .get (proto_class_name , {"attributes" : [], "setters" : []})
96+ actual_proto_attrs = [map_proto_to_sdk (a ) for a in proto_info ["attributes" ]]
97+ predicted_setters = predicted_proto_setters (proto_info ["attributes" ])
8398
84- missing_attrs = [ a for a in actual_proto_attrs if a not in sdk_class_info [ ' attributes' ]]
85- missing_setters = [ s for s in predicted_setters if s not in sdk_methods ]
99+ sdk_attrs = sdk_class_info . get ( " attributes" , [])
100+ sdk_methods = sdk_class_info . get ( "setters" , []) + sdk_class_info . get ( "other_methods" , [])
86101
87- # Detect extra SDK helpers beyond predicted setters
102+ missing_attrs = [a for a in actual_proto_attrs if a not in sdk_attrs ]
103+ missing_setters = [s for s in predicted_setters if s not in sdk_methods ]
88104 extra_sdk_methods = [m for m in sdk_methods if m not in predicted_setters ]
89105
90- # Logging
91106 print (f"\n 💠 { sdk_class_name } vs { proto_class_name } " )
92- print ("✅ SDK Attributes:" , sdk_class_info [ 'attributes' ] )
93- print ("✅ SDK Setters:" , sdk_class_info [ ' setters' ] )
94- print ("✅ SDK Other Methods:" , sdk_class_info [ ' other_methods' ] )
107+ print ("✅ SDK Attributes:" , sdk_attrs )
108+ print ("✅ SDK Setters:" , sdk_class_info . get ( " setters" , []) )
109+ print ("✅ SDK Other Methods:" , sdk_class_info . get ( " other_methods" , []) )
95110 print ("📦 Actual Proto Attributes:" , actual_proto_attrs )
96111 print ("📦 Predicted Proto Setters:" , predicted_setters )
97112
0 commit comments