1010import logging
1111import platform
1212from pathlib import Path
13- from typing import Optional , Tuple
13+ from typing import Optional
1414from enum import Enum
1515
1616# Debug flag for library loading
1717DEBUG_LIBRARY_LOADING = False
1818
19- # Create a module-specific logger with NullHandler to avoid interfering with global configuration
20- logger = logging .getLogger ("c2pa" )
21- logger .addHandler (logging .NullHandler ())
19+ # Configure logging
20+ logging .basicConfig (
21+ level = logging .INFO ,
22+ format = '%(asctime)s - %(levelname)s - %(message)s' ,
23+ force = True # Force configuration even if already configured
24+ )
25+ logger = logging .getLogger (__name__ )
2226
2327
2428class CPUArchitecture (Enum ):
@@ -27,34 +31,20 @@ class CPUArchitecture(Enum):
2731 X86_64 = "x86_64"
2832
2933
30- def get_platform_identifier (cpu_arch : Optional [ CPUArchitecture ] = None ) -> str :
31- """Get the full platform identifier (arch-os) for the current system,
34+ def get_platform_identifier () -> str :
35+ """Get the platform identifier (arch-os) for the current system,
3236 matching the downloaded identifiers used by the Github publisher.
3337
34- Args:
35- cpu_arch: Optional CPU architecture for macOS.
36- If not provided, returns universal build.
37- Only used on macOS systems.
38-
3938 Returns one of:
40- - universal-apple-darwin (for Mac, when cpu_arch is None)
41- - aarch64-apple-darwin (for Mac ARM64)
42- - x86_64-apple-darwin (for Mac x86_64)
39+ - universal-apple-darwin (for Mac, ARM or Intel)
4340 - x86_64-pc-windows-msvc (for Windows 64-bit)
4441 - x86_64-unknown-linux-gnu (for Linux 64-bit)
42+ - aarch64-unknown-linux-gnu (for Linux ARM)
4543 """
4644 system = platform .system ().lower ()
4745
4846 if system == "darwin" :
49- if cpu_arch is None :
50- return "universal-apple-darwin"
51- elif cpu_arch == CPUArchitecture .AARCH64 :
52- return "aarch64-apple-darwin"
53- elif cpu_arch == CPUArchitecture .X86_64 :
54- return "x86_64-apple-darwin"
55- else :
56- raise ValueError (
57- f"Unsupported CPU architecture for macOS: { cpu_arch } " )
47+ return "universal-apple-darwin"
5848 elif system == "windows" :
5949 return "x86_64-pc-windows-msvc"
6050 elif system == "linux" :
@@ -81,7 +71,8 @@ def _get_architecture() -> str:
8171 elif sys .platform == "linux" :
8272 return platform .machine ()
8373 elif sys .platform == "win32" :
84- # win32 will cover all Windows versions (the 32 is a historical quirk)
74+ # win32 will cover all Windows versions
75+ # (the 32 is a historical quirk)
8576 return platform .machine ()
8677 else :
8778 raise RuntimeError (f"Unsupported platform: { sys .platform } " )
@@ -99,7 +90,8 @@ def _get_platform_dir() -> str:
9990 elif sys .platform == "linux" :
10091 return "unknown-linux-gnu"
10192 elif sys .platform == "win32" :
102- # win32 will cover all Windows versions (the 32 is a historical quirk)
93+ # win32 will cover all Windows versions
94+ # (the 32 is a historical quirk)
10395 return "pc-windows-msvc"
10496 else :
10597 raise RuntimeError (f"Unsupported platform: { sys .platform } " )
@@ -117,28 +109,31 @@ def _load_single_library(lib_name: str,
117109 Returns:
118110 The loaded library or None if loading failed
119111 """
120- if DEBUG_LIBRARY_LOADING :
121- logger .info (f"Searching for library '{ lib_name } ' in paths: { [str (p ) for p in search_paths ]} " )
112+ if DEBUG_LIBRARY_LOADING : # pragma: no cover
113+ logger .info (
114+ f"Searching for library '{ lib_name } ' in paths: { [str (p ) for p in search_paths ]} " )
122115 current_arch = _get_architecture ()
123- if DEBUG_LIBRARY_LOADING :
116+ if DEBUG_LIBRARY_LOADING : # pragma: no cover
124117 logger .info (f"Current architecture: { current_arch } " )
125118
126119 for path in search_paths :
127120 lib_path = path / lib_name
128- if DEBUG_LIBRARY_LOADING :
121+ if DEBUG_LIBRARY_LOADING : # pragma: no cover
129122 logger .info (f"Checking path: { lib_path } " )
130123 if lib_path .exists ():
131- if DEBUG_LIBRARY_LOADING :
124+ if DEBUG_LIBRARY_LOADING : # pragma: no cover
132125 logger .info (f"Found library at: { lib_path } " )
133126 try :
134127 return ctypes .CDLL (str (lib_path ))
135128 except Exception as e :
136129 error_msg = str (e )
137130 if "incompatible architecture" in error_msg :
138- logger .error (f"Architecture mismatch: Library at { lib_path } is not compatible with current architecture { current_arch } " )
131+ logger .error (
132+ f"Architecture mismatch: Library at { lib_path } is not compatible with current architecture { current_arch } " )
139133 logger .error (f"Error details: { error_msg } " )
140134 else :
141- logger .error (f"Failed to load library from { lib_path } : { e } " )
135+ logger .error (
136+ f"Failed to load library from { lib_path } : { e } " )
142137 else :
143138 logger .debug (f"Library not found at: { lib_path } " )
144139 return None
@@ -155,7 +150,7 @@ def _get_possible_search_paths() -> list[Path]:
155150 platform_dir = _get_platform_dir ()
156151 platform_id = get_platform_identifier ()
157152
158- if DEBUG_LIBRARY_LOADING :
153+ if DEBUG_LIBRARY_LOADING : # pragma: no cover
159154 logger .info (f"Using platform directory: { platform_dir } " )
160155 logger .info (f"Using platform identifier: { platform_id } " )
161156
@@ -196,9 +191,12 @@ def dynamically_load_library(
196191 Load the dynamic library containing the C-API based on the platform.
197192
198193 Args:
199- lib_name: Optional specific library name to load. If provided, only this library will be loaded.
200- This enables to potentially load wrapper libraries of the C-API that may have an other name
201- (the presence of required symbols will nevertheless be verified once the library is loaded).
194+ lib_name: Optional specific library name to load.
195+ If provided, only this library will be loaded.
196+ This enables to potentially load wrapper libraries
197+ of the C-API that may have an other name
198+ (the presence of required symbols will nevertheless
199+ be verified once the library is loaded).
202200
203201 Returns:
204202 The loaded library or None if loading failed
@@ -212,15 +210,15 @@ def dynamically_load_library(
212210 else :
213211 raise RuntimeError (f"Unsupported platform: { sys .platform } " )
214212
215- if DEBUG_LIBRARY_LOADING :
213+ if DEBUG_LIBRARY_LOADING : # pragma: no cover
216214 logger .info (f"Current working directory: { Path .cwd ()} " )
217215 logger .info (f"Package directory: { Path (__file__ ).parent } " )
218216 logger .info (f"System architecture: { _get_architecture ()} " )
219217
220218 # Check for C2PA_LIBRARY_NAME environment variable
221219 env_lib_name = os .environ .get ("C2PA_LIBRARY_NAME" )
222220 if env_lib_name :
223- if DEBUG_LIBRARY_LOADING :
221+ if DEBUG_LIBRARY_LOADING : # pragma: no cover
224222 logger .info (
225223 f"Using library name from env var C2PA_LIBRARY_NAME: { env_lib_name } " )
226224 try :
@@ -229,13 +227,14 @@ def dynamically_load_library(
229227 if lib :
230228 return lib
231229 else :
232- logger .error (f"Could not find library { env_lib_name } in any of the search paths" )
230+ logger .error (
231+ f"Could not find library { env_lib_name } in any of the search paths" )
233232 # Continue with normal loading if environment variable library
234233 # name fails
235234 except Exception as e :
236235 logger .error (f"Failed to load library from C2PA_LIBRARY_NAME: { e } " )
237- # Continue with normal loading if environment variable library name
238- # fails
236+ # Continue with normal loading if
237+ # environment variable library name fails
239238
240239 possible_paths = _get_possible_search_paths ()
241240
@@ -245,15 +244,22 @@ def dynamically_load_library(
245244 if not lib :
246245 platform_id = get_platform_identifier ()
247246 current_arch = _get_architecture ()
248- logger .error (f"Could not find { lib_name } in any of the search paths: { [str (p ) for p in possible_paths ]} " )
249- logger .error (f"Platform: { platform_id } , Architecture: { current_arch } " )
250- raise RuntimeError (f"Could not find { lib_name } in any of the search paths (Platform: { platform_id } , Architecture: { current_arch } )" )
247+ logger .error (
248+ f"Could not find { lib_name } in any of the search paths: { [str (p ) for p in possible_paths ]} " )
249+ logger .error (
250+ f"Platform: { platform_id } , Architecture: { current_arch } " )
251+ raise RuntimeError (
252+ f"Could not find { lib_name } in any of the search paths (Platform: { platform_id } , Architecture: { current_arch } )" )
251253 return lib
252254
253255 # Default path (no library name provided in the environment)
254256 c2pa_lib = _load_single_library (c2pa_lib_name , possible_paths )
255257 if not c2pa_lib :
256- logger .error (f"Could not find { c2pa_lib_name } in any of the search paths: { [str (p ) for p in possible_paths ]} " )
257- raise RuntimeError (f"Could not find { c2pa_lib_name } in any of the search paths" )
258+ logger .error (
259+ f"Could not find { c2pa_lib_name } in any of the search paths: {
260+ [
261+ str (p ) for p in possible_paths ]} " )
262+ raise RuntimeError (
263+ f"Could not find { c2pa_lib_name } in any of the search paths" )
258264
259265 return c2pa_lib
0 commit comments