diff --git a/dev-requirements.txt b/dev-requirements.txt index 1bc726c0..202cdfbe 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,4 +1,5 @@ pytest==7.1.2 # tests/test_utils.py depends on that pytest version is exactly 7.1.2 +pytest-cov colorama docopt-ng gitdb2 diff --git a/requirements.txt b/requirements.txt index f53b9b0a..59562d92 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,5 @@ py-cpuinfo>=4.0 colorama>=0.4 packaging>=18.0 GitPython +importlib_metadata ; python_version < '3.11' +importlib_resources ; python_version < '3.10' diff --git a/sacred/dependencies.py b/sacred/dependencies.py index 8470c048..9760b1b7 100644 --- a/sacred/dependencies.py +++ b/sacred/dependencies.py @@ -8,7 +8,15 @@ import sys from pathlib import Path -import pkg_resources +if sys.version_info < (3, 10): + import importlib_resources +else: + import importlib.resources as importlib_resources + +if sys.version_info < (3, 11): + import importlib_metadata +else: + import importlib.metadata as importlib_metadata import sacred.optional as opt from sacred import SETTINGS @@ -226,7 +234,6 @@ "pickletools", "pip", "pipes", - "pkg_resources", "pkgutil", "platform", "plistlib", @@ -261,7 +268,6 @@ "ScrolledText", "selectors", "sets", - "setuptools", "sgmllib", "sha", "shelve", @@ -498,8 +504,10 @@ def __init__(self, name, version): def fill_missing_version(self): if self.version is not None: return - dist = pkg_resources.working_set.by_key.get(self.name) - self.version = dist.version if dist else None + try: + self.version = importlib_metadata.distribution(self.name).version + except importlib_metadata.PackageNotFoundError: + self.version = None def to_json(self): return "{}=={}".format(self.name, self.version or "") @@ -523,14 +531,12 @@ def __repr__(self): def create(cls, mod): if not cls.modname_to_dist: # some packagenames don't match the module names (e.g. PyYAML) - # so we set up a dict to map from module name to package name - for dist in pkg_resources.working_set: - try: - toplevel_names = dist._get_metadata("top_level.txt") - for tln in toplevel_names: - cls.modname_to_dist[tln] = dist.project_name, dist.version - except Exception: - pass + # so we use the packages_distributions() mapping provided by importlib_metadata + cls.modname_to_dist = { + m: (dist, importlib_metadata.distribution(dist).version) + for m, dists in importlib_metadata.packages_distributions().items() + for dist in dists + } name, version = cls.modname_to_dist.get(mod.__name__, (mod.__name__, None)) @@ -701,10 +707,8 @@ def get_dependencies_from_imported_modules(globs, base_path): def get_dependencies_from_pkg(globs, base_path): dependencies = set() - for dist in pkg_resources.working_set: - if dist.version == "0.0.0": - continue # ugly hack to deal with pkg-resource version bug - dependencies.add(PackageDependency(dist.project_name, dist.version)) + for dist in importlib_metadata.distributions(): + dependencies.add(PackageDependency(dist.name, dist.version)) return dependencies diff --git a/sacred/observers/mongo.py b/sacred/observers/mongo.py index 7c6a90e9..3d00e025 100644 --- a/sacred/observers/mongo.py +++ b/sacred/observers/mongo.py @@ -7,6 +7,10 @@ import time from tempfile import NamedTemporaryFile import warnings +if sys.version_info < (3, 10): + import importlib_resources +else: + import importlib.resources as importlib_resources import sacred.optional as opt from sacred.commandline_options import cli_option @@ -15,13 +19,12 @@ from sacred.observers.queue import QueueObserver from sacred.serializer import flatten from sacred.utils import ObserverError, PathType -import pkg_resources DEFAULT_MONGO_PRIORITY = 30 # This ensures consistent mimetype detection across platforms. mimetype_detector = mimetypes.MimeTypes( - filenames=[pkg_resources.resource_filename("sacred", "data/mime.types")] + filenames=[str(importlib_resources.files("sacred") / "data/mime.types")] ) diff --git a/tests/test_observers/test_tinydb_observer.py b/tests/test_observers/test_tinydb_observer.py index 0e72b263..d65e8242 100644 --- a/tests/test_observers/test_tinydb_observer.py +++ b/tests/test_observers/test_tinydb_observer.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# coding=utf-8 from __future__ import division, print_function, unicode_literals, absolute_import +# coding=utf-8 import os import datetime