From 8bc7b06fb18b2ce2bfbdd32fd36a1372aaf538fc Mon Sep 17 00:00:00 2001 From: kba Date: Thu, 7 May 2026 15:07:19 +0200 Subject: [PATCH 1/3] replace pkg_resource with importlib{_,.}{metadata,resources} --- dev-requirements.txt | 1 + requirements.txt | 2 ++ sacred/dependencies.py | 38 +++++++++++--------- sacred/observers/mongo.py | 7 ++-- tests/test_observers/test_tinydb_observer.py | 2 +- 5 files changed, 30 insertions(+), 20 deletions(-) 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..f5542b8c 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.8' +importlib_resources ; python_version < '3.10' diff --git a/sacred/dependencies.py b/sacred/dependencies.py index 8470c048..c5bf524c 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, 8): + 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 From 266798f3b82353fdb2b2d3970218d6ca47648045 Mon Sep 17 00:00:00 2001 From: kba Date: Mon, 11 May 2026 10:04:20 +0200 Subject: [PATCH 2/3] importlib_metadata for Python < 3.11 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f5542b8c..59562d92 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,5 +6,5 @@ py-cpuinfo>=4.0 colorama>=0.4 packaging>=18.0 GitPython -importlib_metadata ; python_version < '3.8' +importlib_metadata ; python_version < '3.11' importlib_resources ; python_version < '3.10' From 6c1aef991dacacd20ff7874371cbb58255a8bce4 Mon Sep 17 00:00:00 2001 From: kba Date: Mon, 11 May 2026 12:54:06 +0200 Subject: [PATCH 3/3] use importlib_metadata replacement for Python < 3.11 --- sacred/dependencies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sacred/dependencies.py b/sacred/dependencies.py index c5bf524c..9760b1b7 100644 --- a/sacred/dependencies.py +++ b/sacred/dependencies.py @@ -13,7 +13,7 @@ else: import importlib.resources as importlib_resources -if sys.version_info < (3, 8): +if sys.version_info < (3, 11): import importlib_metadata else: import importlib.metadata as importlib_metadata