From e598d8c1a1cb12389366cb8fa774300a2a1bf487 Mon Sep 17 00:00:00 2001 From: Maurits van Rees Date: Wed, 4 Jun 2025 17:59:29 +0200 Subject: [PATCH] Fix ModuleNotFoundError with setuptools 80.2.0 or higher. Sample error: ``` .tox/py312/lib/python3.12/site-packages/mr/developer/extension.py:2: in from setuptools.package_index import safe_name E ModuleNotFoundError: No module named 'setuptools.package_index' ``` `setuptools` 80.2.0 removes the `package_index` module. When it still existed, this actually imported `safe_name` from `pkg_resources`. This may depend on the setuptools version as well, and `pkg_resources` will be removed at the end of the year. So I copied the only thing we needed: the `safe_name` function. --- CHANGES.rst | 3 ++- src/mr/developer/extension.py | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 3e416b5f..bc967dc1 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,8 @@ Changelog 2.0.3 (unreleased) ------------------ -- Nothing changed yet. +- Fix ``ModuleNotFoundError`` when trying to import ``safe_name`` from ``setuptools`` 80.2.0 or higher. + [maurits] 2.0.2 (2024-04-24) diff --git a/src/mr/developer/extension.py b/src/mr/developer/extension.py index d37594ac..4e285ae0 100644 --- a/src/mr/developer/extension.py +++ b/src/mr/developer/extension.py @@ -1,5 +1,4 @@ from mr.developer.common import memoize, WorkingCopies, Config, get_workingcopytypes -from setuptools.package_index import safe_name import logging import os import re @@ -11,6 +10,17 @@ logger = logging.getLogger("mr.developer") +def safe_name(name: str) -> str: + """Convert an arbitrary string to a standard distribution name + + Any runs of non-alphanumeric/. characters are replaced with a single '-'. + + This is copied from pkg_resources.safe_name. + (formerly setuptools.package_index.safe_name) + """ + return re.sub('[^A-Za-z0-9.]+', '-', name) + + class Source(dict): def exists(self): return os.path.exists(self['path'])