@@ -1510,6 +1510,11 @@ def __init__(self,
15101510 )
15111511
15121512 def __enter__ (self ):
1513+ self ._ensure_valid_state ()
1514+
1515+ if not self ._reader :
1516+ raise C2paError ("Invalid Reader when entering context" )
1517+
15131518 return self
15141519
15151520 def __exit__ (self , exc_type , exc_val , exc_tb ):
@@ -1543,6 +1548,8 @@ def _cleanup_resources(self):
15431548 try :
15441549 # Only cleanup if not already closed and we have a valid reader
15451550 if hasattr (self , '_closed' ) and not self ._closed :
1551+ self ._closed = True
1552+
15461553 # Clean up reader
15471554 if hasattr (self , '_reader' ) and self ._reader :
15481555 try :
@@ -1578,13 +1585,12 @@ def _cleanup_resources(self):
15781585 finally :
15791586 self ._backing_file = None
15801587
1581- self ._closed = True
15821588 except Exception :
15831589 # Ensure we don't raise exceptions during cleanup
15841590 pass
15851591
15861592 def close (self ):
1587- """Release the reader resources safely .
1593+ """Release the reader resources.
15881594
15891595 This method ensures all resources are properly cleaned up,
15901596 even if errors occur during cleanup.
@@ -1866,7 +1872,6 @@ def __enter__(self):
18661872 """Context manager entry."""
18671873 self ._ensure_valid_state ()
18681874
1869- # Additional pointer validation before entering context
18701875 if not self ._signer :
18711876 raise C2paError ("Invalid signer pointer: pointer is null" )
18721877
@@ -1877,13 +1882,15 @@ def __exit__(self, exc_type, exc_val, exc_tb):
18771882 self .close ()
18781883
18791884 def _cleanup_resources (self ):
1880- """Internal cleanup method that safely releases native resources.
1885+ """Internal cleanup method that releases native resources.
18811886
18821887 This method handles the actual cleanup logic and can be called
18831888 from both close() and __del__ without causing double frees.
18841889 """
18851890 try :
18861891 if not self ._closed and self ._signer :
1892+ self ._closed = True
1893+
18871894 try :
18881895 _lib .c2pa_signer_free (self ._signer )
18891896 except Exception :
@@ -1896,7 +1903,6 @@ def _cleanup_resources(self):
18961903 if self ._callback_cb :
18971904 self ._callback_cb = None
18981905
1899- self ._closed = True
19001906 except Exception :
19011907 # Ensure we don't raise exceptions during cleanup
19021908 pass
@@ -1913,7 +1919,7 @@ def _ensure_valid_state(self):
19131919 raise C2paError (Signer ._ERROR_MESSAGES ['closed_error' ])
19141920
19151921 def close (self ):
1916- """Release the signer resources safely .
1922+ """Release the signer resources.
19171923
19181924 This method ensures all resources are properly cleaned up,
19191925 even if errors occur during cleanup.
@@ -2146,10 +2152,6 @@ def from_archive(cls, stream: Any) -> 'Builder':
21462152
21472153 return builder
21482154
2149- def __del__ (self ):
2150- """Ensure resources are cleaned up if close() wasn't called."""
2151- self ._cleanup_resources ()
2152-
21532155 def _ensure_valid_state (self ):
21542156 """Ensure the builder is in a valid state for operations.
21552157
@@ -2162,14 +2164,16 @@ def _ensure_valid_state(self):
21622164 raise C2paError (Builder ._ERROR_MESSAGES ['closed_error' ])
21632165
21642166 def _cleanup_resources (self ):
2165- """Internal cleanup method that safely releases native resources.
2167+ """Internal cleanup method that releases native resources.
21662168
21672169 This method handles the actual cleanup logic and can be called
21682170 from both close() and __del__ without causing double frees.
21692171 """
21702172 try :
21712173 # Only cleanup if not already closed and we have a valid builder
21722174 if hasattr (self , '_closed' ) and not self ._closed :
2175+ self ._closed = True
2176+
21732177 if hasattr (
21742178 self ,
21752179 '_builder' ) and self ._builder and self ._builder != 0 :
@@ -2182,13 +2186,15 @@ def _cleanup_resources(self):
21822186 )
21832187 pass
21842188 finally :
2185- # Always clear the pointer and mark as closed
21862189 self ._builder = None
2187- self ._closed = True
21882190 except Exception :
21892191 # Ensure we don't raise exceptions during cleanup
21902192 pass
21912193
2194+ def __del__ (self ):
2195+ """Ensure resources are cleaned up if close() wasn't called."""
2196+ self ._cleanup_resources ()
2197+
21922198 def close (self ):
21932199 """Release the builder resources.
21942200
@@ -2212,6 +2218,11 @@ def close(self):
22122218 self ._closed = True
22132219
22142220 def __enter__ (self ):
2221+ self ._ensure_valid_state ()
2222+
2223+ if not self ._builder :
2224+ raise C2paError ("Invalid Builder when entering context" )
2225+
22152226 return self
22162227
22172228 def __exit__ (self , exc_type , exc_val , exc_tb ):
0 commit comments