22
22
"win32" : ".dll" ,
23
23
}
24
24
25
- def _find_in_package (lib_name : str , pkg_name : str ) -> str | None :
25
+
26
+ def _find_in_package (lib_name : str , pkg_name : str ) -> str | None :
26
27
"""Tries to find the library in an installed python module `{pgk_name}libs`.
27
28
This is a convention used by, for example, by newly built binary-only ecmwf
28
29
packages, such as eckit dlibs in the "eckitlib" python module."""
@@ -32,14 +33,15 @@ def _find_in_package(lib_name: str, pkg_name: str) -> str|None:
32
33
# the default output of auditwheel wont work
33
34
try :
34
35
module = importlib .import_module (pkg_name + "libs" )
35
- venv_wheel_lib = str ((Path (module .__file__ ) / '..' / lib_name ).resolve ())
36
+ venv_wheel_lib = str ((Path (module .__file__ ) / ".." / lib_name ).resolve ())
36
37
if os .path .exists (venv_wheel_lib ):
37
38
return venv_wheel_lib
38
39
except ImportError :
39
40
pass
40
41
return None
41
42
42
- def _find_in_python (lib_name : str , pkg_name : str ) -> str | None :
43
+
44
+ def _find_in_python (lib_name : str , pkg_name : str ) -> str | None :
43
45
"""Tries to find the library installed directly to Conda/Python sys.prefix
44
46
libs"""
45
47
roots = [sys .prefix ]
@@ -53,7 +55,8 @@ def _find_in_python(lib_name: str, pkg_name: str) -> str|None:
53
55
return fullname
54
56
return None
55
57
56
- def _find_in_home (lib_name : str , pkg_name : str ) -> str | None :
58
+
59
+ def _find_in_home (lib_name : str , pkg_name : str ) -> str | None :
57
60
env_prefixes = [pkg_name .upper (), pkg_name .lower ()]
58
61
env_suffixes = ["HOME" , "DIR" ]
59
62
envs = ["{}_{}" .format (x , y ) for x in env_prefixes for y in env_suffixes ]
@@ -67,6 +70,7 @@ def _find_in_home(lib_name: str, pkg_name: str) -> str|None:
67
70
return fullname
68
71
return None
69
72
73
+
70
74
def _get_paths_from_config ():
71
75
locations = [
72
76
Path (p ).expanduser ()
@@ -116,7 +120,8 @@ def _get_paths_from_config():
116
120
117
121
return paths
118
122
119
- def _find_in_config_paths (lib_name : str , pkg_name : str ) -> str | None :
123
+
124
+ def _find_in_config_paths (lib_name : str , pkg_name : str ) -> str | None :
120
125
paths = _get_paths_from_config ()
121
126
for root in paths :
122
127
for lib in ("lib" , "lib64" ):
@@ -125,7 +130,8 @@ def _find_in_config_paths(lib_name: str, pkg_name: str) -> str|None:
125
130
return str (filepath )
126
131
return None
127
132
128
- def _find_in_ld_path (lib_name : str , pkg_name : str ) -> str | None :
133
+
134
+ def _find_in_ld_path (lib_name : str , pkg_name : str ) -> str | None :
129
135
for path in (
130
136
"LD_LIBRARY_PATH" ,
131
137
"DYLD_LIBRARY_PATH" ,
@@ -136,7 +142,8 @@ def _find_in_ld_path(lib_name: str, pkg_name: str) -> str|None:
136
142
return fullname
137
143
return None
138
144
139
- def _find_in_sys (lib_name : str , pkg_name : str ) -> str | None :
145
+
146
+ def _find_in_sys (lib_name : str , pkg_name : str ) -> str | None :
140
147
for root in (
141
148
"/" ,
142
149
"/usr/" ,
@@ -151,11 +158,24 @@ def _find_in_sys(lib_name: str, pkg_name: str) -> str|None:
151
158
return fullname
152
159
return None
153
160
154
- def _find_in_ctypes_util (lib_name : str , pkg_name : str ) -> str | None :
161
+
162
+ def _find_in_ctypes_util (lib_name : str , pkg_name : str ) -> str | None :
155
163
return ctypes .util .find_library (lib_name )
156
164
157
- def find (lib_name : str , pkg_name : str | None = None ) -> str | None :
165
+
166
+ def find (lib_name : str , pkg_name : str | None = None ) -> str | None :
158
167
"""Returns the path to the selected library, or None if not found.
168
+ Searches over multiple sources in this order:
169
+ - importible python module ("PACKAGE")
170
+ - python's sys.prefix and conda's libs ("PYTHON")
171
+ - package's home like ECCODES_HOME ("HOME")
172
+ - findlibs config like .findlibs ("CONFIG_PATHS")
173
+ - ld library path ("LD_PATH")
174
+ - system's libraries ("SYS")
175
+ - invocation of ctypes.util ("CTYPES_UTIL")
176
+ each can be disabled via setting FINDLIBS_DISABLE_{method} to "yes",
177
+ so eg `export FINDLIBS_DISABLE_PACKAGE=yes`. Consult the code for each
178
+ individual method implementation and further configurability.
159
179
160
180
Arguments
161
181
---------
@@ -177,17 +197,22 @@ def find(lib_name: str, pkg_name: str|None = None) -> str|None:
177
197
extension = EXTENSIONS .get (sys .platform , ".so" )
178
198
lib_name = "lib{}{}" .format (lib_name , extension )
179
199
180
- sources = [
181
- _find_in_package ,
182
- _find_in_python ,
183
- _find_in_home ,
184
- _find_in_config_paths ,
185
- _find_in_ld_path ,
186
- _find_in_sys ,
187
- _find_in_ctypes_util ,
188
- ]
189
-
190
- for source in sources :
191
- if (result := source (lib_name , pkg_name )):
200
+ sources = (
201
+ (_find_in_package , "PACKAGE" ),
202
+ (_find_in_python , "PYTHON" ),
203
+ (_find_in_home , "HOME" ),
204
+ (_find_in_config_paths , "CONFIG_PATHS" ),
205
+ (_find_in_ld_path , "LD_PATH" ),
206
+ (_find_in_sys , "SYS" ),
207
+ (_find_in_ctypes_util , "CTYPES_UTIL" ),
208
+ )
209
+ sources_filtered = (
210
+ source_clb
211
+ for source_clb , source_name in sources
212
+ if os .environ .get (f"FINDLIBS_DISABLE_{ source_name } " , None ) != "yes"
213
+ )
214
+
215
+ for source in sources_filtered :
216
+ if result := source (lib_name , pkg_name ):
192
217
return result
193
218
return None
0 commit comments