Skip to content

Commit 26c9b1b

Browse files
authored
Fallback method for gathering package version numbers (#11)
1 parent 6b10e39 commit 26c9b1b

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

processinghistory/history.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@
3838
import time
3939
import zlib
4040
import base64
41+
try:
42+
import importlib.metadata
43+
HAVE_IMPLIB_METADATA = True
44+
except ImportError:
45+
HAVE_IMPLIB_METADATA = False
4146

4247
from osgeo import gdal
4348

@@ -176,14 +181,57 @@ def makeAutomaticFields():
176181
moduleVersionDict[toplevelModname] = "Unknown"
177182

178183
if len(moduleVersionDict) > 0:
179-
for modname in moduleVersionDict:
184+
moduleVersionDictKeys = list(moduleVersionDict.keys())
185+
for modname in moduleVersionDictKeys:
180186
if hasattr(sys.modules[modname], '__version__'):
181187
moduleVersionDict[modname] = str(sys.modules[modname].__version__)
188+
else:
189+
(distributionName, verStr) = versionFromDistribution(modname)
190+
if None not in (distributionName, verStr):
191+
moduleVersionDict[distributionName] = verStr
192+
# If distribution name is different, remove modname
193+
if modname != distributionName:
194+
moduleVersionDict.pop(modname)
195+
182196
dictn['package_version_dict'] = json.dumps(moduleVersionDict)
183197

184198
return dictn
185199

186200

201+
def versionFromDistribution(modname):
202+
"""
203+
If possible, deduce a package version number for the given
204+
module/package name, using distribution metadata.
205+
206+
If available, return a tuple of (distributionName, versionStr)
207+
Note that the distribution name may not be the same as the
208+
module or package name.
209+
210+
If unavailable for any reason, return (None, None).
211+
212+
"""
213+
nullReturn = (None, None)
214+
215+
# The importlib.metadata module was only introduced in Python 3.8
216+
if not HAVE_IMPLIB_METADATA:
217+
return nullReturn
218+
pkgs = importlib.metadata.packages_distributions()
219+
distNameList = pkgs.get(modname)
220+
if distNameList is None:
221+
return nullReturn
222+
if len(distNameList) == 0:
223+
return nullReturn
224+
distName = distNameList[0]
225+
try:
226+
verStr = importlib.metadata.version(distName)
227+
except importlib.metadata.PackageNotFoundError:
228+
verStr = None
229+
if verStr is None:
230+
return nullReturn
231+
232+
return (distName, verStr)
233+
234+
187235
def writeHistoryToFile(userDict={}, parents=[], *, filename=None, gdalDS=None):
188236
"""
189237
Make the full processing history and save to the given file.

processinghistory/tests.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ def test_singleFile(self):
7676
self.assertIn(k, metadict,
7777
msg=f"Automatic key {k} missing (driver={drvrName})")
7878

79+
pkgVerDict = metadict['package_version_dict']
80+
for pkg in ['processinghistory', 'osgeo', 'numpy']:
81+
self.assertIn(pkg, pkgVerDict,
82+
msg=f"Expected '{pkg}' in package_version_dict, not found")
83+
self.assertNotIn('_distutils_hack', pkgVerDict,
84+
msg=("Found _distutils_hack in package_version_dict, " +
85+
"should be recorded as setuptools"))
86+
7987
self.deleteTempFiles(tmpfileList)
8088

8189
def test_ancestry(self):

0 commit comments

Comments
 (0)