@@ -244,6 +244,19 @@ class C2paStream(ctypes.Structure):
244244 ]
245245
246246
247+ def _clear_error_state ():
248+ """Clear any existing error state from the C library.
249+
250+ This function should be called at the beginning of object initialization
251+ and before any operations that could potentially raise an error,
252+ to ensure that stale error states from previous operations don't interfere
253+ with new objects being created.
254+ """
255+ error = _lib .c2pa_error ()
256+ if error :
257+ # Free the error to clear the state
258+ _lib .c2pa_string_free (error )
259+
247260class C2paSignerInfo (ctypes .Structure ):
248261 """Configuration for a Signer."""
249262 _fields_ = [
@@ -264,6 +277,7 @@ def __init__(self, alg, sign_cert, private_key, ta_url):
264277 private_key: The private key as a string
265278 ta_url: The timestamp authority URL as bytes
266279 """
280+ _clear_error_state ()
267281
268282 if sign_cert is None :
269283 raise ValueError ("sign_cert must be set" )
@@ -601,19 +615,6 @@ def _convert_to_py_string(value) -> str:
601615 return py_string
602616
603617
604- def _clear_error_state ():
605- """Clear any existing error state from the C library.
606-
607- This function should be called at the beginning of object initialization
608- to ensure that stale error states from previous operations don't interfere
609- with new objects being created.
610- """
611- error = _lib .c2pa_error ()
612- if error :
613- # Free the error to clear the state
614- _lib .c2pa_string_free (error )
615-
616-
617618def _parse_operation_result_for_error (
618619 result : ctypes .c_void_p | None ,
619620 check_error : bool = True ) -> Optional [str ]:
@@ -705,6 +706,8 @@ def load_settings(settings: Union[str, dict], format: str = "json") -> None:
705706 Raises:
706707 C2paError: If there was an error loading the settings
707708 """
709+ _clear_error_state ()
710+
708711 # Convert to JSON string as necessary
709712 try :
710713 if isinstance (settings , dict ):
@@ -789,6 +792,8 @@ def read_ingredient_file(
789792 stacklevel = 2 ,
790793 )
791794
795+ _clear_error_state ()
796+
792797 container = _StringContainer ()
793798
794799 container ._path_str = str (path ).encode ('utf-8' )
@@ -834,6 +839,8 @@ def read_file(path: Union[str, Path],
834839 stacklevel = 2 ,
835840 )
836841
842+ _clear_error_state ()
843+
837844 container = _StringContainer ()
838845
839846 container ._path_str = str (path ).encode ('utf-8' )
@@ -920,6 +927,8 @@ def sign_file(
920927 stacklevel = 2 ,
921928 )
922929
930+ _clear_error_state ()
931+
923932 try :
924933 # Determine if we have a signer or signer info
925934 if isinstance (signer_or_info , C2paSignerInfo ):
@@ -1946,6 +1955,10 @@ def from_info(cls, signer_info: C2paSignerInfo) -> 'Signer':
19461955 Raises:
19471956 C2paError: If there was an error creating the signer
19481957 """
1958+ # Native libs plumbing:
1959+ # Clear any stale error state from previous operations
1960+ _clear_error_state ()
1961+
19491962 signer_ptr = _lib .c2pa_signer_from_info (ctypes .byref (signer_info ))
19501963
19511964 if not signer_ptr :
@@ -2071,6 +2084,10 @@ def wrapped_callback(
20712084 cls ._ERROR_MESSAGES ['encoding_error' ].format (
20722085 str (e )))
20732086
2087+ # Native libs plumbing:
2088+ # Clear any stale error state from previous operations
2089+ _clear_error_state ()
2090+
20742091 # Create the callback object using the callback function
20752092 callback_cb = SignerCallback (wrapped_callback )
20762093
@@ -2114,7 +2131,7 @@ def __init__(self, signer_ptr: ctypes.POINTER(C2paSigner)):
21142131 # Native libs plumbing:
21152132 # Clear any stale error state from previous operations
21162133 _clear_error_state ()
2117-
2134+
21182135 # Validate pointer before assignment
21192136 if not signer_ptr :
21202137 raise C2paError ("Invalid signer pointer: pointer is null" )
@@ -2347,6 +2364,7 @@ def from_archive(cls, stream: Any) -> 'Builder':
23472364 """
23482365 builder = cls ({})
23492366 stream_obj = Stream (stream )
2367+
23502368 builder ._builder = _lib .c2pa_builder_from_archive (stream_obj ._stream )
23512369
23522370 if not builder ._builder :
@@ -2908,6 +2926,8 @@ def format_embeddable(format: str, manifest_bytes: bytes) -> tuple[int, bytes]:
29082926 Raises:
29092927 C2paError: If there was an error converting the manifest
29102928 """
2929+ _clear_error_state ()
2930+
29112931 format_str = format .encode ('utf-8' )
29122932 manifest_array = (ctypes .c_ubyte * len (manifest_bytes ))(* manifest_bytes )
29132933 result_bytes_ptr = ctypes .POINTER (ctypes .c_ubyte )()
@@ -3017,6 +3037,8 @@ def ed25519_sign(data: bytes, private_key: str) -> bytes:
30173037 C2paError: If there was an error signing the data
30183038 C2paError.Encoding: If the private key contains invalid UTF-8 chars
30193039 """
3040+ _clear_error_state ()
3041+
30203042 if not data :
30213043 raise C2paError ("Data to sign cannot be empty" )
30223044
0 commit comments