@@ -1102,8 +1102,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
11021102 self .close ()
11031103
11041104 def __del__ (self ):
1105- """Ensure resources are cleaned up if close()
1106- wasn't called.
1105+ """Ensure resources are cleaned up if close()wasn't called.
11071106
11081107 This destructor only cleans up if the object
11091108 hasn't been explicitly closed.
@@ -1217,9 +1216,7 @@ class Reader:
12171216 @classmethod
12181217 def get_supported_mime_types (cls ) -> list [str ]:
12191218 """Get the list of supported MIME types for the Reader.
1220-
1221- This method retrieves supported MIME types from the native library
1222- with proper pointer validation and error handling.
1219+ This method retrieves supported MIME types from the native library.
12231220
12241221 Returns:
12251222 List of supported MIME type strings
@@ -1808,6 +1805,41 @@ def __exit__(self, exc_type, exc_val, exc_tb):
18081805 """Context manager exit."""
18091806 self .close ()
18101807
1808+ def _cleanup_resources (self ):
1809+ """Internal cleanup method that safely releases native resources.
1810+
1811+ This method handles the actual cleanup logic and can be called
1812+ from both close() and __del__ without causing double frees.
1813+ """
1814+ try :
1815+ # Only cleanup if not already closed and we have a valid signer
1816+ if hasattr (self , '_closed' ) and not self ._closed :
1817+ if hasattr (self , '_signer' ) and self ._signer :
1818+ try :
1819+ _lib .c2pa_signer_free (self ._signer )
1820+ except Exception :
1821+ # Cleanup failure doesn't raise exceptions
1822+ pass
1823+ finally :
1824+ self ._signer = None
1825+
1826+ # Clear callback reference to prevent cycles
1827+ if hasattr (self , '_callback_cb' ):
1828+ self ._callback_cb = None
1829+
1830+ self ._closed = True
1831+ except Exception :
1832+ # Ensure we don't raise exceptions during cleanup
1833+ pass
1834+
1835+ def __del__ (self ):
1836+ """Ensure resources are cleaned up if close() wasn't called.
1837+
1838+ This destructor safely handles cleanup without causing double frees.
1839+ It only cleans up if the object hasn't been explicitly closed.
1840+ """
1841+ self ._cleanup_resources ()
1842+
18111843 def close (self ):
18121844 """Release the signer resources.
18131845
@@ -1820,16 +1852,10 @@ def close(self):
18201852 return
18211853
18221854 try :
1823- if self ._signer :
1824- try :
1825- _lib .c2pa_signer_free (self ._signer )
1826- except Exception as e :
1827- print (
1828- Signer ._ERROR_MESSAGES ['signer_cleanup' ].format (
1829- str (e )), file = sys .stderr )
1830- finally :
1831- self ._signer = None
1855+ # Use the internal cleanup method
1856+ self ._cleanup_resources ()
18321857 except Exception as e :
1858+ # Log any unexpected errors during close
18331859 print (
18341860 Signer ._ERROR_MESSAGES ['cleanup_error' ].format (
18351861 str (e )), file = sys .stderr )
@@ -1893,9 +1919,7 @@ class Builder:
18931919 @classmethod
18941920 def get_supported_mime_types (cls ) -> list [str ]:
18951921 """Get the list of supported MIME types for the Builder.
1896-
1897- This method retrieves supported MIME types from the native library
1898- with proper pointer validation and error handling.
1922+ This method retrieves supported MIME types from the native library.
18991923
19001924 Returns:
19011925 List of supported MIME type strings
0 commit comments