@@ -2079,6 +2079,7 @@ def __init__(self, manifest_json: Any):
20792079 C2paError.Json: If the manifest JSON cannot be serialized
20802080 """
20812081 self ._closed = False
2082+ self ._initialized = False
20822083 self ._builder = None
20832084
20842085 if not isinstance (manifest_json , str ):
@@ -2108,6 +2109,9 @@ def __init__(self, manifest_json: Any):
21082109 )
21092110 )
21102111
2112+ # Mark as initialized only after successful creation
2113+ self ._initialized = True
2114+
21112115 @classmethod
21122116 def from_json (cls , manifest_json : Any ) -> 'Builder' :
21132117 """Create a new Builder from a JSON manifest.
@@ -2150,16 +2154,20 @@ def from_archive(cls, stream: Any) -> 'Builder':
21502154 raise C2paError (error )
21512155 raise C2paError ("Failed to create builder from archive" )
21522156
2157+ # Mark as initialized after successful creation from archive
2158+ builder ._initialized = True
21532159 return builder
21542160
21552161 def _ensure_valid_state (self ):
21562162 """Ensure the builder is in a valid state for operations.
21572163
21582164 Raises:
2159- C2paError: If the builder is closed or invalid
2165+ C2paError: If the builder is closed, not initialized, or invalid
21602166 """
21612167 if self ._closed :
21622168 raise C2paError (Builder ._ERROR_MESSAGES ['closed_error' ])
2169+ if not self ._initialized :
2170+ raise C2paError ("Builder is not properly initialized" )
21632171 if not self ._builder :
21642172 raise C2paError (Builder ._ERROR_MESSAGES ['closed_error' ])
21652173
@@ -2187,6 +2195,9 @@ def _cleanup_resources(self):
21872195 pass
21882196 finally :
21892197 self ._builder = None
2198+
2199+ # Reset initialized state after cleanup
2200+ self ._initialized = False
21902201 except Exception :
21912202 # Ensure we don't raise exceptions during cleanup
21922203 pass
@@ -2219,10 +2230,6 @@ def close(self):
22192230
22202231 def __enter__ (self ):
22212232 self ._ensure_valid_state ()
2222-
2223- if not self ._builder :
2224- raise C2paError ("Invalid Builder when entering context" )
2225-
22262233 return self
22272234
22282235 def __exit__ (self , exc_type , exc_val , exc_tb ):
@@ -2327,8 +2334,7 @@ def add_ingredient_from_stream(
23272334 C2paError.Encoding: If the ingredient JSON or format
23282335 contains invalid UTF-8 characters
23292336 """
2330- if not self ._builder :
2331- raise C2paError (Builder ._ERROR_MESSAGES ['closed_error' ])
2337+ self ._ensure_valid_state ()
23322338
23332339 try :
23342340 ingredient_str = ingredient_json .encode ('utf-8' )
@@ -2413,8 +2419,7 @@ def to_archive(self, stream: Any) -> None:
24132419 Raises:
24142420 C2paError: If there was an error writing the archive
24152421 """
2416- if not self ._builder :
2417- raise C2paError (Builder ._ERROR_MESSAGES ['closed_error' ])
2422+ self ._ensure_valid_state ()
24182423
24192424 with Stream (stream ) as stream_obj :
24202425 result = _lib .c2pa_builder_to_archive (
@@ -2452,8 +2457,7 @@ def _sign_internal(
24522457 Raises:
24532458 C2paError: If there was an error during signing
24542459 """
2455- if not self ._builder :
2456- raise C2paError (Builder ._ERROR_MESSAGES ['closed_error' ])
2460+ self ._ensure_valid_state ()
24572461
24582462 # Validate signer pointer before use
24592463 if not signer or not hasattr (signer , '_signer' ) or not signer ._signer :
0 commit comments