Skip to content

Commit

Permalink
Merge pull request #4215 from pypa/bugfix/4167-egg-link-mangling
Browse files Browse the repository at this point in the history
Restore egg link names with dashes for now
  • Loading branch information
jaraco authored Feb 12, 2024
2 parents 9cbe157 + ac20e42 commit 115d381
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 7 deletions.
20 changes: 14 additions & 6 deletions docs/deprecated/python_eggs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,12 @@ egg filename is as follows::

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

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

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

Note: Due to `pypa/setuptools#4167
<https://github.com/pypa/setuptools/issues/4167>`_, the name in the egg-link
filename does not match the filename components used in similar files, but
instead presents with dash separators instead of underscore separators. For
compatibility with pip prior to version 24.0, these dash separators are
retained. In a future release, pip 24 or later will be required and the
underscore separators will be used.

Each ``.egg-link`` file should contain a single file or directory name,
with no newlines. This filename should be the base location of one or
more eggs. That is, the name must either end in ``.egg``, or else it
Expand Down
1 change: 1 addition & 0 deletions newsfragments/4167.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Restored expectation that egg-link files would be named with dash separators for compatibility with pip prior to version 24.
15 changes: 15 additions & 0 deletions setuptools/_normalization.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,21 @@ def filename_component(value: str) -> str:
return value.replace("-", "_").strip("_")


def filename_component_broken(value: str) -> str:
"""
Produce the incorrect filename component for compatibility.
See pypa/setuptools#4167 for detailed analysis.
TODO: replace this with filename_component after pip 24 is
nearly-ubiquitous.
>>> filename_component_broken('foo_bar-baz')
'foo-bar-baz'
"""
return value.replace('_', '-')


def safer_name(value: str) -> str:
"""Like ``safe_name`` but can be used as filename component for wheel"""
# See bdist_wheel.safer_name
Expand Down
5 changes: 4 additions & 1 deletion setuptools/command/develop.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import glob

from setuptools.command.easy_install import easy_install
from setuptools import _normalization
from setuptools import _path
from setuptools import namespaces
import setuptools
Expand Down Expand Up @@ -52,7 +53,9 @@ def finalize_options(self):
# pick up setup-dir .egg files only: no .egg-info
self.package_index.scan(glob.glob('*.egg'))

egg_link_fn = ei.egg_name + '.egg-link'
egg_link_fn = (
_normalization.filename_component_broken(ei.egg_name) + '.egg-link'
)
self.egg_link = os.path.join(self.install_dir, egg_link_fn)
self.egg_base = ei.egg_base
if self.egg_path is None:
Expand Down
13 changes: 13 additions & 0 deletions setuptools/tests/test_develop.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import os
import sys
import subprocess
import pathlib
import platform

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

@pytest.mark.xfail(reason="legacy behavior retained for compatibility #4167")
def test_egg_link_filename(self):
settings = dict(
name='Foo $$$ Bar_baz-bing',
)
dist = Distribution(settings)
cmd = develop(dist)
cmd.ensure_finalized()
link = pathlib.Path(cmd.egg_link)
assert link.suffix == '.egg-link'
assert link.stem == 'Foo_Bar_baz_bing'


class TestResolver:
"""
Expand Down

0 comments on commit 115d381

Please sign in to comment.