Skip to content

Commit 115d381

Browse files
authored
Merge pull request #4215 from pypa/bugfix/4167-egg-link-mangling
Restore egg link names with dashes for now
2 parents 9cbe157 + ac20e42 commit 115d381

File tree

5 files changed

+47
-7
lines changed

5 files changed

+47
-7
lines changed

docs/deprecated/python_eggs.rst

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,12 @@ egg filename is as follows::
131131

132132
name ["-" version ["-py" pyver ["-" required_platform]]] "." ext
133133

134-
The "name" and "version" should be escaped using the ``to_filename()``
135-
function provided by ``pkg_resources``, after first processing them with
136-
``safe_name()`` and ``safe_version()`` respectively. These latter two
137-
functions can also be used to later "unescape" these parts of the
138-
filename. (For a detailed description of these transformations, please
139-
see the "Parsing Utilities" section of the ``pkg_resources`` manual.)
134+
The "name" and "version" should be escaped using ``pkg_resources`` functions
135+
``safe_name()`` and ``safe_version()`` respectively then using
136+
``to_filename()``. Note that the escaping is irreversible and the original
137+
name can only be retrieved from the distribution metadata. For a detailed
138+
description of these transformations, please see the "Parsing Utilities"
139+
section of the ``pkg_resources`` manual.
140140

141141
The "pyver" string is the Python major version, as found in the first
142142
3 characters of ``sys.version``. "required_platform" is essentially
@@ -193,6 +193,14 @@ Python version, or platform information is included. When the runtime
193193
searches for available eggs, ``.egg-link`` files are opened and the
194194
actual egg file/directory name is read from them.
195195

196+
Note: Due to `pypa/setuptools#4167
197+
<https://github.com/pypa/setuptools/issues/4167>`_, the name in the egg-link
198+
filename does not match the filename components used in similar files, but
199+
instead presents with dash separators instead of underscore separators. For
200+
compatibility with pip prior to version 24.0, these dash separators are
201+
retained. In a future release, pip 24 or later will be required and the
202+
underscore separators will be used.
203+
196204
Each ``.egg-link`` file should contain a single file or directory name,
197205
with no newlines. This filename should be the base location of one or
198206
more eggs. That is, the name must either end in ``.egg``, or else it

newsfragments/4167.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Restored expectation that egg-link files would be named with dash separators for compatibility with pip prior to version 24.

setuptools/_normalization.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,21 @@ def filename_component(value: str) -> str:
120120
return value.replace("-", "_").strip("_")
121121

122122

123+
def filename_component_broken(value: str) -> str:
124+
"""
125+
Produce the incorrect filename component for compatibility.
126+
127+
See pypa/setuptools#4167 for detailed analysis.
128+
129+
TODO: replace this with filename_component after pip 24 is
130+
nearly-ubiquitous.
131+
132+
>>> filename_component_broken('foo_bar-baz')
133+
'foo-bar-baz'
134+
"""
135+
return value.replace('_', '-')
136+
137+
123138
def safer_name(value: str) -> str:
124139
"""Like ``safe_name`` but can be used as filename component for wheel"""
125140
# See bdist_wheel.safer_name

setuptools/command/develop.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import glob
66

77
from setuptools.command.easy_install import easy_install
8+
from setuptools import _normalization
89
from setuptools import _path
910
from setuptools import namespaces
1011
import setuptools
@@ -52,7 +53,9 @@ def finalize_options(self):
5253
# pick up setup-dir .egg files only: no .egg-info
5354
self.package_index.scan(glob.glob('*.egg'))
5455

55-
egg_link_fn = ei.egg_name + '.egg-link'
56+
egg_link_fn = (
57+
_normalization.filename_component_broken(ei.egg_name) + '.egg-link'
58+
)
5659
self.egg_link = os.path.join(self.install_dir, egg_link_fn)
5760
self.egg_base = ei.egg_base
5861
if self.egg_path is None:

setuptools/tests/test_develop.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import os
44
import sys
55
import subprocess
6+
import pathlib
67
import platform
78

89
from setuptools.command import test
@@ -82,6 +83,18 @@ def test_console_scripts(self, tmpdir):
8283
cmd.run()
8384
# assert '0.0' not in foocmd_text
8485

86+
@pytest.mark.xfail(reason="legacy behavior retained for compatibility #4167")
87+
def test_egg_link_filename(self):
88+
settings = dict(
89+
name='Foo $$$ Bar_baz-bing',
90+
)
91+
dist = Distribution(settings)
92+
cmd = develop(dist)
93+
cmd.ensure_finalized()
94+
link = pathlib.Path(cmd.egg_link)
95+
assert link.suffix == '.egg-link'
96+
assert link.stem == 'Foo_Bar_baz_bing'
97+
8598

8699
class TestResolver:
87100
"""

0 commit comments

Comments
 (0)