33import json
44from dataclasses import dataclass
55from pathlib import Path
6- from typing import Annotated , Any , Dict , List , Self
6+ from typing import Annotated , Any , Dict , Generic , List , Self , TypeVar
77
88from pydantic import Field , PlainSerializer , PlainValidator
99
@@ -287,43 +287,53 @@ class Result(CamelModel):
287287 opcode_count : OpcodeCount | None = None
288288
289289
290+ JSONDict = Dict [str , Any ]
291+
292+ TRaw = TypeVar ("TRaw" , str , JSONDict )
290293
291294
292295@dataclass (kw_only = True )
293- class LazyAlloc :
296+ class LazyAlloc ( Generic [ TRaw ]) :
294297 """
295298 Allocation that is lazily loaded from a JSON file.
296299 """
297300
298- json_contents : Dict | None = None
299- str_contents : str | None = None
301+ raw : TRaw
300302 alloc : Alloc | None = None
301303
302- def str_contents_from_cache (self ) -> str :
303- """
304- Return the cached, unparsed, alloc from the last t8n execution.
305- """
306- assert self .str_contents is not None , "No string cache found"
307- return self .str_contents
308-
309- def json_contents_from_cache (self ) -> Dict :
310- """
311- Return the cached, unparsed, json dict from the last t8n execution.
312- """
313- assert self .json_contents is not None , "No json cache found"
314- return self .json_contents
304+ def validate (self ) -> Alloc :
305+ """Validate the alloc."""
306+ raise NotImplementedError ("validate method not implemented." )
315307
316- def get_alloc (self ) -> Alloc :
308+ def get (self ) -> Alloc :
317309 """Model validate the allocation and return it."""
318- if self .alloc is not None :
319- return self .alloc
320- elif self .json_contents is not None :
321- self .alloc = Alloc .model_validate (self .json_contents )
322- return self .alloc
323- elif self .str_contents is not None :
324- self .alloc = Alloc .model_validate_json (self .str_contents )
325- return self .alloc
326- raise ValueError ("No alloc found" )
310+ if self .alloc is None :
311+ self .alloc = self .validate ()
312+ return self .alloc
313+
314+
315+ class LazyAllocJson (LazyAlloc [JSONDict ]):
316+ """
317+ Lazy allocation backed by a JSON dict cache.
318+
319+ Uses Alloc.model_validate on the dict.
320+ """
321+
322+ def validate (self ) -> Alloc :
323+ """Validate the alloc."""
324+ return Alloc .model_validate (self .raw )
325+
326+
327+ class LazyAllocStr (LazyAlloc [str ]):
328+ """
329+ Lazy allocation backed by a JSON dict cache.
330+
331+ Uses Alloc.model_validate on the dict.
332+ """
333+
334+ def validate (self ) -> Alloc :
335+ """Validate the alloc."""
336+ return Alloc .model_validate_json (self .raw )
327337
328338
329339@dataclass
@@ -342,10 +352,12 @@ def to_files(
342352 Prepare the input in a directory path in the file system for
343353 consumption by the t8n tool.
344354 """
345- if isinstance (self .alloc , LazyAlloc ):
346- alloc_contents = self .alloc .str_contents_from_cache ()
347- else :
355+ if isinstance (self .alloc , Alloc ):
348356 alloc_contents = self .alloc .model_dump_json (** model_dump_config )
357+ elif isinstance (self .alloc , LazyAllocStr ):
358+ alloc_contents = self .alloc .raw
359+ else :
360+ raise Exception (f"Invalid alloc type: { type (self .alloc )} " )
349361
350362 env_contents = self .env .model_dump_json (** model_dump_config )
351363 txs_contents = (
@@ -375,10 +387,12 @@ def to_files(
375387
376388 def model_dump_json (self , ** model_dump_config : Any ) -> str :
377389 """Dump the model in string JSON format."""
378- if isinstance (self .alloc , LazyAlloc ):
379- alloc_contents = self .alloc .str_contents_from_cache ()
380- else :
390+ if isinstance (self .alloc , Alloc ):
381391 alloc_contents = self .alloc .model_dump_json (** model_dump_config )
392+ elif isinstance (self .alloc , LazyAllocStr ):
393+ alloc_contents = self .alloc .raw
394+ else :
395+ raise Exception (f"Invalid alloc type: { type (self .alloc )} " )
382396
383397 env_contents = self .env .model_dump_json (** model_dump_config )
384398 txs_contents = (
@@ -405,12 +419,14 @@ def model_dump_json(self, **model_dump_config: Any) -> str:
405419 def model_dump (self , mode : str , ** model_dump_config : Any ) -> Any :
406420 """Return the validated model."""
407421 assert mode == "json" , f"Mode { mode } not supported."
408- if isinstance (self .alloc , LazyAlloc ):
409- alloc_contents = self .alloc .json_contents_from_cache ()
410- else :
422+ if isinstance (self .alloc , Alloc ):
411423 alloc_contents = self .alloc .model_dump (
412424 mode = mode , ** model_dump_config
413425 )
426+ elif isinstance (self .alloc , LazyAllocJson ):
427+ alloc_contents = self .alloc .raw
428+ else :
429+ raise Exception (f"Invalid alloc type: { type (self .alloc )} " )
414430
415431 env_contents = self .env .model_dump (mode = mode , ** model_dump_config )
416432 txs_contents = [
@@ -450,7 +466,7 @@ def model_validate_files(
450466 result = Result .model_validate_json (
451467 json_data = result_data , context = context
452468 )
453- alloc = LazyAlloc ( str_contents = alloc_data )
469+ alloc = LazyAllocStr ( raw = alloc_data )
454470 output = cls (result = result , alloc = alloc )
455471 return output
456472
@@ -465,7 +481,7 @@ def model_validate(
465481 result = Result .model_validate (
466482 obj = response_json ["result" ], context = context
467483 )
468- alloc = LazyAlloc ( json_contents = response_json ["alloc" ])
484+ alloc = LazyAllocJson ( raw = response_json ["alloc" ])
469485 output = cls (result = result , alloc = alloc )
470486 return output
471487
@@ -482,7 +498,7 @@ def model_validate_json(
482498 result = Result .model_validate (
483499 obj = parsed_json ["result" ], context = context
484500 )
485- alloc = LazyAlloc ( str_contents = json .dumps (parsed_json ["alloc" ]))
501+ alloc = LazyAllocStr ( raw = json .dumps (parsed_json ["alloc" ]))
486502 output = cls (result = result , alloc = alloc )
487503 return output
488504
0 commit comments