Use consistent spacing in tox variables and lists
[mudpy.git] / mudpy / version.py
index 0b4ad79..d99617e 100644 (file)
@@ -1,20 +1,32 @@
 """Version and diagnostic information for the mudpy engine."""
 
-# Copyright (c) 2018 mudpy authors. Permission to use, copy,
+# Copyright (c) 2018-2020 mudpy authors. Permission to use, copy,
 # modify, and distribute this software is granted under terms
 # provided in the LICENSE file distributed with this software.
 
 import json
-import pkg_resources
 import sys
 
 
+# TODO(fungi) Clean up once Python 3.8 is the oldest interpreter supported
+try:
+    import importlib.metadata
+    use_importlib = True
+except ModuleNotFoundError:
+    import pkg_resources
+    use_importlib = False
+
+
 class VersionDetail:
 
     """Version detail for a Python package."""
 
     def __init__(self, package):
-        self.project_name = _normalize_project(package.project_name)
+        if use_importlib:
+            project_name = package.metadata.get('Name')
+        else:
+            project_name = package.project_name
+        self.project_name = _normalize_project(project_name)
         version = package.version
         self.version_info = tuple(version.split('.'))
 
@@ -22,13 +34,23 @@ class VersionDetail:
         self.text = "%s %s" % (self.project_name, version)
 
         # Obtain Git commit ID from PBR metadata if present
-        dist = pkg_resources.get_distribution(self.project_name)
+        if use_importlib:
+            dist = importlib.metadata.distribution(self.project_name)
+        else:
+            dist = pkg_resources.get_distribution(self.project_name)
         try:
-            self.git_version = json.loads(
-                dist.get_metadata("pbr.json"))["git_version"]
-            self.text = "%s (%s)" % (self.text, self.git_version)
+            if use_importlib:
+                pbr_metadata = dist.read_text("pbr.json")
+            else:
+                pbr_metadata = dist.get_metadata("pbr.json")
         except (IOError, KeyError):
+            pbr_metadata = None
+        if pbr_metadata:
+            self.git_version = json.loads(pbr_metadata)["git_version"]
+        else:
             self.git_version = None
+        if self.git_version:
+            self.text = "%s (%s)" % (self.text, self.git_version)
 
     def __repr__(self):
         return self.text
@@ -48,15 +70,23 @@ class Versions:
 
         # List of package names for this package's declared dependencies
         requirements = []
-        for package in pkg_resources.get_distribution(project_name).requires():
-            requirements.append(_normalize_project(package.project_name))
+        if use_importlib:
+            for req in importlib.metadata.distribution(project_name).requires:
+                requirements.append(_normalize_project(req))
+        else:
+            for req in pkg_resources.get_distribution(project_name).requires():
+                requirements.append(_normalize_project(req.project_name))
 
         # Accumulators for Python package versions
         self.dependencies = {}
         self.environment = {}
 
         # Loop over all installed packages
-        for package in pkg_resources.working_set:
+        if use_importlib:
+            distributions = importlib.metadata.distributions()
+        else:
+            distributions = pkg_resources.working_set
+        for package in distributions:
             version = VersionDetail(package)
             # Sort packages into the corresponding buckets
             if version.project_name in requirements:
@@ -84,4 +114,7 @@ class Versions:
 
 def _normalize_project(project_name):
     """Convenience function to normalize Python project names."""
-    return pkg_resources.safe_name(project_name).lower()
+    if use_importlib:
+        return project_name.lower()
+    else:
+        return pkg_resources.safe_name(project_name).lower()