"""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.6 is the oldest interpreter supported
+if not hasattr(__builtins__, 'ModuleNotFoundError'):
+ ModuleNotFoundError = ImportError
+# 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('.'))
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
# 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:
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()