11#!/usr/bin/env python3
22"""
33Step 6: Compare token transaction SDK classes (Step 3) with proto attributes (Step 4)
4- for multiple token transactions
5- + regex + mapping to check if proto really missing
6- + logging missing proto mappings
4+ Accurate logging: actual proto attributes, predicted setters, SDK coverage,
5+ and SDK-specific extra methods
76"""
87
98from pathlib import Path
109import importlib .util
1110import sys
1211import re
1312
14- # Step 3 and Step 4 generated files
1513STEP3_FILE = Path (__file__ ).resolve ().parent / "steps_3_token_classes_info_readable.py"
1614STEP4_FILE = Path (__file__ ).resolve ().parent / "steps_4_token_classes_proto_attributes.py"
1715
1816def load_module (file_path : Path , module_name : str ):
19- """Dynamically load a Python file as a module."""
2017 if not file_path .exists ():
2118 raise FileNotFoundError (f"File not found: { file_path } " )
2219 spec = importlib .util .spec_from_file_location (module_name , file_path )
@@ -26,12 +23,10 @@ def load_module(file_path: Path, module_name: str):
2623 return module
2724
2825def camel_to_snake (name : str ) -> str :
29- """Convert camelCase or PascalCase to snake_case."""
3026 s1 = re .sub ('(.)([A-Z][a-z]+)' , r'\1_\2' , name )
3127 s2 = re .sub ('([a-z0-9])([A-Z])' , r'\1_\2' , s1 )
3228 return s2 .lower ()
3329
34- # Special proto -> SDK mappings
3530PROTO_TO_SDK_MAP = {
3631 "token" : "token_id" ,
3732 "tokens" : "token_ids" ,
@@ -41,27 +36,19 @@ def camel_to_snake(name: str) -> str:
4136}
4237
4338def map_proto_to_sdk (proto_attr : str ) -> str :
44- """Apply special mapping rules + snake_case conversion."""
45- if proto_attr in PROTO_TO_SDK_MAP :
46- return PROTO_TO_SDK_MAP [proto_attr ]
47- return camel_to_snake (proto_attr )
48-
49- def map_proto_setter_to_sdk (proto_setter : str ) -> str :
50- """Convert proto setter to SDK setter."""
51- if proto_setter .startswith ("set_" ):
52- core = proto_setter [4 :] # remove 'set_'
53- return f"set_{ map_proto_to_sdk (core )} "
54- return proto_setter
55-
56- # Mapping of Step 3 module names -> SDK class names
39+ return PROTO_TO_SDK_MAP .get (proto_attr , camel_to_snake (proto_attr ))
40+
41+ def predicted_proto_setters (proto_attrs ):
42+ """Return predicted setters from actual proto attributes"""
43+ return [f"set_{ map_proto_to_sdk (a )} " for a in proto_attrs ]
44+
5745SDK_MODULE_CLASS_MAP = {
5846 "token_burn_transaction" : "TokenBurnTransaction" ,
5947 "token_associate_transaction" : "TokenAssociateTransaction" ,
6048 "token_dissociate_transaction" : "TokenDissociateTransaction" ,
6149 "token_mint_transaction" : "TokenMintTransaction" ,
6250}
6351
64- # Mapping of SDK class -> proto class
6552TRANSACTION_PROTO_MAP = {
6653 "TokenBurnTransaction" : "TokenBurnTransactionBody" ,
6754 "TokenAssociateTransaction" : "TokenAssociateTransactionBody" ,
@@ -70,48 +57,52 @@ def map_proto_setter_to_sdk(proto_setter: str) -> str:
7057}
7158
7259if __name__ == "__main__" :
73- # Load Step 3 (SDK classes)
7460 step3_module = load_module (STEP3_FILE , "step3_token_classes" )
75- # Load Step 4 (proto mappings)
7661 step4_module = load_module (STEP4_FILE , "step4_proto_attributes" )
7762 proto_mappings = getattr (step4_module , "proto_mappings" , {})
7863
79- print ("\n 📦 All proto mappings available in Step 4 :" )
64+ print ("\n 📦 Proto mappings available:" )
8065 for k in sorted (proto_mappings .keys ()):
8166 print (" -" , k )
8267
8368 for sdk_module_name , sdk_class_name in SDK_MODULE_CLASS_MAP .items ():
84- # Get SDK info
8569 sdk_module = getattr (step3_module , sdk_module_name , None )
86- sdk_class_info = getattr (sdk_module , sdk_class_name , None ) if sdk_module else {'attributes' : [], 'setters' : []}
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' , [])
8772
88- # Get proto info
8973 proto_class_name = TRANSACTION_PROTO_MAP .get (sdk_class_name , "" )
9074 proto_info = proto_mappings .get (proto_class_name )
91-
9275 if proto_info is None :
9376 print (f"\n ⚠️ Proto mapping missing for { proto_class_name } (SDK { sdk_class_name } )" )
9477 proto_info = {'attributes' : [], 'setters' : []}
9578
96- # Map proto attributes and setters to SDK equivalents
97- mapped_proto_attrs = [map_proto_to_sdk (a ) for a in proto_info ['attributes' ]]
98- mapped_proto_setters = [map_proto_setter_to_sdk (s ) for s in proto_info ['setters' ]]
79+ actual_proto_attrs = [map_proto_to_sdk (a ) for a in proto_info ['attributes' ]]
80+ predicted_setters = predicted_proto_setters (proto_info ['attributes' ])
9981
100- # Compute missing attributes and setters
101- missing_attributes = [a for a in mapped_proto_attrs if a not in sdk_class_info ['attributes' ]]
102- missing_setters = [s for s in mapped_proto_setters if s not in sdk_class_info ['setters' ]]
82+ sdk_methods = sdk_class_info ['setters' ] + sdk_class_info ['other_methods' ]
10383
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 ]
86+
87+ # Detect extra SDK helpers beyond predicted setters
88+ extra_sdk_methods = [m for m in sdk_methods if m not in predicted_setters ]
89+
90+ # Logging
10491 print (f"\n 💠 { sdk_class_name } vs { proto_class_name } " )
10592 print ("✅ SDK Attributes:" , sdk_class_info ['attributes' ])
10693 print ("✅ SDK Setters:" , sdk_class_info ['setters' ])
107- print ("📦 Proto Attributes (mapped):" , mapped_proto_attrs )
108- print ("📦 Proto Setters (mapped):" , mapped_proto_setters )
94+ print ("✅ SDK Other Methods:" , sdk_class_info ['other_methods' ])
95+ print ("📦 Actual Proto Attributes:" , actual_proto_attrs )
96+ print ("📦 Predicted Proto Setters:" , predicted_setters )
10997
110- if missing_attributes or missing_setters :
98+ if missing_attrs or missing_setters :
11199 print ("⚠️ Missing in SDK:" )
112- if missing_attributes :
113- print (" - Attributes:" , missing_attributes )
100+ if missing_attrs :
101+ print (" - Attributes:" , missing_attrs )
114102 if missing_setters :
115- print (" - Setters:" , missing_setters )
103+ print (" - Predicted Setters / Methods :" , missing_setters )
116104 else :
117- print ("✅ No proto attributes or setters are actually missing in SDK" )
105+ print ("✅ SDK fully covers proto attributes and predicted setters" )
106+
107+ if extra_sdk_methods :
108+ print ("✨ Extra SDK methods beyond proto setters:" , extra_sdk_methods )
0 commit comments