# Killing off the \`egg=\` fragment once and for all?

**URL:** <https://discuss.python.org/t/killing-off-the-egg-fragment-once-and-for-all/21660>\
**Category:** Packaging\
**Created:** [December 5, 2022, 6:15am UTC](https://discuss.python.org/t/killing-off-the-egg-fragment-once-and-for-all/21660 "2022-12-05T06:15:24Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![woodruffw](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/woodruffw/32/37228_2.png) [@woodruffw](https://discuss.python.org/u/woodruffw)\
**Post date:** [December 5, 2022, 6:15am UTC](https://discuss.python.org/t/killing-off-the-egg-fragment-once-and-for-all/21660/1 "2022-12-05T06:15:24Z")

</div>

I’m proposing this to the packaging community, with the hopes of getting thoughts and feedback. I’m interested to hear what you all think!

## Background

The `egg=` fragment is one of two ways to specify the name of a package in a requirement specifier that doesn’t “natively” contain the package name (e.g. a URL, where the base component of the URL may not match the project’s name).

For example, here’s how you can tell `pip` that a URL requirement installs package `foo`:

```plaintext
git+https://github.com/some-org/some-repo.git@some-rev#egg=foo

```

This is equivalent, as far as I can tell, to the preferred requirement syntax:

```plaintext
foo @ git+https://github.com/some-org/some-repo.git@some-rev

```

## Motivation

The `egg=` fragment is only weakly specified, and currently enables some surprising behavior:

1. The value of the `egg` fragment is parsed as a requirement in its own right, meaning that the following happily parses:

2. It isn’t immediately clear what a requirement like this does:

## Proposed solution

Deprecate `egg=` fragment support entirely, and eventually remove it from `pip` and related tools.

If I’m correct (and I might not be!), then `egg=` is _entirely_ vestigial in the current packaging ecosystem: it’s functionally equivalent to the less ambiguous and easier to parse `name @ url` syntax, is (currently) poorly specified, and references a long obsoleted packaging format (Eggs).

## Further context

I currently have a PR open ([https://github.com/pypa/pip/pull/11617](https://github.com/pypa/pip/pull/11617)) on `pip` to refine `pip`’s existing behavior around `egg=` fragments: the current surprising behavior around extras is being deprecated, with the current plan being to remove it after two full releases.

---

<div class="post-metadata">

**Author:** ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)\
**Post date:** [December 5, 2022, 9:58am UTC](https://discuss.python.org/t/killing-off-the-egg-fragment-once-and-for-all/21660/2 "2022-12-05T09:58:03Z")

</div>

It would be great if `pip` could start showing deprecation warnings that would include how the specifier would be rewritten using `foo @` – both to encourage updating and to verify how `pip` parsed ambiguous input.

Is far as I can see, the `egg` fragment is not part of the [standard](https://packaging.python.org/en/latest/specifications/dependency-specifiers/), so, it _is_ vestigial and limited to tools that need to work with older conventions. But, `pip` is one of those tools. If these specifiers are on PyPI or in popular `requirements.txt` files, I don’t think two `pip` releases is long enough as a deprecation period.  
I wouldn’t be surprised if places we “can’t see” – outside PyPI – used this syntax much more commonly than public code.

Can/does PyPI disallow uploading packages with non-standard specifiers?

---

<div class="post-metadata">

**Author:** ![fungi](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/fungi/32/5963_2.png) [@fungi](https://discuss.python.org/u/fungi)\
**Post date:** [December 5, 2022, 1:38pm UTC](https://discuss.python.org/t/killing-off-the-egg-fragment-once-and-for-all/21660/3 "2022-12-05T13:38:44Z")

</div>

How long ago did pip’s parser gain suppport for the foo@ syntax? Not  
all users will (or can) upgrade to the latest versions of pip, and  
many use the what’s provided by their stable server distributions  
which may be many years old.

Some projects I work on try not to alienate those users and would  
likely include both foo@ and #egg=foo together in order to support a  
broader range of pip vintages. It may make sense to not print such  
deprecation warnings in situations where both package name  
indicators are present and contain the same value.

---

<div class="post-metadata">

**Author:** ![woodruffw](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/woodruffw/32/37228_2.png) [@woodruffw](https://discuss.python.org/u/woodruffw)\
**Post date:** [December 5, 2022, 5:14pm UTC](https://discuss.python.org/t/killing-off-the-egg-fragment-once-and-for-all/21660/4 "2022-12-05T17:14:59Z")

</div>

> [@encukou](#):
>
> It would be great if `pip` could start showing deprecation warnings that would include how the specifier would be rewritten using `foo @` – both to encourage updating and to verify how `pip` parsed ambiguous input.

Agreed – the PR I currently have open only nudges users towards the `name @ ...` syntax, but a full deprecation of the `egg=` fragment should provide the exact equivalent replacement so that a user could drop it in.

> [@encukou](#):
>
> If these specifiers are on PyPI or in popular `requirements.txt` files, I don’t think two `pip` releases is long enough as a deprecation period.

Just to clarify: the “two releases” in the top-level comment doesn’t refer to this proposal, but to the current PR open (which doesn’t remove the `egg=` fragment at all). The current PR only restricts the `egg=` fragment to valid PEP 508 project identifiers, which should have far less impact 🙂

I 100% agree that two releases wouldn’t be enough of a period for a full deprecation/removal of the `egg=` fragment!

> [@encukou](#):
>
> Can/does PyPI disallow uploading packages with non-standard specifiers?

I don’t believe it’s something that PyPI can check for in the general case, unfortunately, since doing so would require executing arbitrary `setup.py` code to grab the requries metadata.

> [@fungi](#):
>
> How long ago did pip’s parser gain suppport for the foo@ syntax? Not  
> all users will (or can) upgrade to the latest versions of pip, and  
> many use the what’s provided by their stable server distributions  
> which may be many years old.

I’ll find a more precise answer in a bit, but `pip` probably gained `name @ url` support around 2015, since that’s when PEP 508 was finalized. So, roughly 7-8 years most likely.

---

<div class="post-metadata">

**Author:** ![hugovk](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/hugovk/32/14505_2.png) [@hugovk](https://discuss.python.org/u/hugovk)\
**Post date:** [December 5, 2022, 5:16pm UTC](https://discuss.python.org/t/killing-off-the-egg-fragment-once-and-for-all/21660/5 "2022-12-05T17:16:30Z")

</div>

> [@encukou](#):
>
> If these specifiers are on PyPI or in popular `requirements.txt` files, I don’t think two `pip` releases is long enough as a deprecation period.

Searching sdists of the top 5k projects (4,753 had sdists, 2022-11-02):

- found 1,061 matching lines in 154 projects:
  - 231 in `requirements.*txt`
  - 51 in `tox.ini`

Searching for `#egg=` on GitHub, there are:

- [19k results](https://cs.github.com/?scopeName=All+repos&scope=&q=%2F%23egg%3D%2F+path%3Arequirements.txt) in `*requirements.txt` files
- [2.1k results](https://cs.github.com/?scopeName=All+repos&scope=&q=%2F%23egg%3D%2F+path%3Atox.ini) in `tox.ini` files

---

<div class="post-metadata">

**Author:** ![pradyunsg](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pradyunsg/32/206_2.png) [@pradyunsg](https://discuss.python.org/u/pradyunsg)\
**Post date:** [December 6, 2022, 8:40am UTC](https://discuss.python.org/t/killing-off-the-egg-fragment-once-and-for-all/21660/6 "2022-12-06T08:40:12Z")

</div>

FWIW, to confirm: `#egg` support in pip is vestigial, from before PEP 508. PEP 508’s URL requirements format support was added in pip 18.1 (2018-10-05).

I’m in favour of removing all special casing we have around #egg within pip, including around some places where pip presents data it has using that. I do think it would make sense to also error out on requirements with #egg in them, at some point in the future but we should start by clearing out the special casing and replacing it with a warning.

---

<div class="post-metadata">

**Author:** ![fungi](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/fungi/32/5963_2.png) [@fungi](https://discuss.python.org/u/fungi)\
**Post date:** [December 6, 2022, 12:43pm UTC](https://discuss.python.org/t/killing-off-the-egg-fragment-once-and-for-all/21660/7 "2022-12-06T12:43:22Z")

</div>

Projects I work on are definitely still making new releases (for bug  
fixes from stable branches) consumed by users of older versions of  
pip than that. Ubuntu Bionic (18.04 LTS) carries python3-pip 9.0.1  
for example. Our projects likely need to come up with a workaround  
in order to support both users with pip too old to safely parse foo@  
syntax while also supporting users with new enough pip that it  
doesn’t respect the #egg=foo syntax. I’m guessing we could make it  
work with forked requirements files for old vs new pip, but will  
need to look into our options.

At the very least I need to light a fire under the other developers  
to start replacing all the old syntax in our newer branches, a quick  
search turns up around a thousand occurrences across hundreds of our  
repositories just in master branches alone (not only requirements  
files and tox configs, but in integration testing scripts,  
configuration management, documentation, and so on). I don’t think  
any of them saw this coming, but probably should have.

---

<div class="post-metadata">

**Author:** ![hugovk](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/hugovk/32/14505_2.png) [@hugovk](https://discuss.python.org/u/hugovk)\
**Post date:** [December 10, 2022, 2:47pm UTC](https://discuss.python.org/t/killing-off-the-egg-fragment-once-and-for-all/21660/8 "2022-12-10T14:47:44Z")

</div>

See also:

> [@Should PyPI deprecate .egg uploads?](https://discuss.python.org/t/should-pypi-deprecate-egg-uploads/13364):
>
> In [https://github.com/pypa/warehouse/issues/10653](https://github.com/pypa/warehouse/issues/10653) I’m proposing to stop PyPI from accepting uploads of .egg distributions. TL;DR, many tools have deprecated or dropped support for eggs, and overall wheels have far outpaced eggs in terms of uploads: [image] Comments are welcome here or on the GitHub issue. I’d especially like to hear from anyone still building or installing eggs, or maintainers of projects that still support eggs:

![chart of PyPI uploads: exponential wheels growth, eggs are flat](https://us1.discourse-cdn.com/flex002/uploads/python1/original/2X/a/a7b1775d8d602138496fc63b96e057bf1d6a90e5.png)

---

<div class="post-metadata">

**Author:** ![ChrisBarker-NOAA](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/chrisbarker-noaa/32/17339_2.png) [@ChrisBarker-NOAA](https://discuss.python.org/u/ChrisBarker-NOAA)\
**Post date:** [May 6, 2024, 6:13pm UTC](https://discuss.python.org/t/killing-off-the-egg-fragment-once-and-for-all/21660/9 "2024-05-06T18:13:16Z")

</div>

Commenting on a very old thread, i know – but apparently it hasn’t happened yet (killing #egg).

Note: the documentation is very sparse for the `package_name@` syntax – I hadn’t done this in a while, and found a bunch of (not all that old) info about using `#egg=`, but suspected that should have been long ago deprecated, but a fair bit of searching didn’t find the more modern solution.

This thread is where I eventually found it.

So; yes, a depreciation warning sooner than later is good, and perhaps a reveiw of docs to make sure the @ sytax is well documented.
