11import logging
2- from contextlib import suppress
32from copy import deepcopy
43from datetime import datetime
54from enum import Enum
6- from typing import Any , Dict , Generic , List , Optional , Type , TypeVar , get_args , get_origin
5+ from typing import Any , Dict , Generic , List , Optional , Type , TypeVar
76
87from pydantic import BaseModel
98from pydantic .dataclasses import dataclass
@@ -35,7 +34,7 @@ class Meta:
3534
3635@dataclass
3736class OperationData :
38- # FIXME:
37+ # FIXME: Bug in TzKT, shouldn't be optional
3938 type : Optional [str ]
4039 id : int
4140 level : int
@@ -67,7 +66,7 @@ class OperationData:
6766
6867 def _merge_bigmapdiffs (self , storage_dict : Dict [str , Any ], bigmap_name : str ) -> None :
6968 if self .bigmaps is None :
70- raise Exception ('`bigaps ` field missing' )
69+ raise Exception ('`bigmaps ` field missing' )
7170 bigmapdiffs = [bm for bm in self .bigmaps if bm ['path' ] == bigmap_name ]
7271 for diff in bigmapdiffs :
7372 if diff ['action' ] in ('add_key' , 'update_key' ):
@@ -80,20 +79,23 @@ def _merge_bigmapdiffs(self, storage_dict: Dict[str, Any], bigmap_name: str) ->
8079 def get_merged_storage (self , storage_type : Type [StorageType ]) -> StorageType :
8180 if self .storage is None :
8281 raise Exception ('`storage` field missing' )
83- if self .bigmaps is None :
84- return storage_type .parse_obj (self .storage )
8582
8683 storage = deepcopy (self .storage )
84+ _logger .debug ('Merging storage' )
85+ _logger .debug ('Before: %s' , storage )
8786 for key , field in storage_type .__fields__ .items ():
88- if field .type_ != int and isinstance (storage [key ], int ):
89- with suppress (AttributeError ):
90- if 'key' in field .type_ .__fields__ :
91- storage [key ] = []
92- else :
93- storage [key ] = {}
94-
95- self ._merge_bigmapdiffs (storage , key )
96-
87+ # NOTE: TzKT could return bigmaps as object or as array of key-value objects. We need to guess this from storage.
88+ # TODO: This code should be a part of datasource module.
89+ if field .type_ not in (int , bool ) and isinstance (storage [key ], int ):
90+ if hasattr (field .type_ , '__fields__' ) and 'key' in field .type_ .__fields__ :
91+ storage [key ] = []
92+ else :
93+ storage [key ] = {}
94+
95+ if self .bigmaps is not None :
96+ self ._merge_bigmapdiffs (storage , key )
97+
98+ _logger .debug ('After: %s' , storage )
9799 return storage_type .parse_obj (storage )
98100
99101
0 commit comments