@@ -255,11 +255,9 @@ def from_package_metadata(cls, package_name: str) -> Software:
255255 :
256256 A Software instance.
257257 """
258- from importlib .metadata import version
259-
260258 return cls (
261259 name = package_name ,
262- version = version (package_name ),
260+ version = _deduce_package_version (package_name ),
263261 url = _deduce_package_source_url (package_name ),
264262 doi = None ,
265263 )
@@ -277,10 +275,39 @@ def compact_repr(self) -> str:
277275 return self .name_version
278276
279277
278+ def _deduce_package_version (package_name : str ) -> str | None :
279+ from importlib .metadata import PackageNotFoundError , version
280+
281+ try :
282+ return version (package_name )
283+ except PackageNotFoundError :
284+ # Either the package is not installed or has no metadata.
285+ from importlib import import_module
286+
287+ try :
288+ package = import_module (package_name )
289+ except ModuleNotFoundError as e :
290+ raise e from None
291+
292+ try :
293+ return package .__version__
294+ except AttributeError :
295+ raise RuntimeError (
296+ f"Package '{ package_name } ' has no metadata and no "
297+ f"__version__ attribute. Specify the version manually."
298+ ) from None
299+
300+
280301def _deduce_package_source_url (package_name : str ) -> str | None :
281- from importlib .metadata import metadata
302+ from importlib .metadata import PackageNotFoundError , metadata
303+
304+ try :
305+ meta = metadata (package_name )
306+ except PackageNotFoundError :
307+ # Either the package is not installed or has no metadata.
308+ return None
282309
283- if not (urls := metadata ( package_name ) .get_all ("project-url" )):
310+ if not (urls := meta .get_all ("project-url" )):
284311 return None
285312
286313 try :
0 commit comments