Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PEP 660 (build_editable) support #8212

Merged
merged 3 commits into from
Sep 29, 2021
Merged

Conversation

sbidoul
Copy link
Member

@sbidoul sbidoul commented May 9, 2020

I wanted to experiment a little bit too with the build_wheel_for_editable concept, just to see how well it fits in the pip code base. I'm sharing in case anyone is interested. This is totally draft and not well tested.

  • install --editable
    • backend has build_wheel_for_editable
    • backend does not have build_wheel_for_editable - fallback to setup.py develop
    • backend does not have build_wheel_for_editable - error if no setup.py
    • update to latest PEP 660
    • support get_requires_for_build_editable
    • support prepare_metadata_for_editable
    • fallback if hook not present
    • make sure pip wheel -e does not use any editable hook
  • uninstall
  • update pip freeze (done in Support PEP 610 editables in pip freeze and pip list #10249)
  • update pip list (done in Support PEP 610 editables in pip freeze and pip list #10249)
  • in log message Building wheel for * (PEP 517) ... done, mention we are in editable mode?

Copy link
Member

@dholth dholth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does it interact with caching and out of tree builds?

@sbidoul
Copy link
Member Author

sbidoul commented May 10, 2020

How does it interact with caching

Caching should be fine when #8145 is merged. I cherry picked it here for clarity and added a few should_build/should_cache unit tests for the editable+pep517 combination.

and out of tree builds?

That should be ok, since the part that does the copytree is never reached for editable requirements.

@dholth
Copy link
Member

dholth commented May 10, 2020

Do you have an opinion on passing the target directory to the build so that it can use relative paths to find the real editable module?

@sbidoul
Copy link
Member Author

sbidoul commented May 10, 2020

Do you have an opinion on passing the target directory to the build so that it can use relative paths to find the real editable module?

I'm personally not opposed to it as I'm not too concerned with having a pure backend/frontend interface for editables. But I guess this would quickly be abused by backends to fiddle inside the target directory.

OTOH my view of editable installs is that they are for development only, so in that scenario absolute paths are probably less of an issue?

@dholth
Copy link
Member

dholth commented May 10, 2020

The 'editable' name or a linked install is better than the 'setup.py develop' name. Packaging provides a feature but shouldn't try to restrict what it is used for.

@sbidoul
Copy link
Member Author

sbidoul commented May 12, 2020

This PR is now somewhat usable. I tested it with a custom backend.

@pfmoore
Copy link
Member

pfmoore commented May 12, 2020

Personally, I still prefer the approach where the backend builds a wheel that installs just like any other wheel but the installed code links back to the source directory. This gives editable support with essentially no support code in pip.

Basic implementation is here. It needs fleshing out to make it into a library that backends can use, I plan on doing that when I have more free time.

@dholth
Copy link
Member

dholth commented May 12, 2020

@pfmoore this could hardly be closer to what you prefer, depending entirely on what the backend decides to put in that wheel.

@pfmoore
Copy link
Member

pfmoore commented May 12, 2020

@dholth Whoops, you're right. I think I was getting confused with another one of the proposals. I'm way too tired, and I need to stop posting now, I think.

Apologies for the confusion, and thanks @sbidoul for this! I'll have a proper look when I'm not half asleep 😴

@ofek
Copy link
Contributor

ofek commented Jul 5, 2020

@sbidoul I'm writing a PEP 517 backend for Hatch. Can you explain what build_wheel_for_editable should do?

@pfmoore
Copy link
Member

pfmoore commented Jul 5, 2020

@ofek If you look at editables that's the basic idea - the backend can use that to build a wheel which when installed, will act like an editable installation of the project.

@ofek
Copy link
Contributor

ofek commented Jul 5, 2020

@pfmoore I starred that then forgot 🤦‍♂️ I'll use that, thanks!!!

@BrownTruck
Copy link
Contributor

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the master branch into this pull request or rebase this pull request against master then it will be eligible for code review and hopefully merging!

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Jul 19, 2020
@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Jul 19, 2020
@sbidoul sbidoul added the C: editable Editable installations label Aug 4, 2020
@BrownTruck
Copy link
Contributor

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the master branch into this pull request or rebase this pull request against master then it will be eligible for code review and hopefully merging!

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Aug 26, 2020
@dholth
Copy link
Member

dholth commented Dec 13, 2020

Rudimentary support: https://github.com/dholth/enscons/pull/9/files

@sbidoul
Copy link
Member Author

sbidoul commented Dec 13, 2020

@dholth cool. I can't seem to make it work though. I've tried an editable install of rsalette in a python 3.8 venv and I get (in verbose mode)

[...]
Getting requirements to build wheel ... done
  Created temporary directory: /tmp/pip-modern-metadata-tbktrjvt
  Running command /home/me/.virtualenvs/tempenv-46f6785219bc/bin/python /home/me/pip/src/pip/_vendor/pep517/_in_process.py prepare_metadata_for_build_wheel /tmp/tmplc9bqnce
  scons: Reading SConscript files ...
  scons: done reading SConscript files.
  scons: Building targets ...
  zip(["/tmp/pip-wheel-32z26ikb/rsalette-0.4.2-ed.py2.py3-none-any.whl"], ["build/wheel/rsalette-0.4.2.dist-info"])
  scons: *** [/tmp/pip-wheel-32z26ikb/rsalette-0.4.2-ed.py2.py3-none-any.whl] TypeError : from_file() got an unexpected keyword argument 'strict_timestamps'
  Traceback (most recent call last):
    File "/tmp/pip-build-env-mpnn1ksd/overlay/lib/python3.8/site-packages/SCons/Action.py", line 1280, in execute
      result = self.execfunction(target=target, source=rsources, env=env)
    File "/tmp/pip-build-env-mpnn1ksd/overlay/lib/python3.8/site-packages/SCons/Tool/zip.py", line 56, in zip
      zf.write(path, os.path.relpath(path, str(env.get('ZIPROOT', ''))))
    File "/usr/lib/python3.8/zipfile.py", line 1741, in write
      zinfo = ZipInfo.from_file(filename, arcname,
  TypeError: from_file() got an unexpected keyword argument 'strict_timestamps'
  scons: building terminated because of errors.
  Building wheel for rsalette (PEP 517) ... done
  Created wheel for rsalette: filename=rsalette-0.4.2-ed.py2.py3-none-any.whl size=22 sha256=8739c76e681f900923b900c9df0ef75cf421d39cabb54650c4b9ad19b6a76d85
  Stored in directory: /tmp/pip-ephem-wheel-cache-24q5wun0/wheels/75/f8/bd/4791c7abdb70831f4b2ce742a4795ad7240c8914367e3a49c1
Successfully built rsalette
[...]

I don't quite understand the unexpected keyword argument 'strict_timestamps' error... it is as if it was running on another python version, although the log says it starts from the python in my venv. And the other issue is that this error is masked, resulting in an invalid wheel (it might be pip not detecting it, not sure yet).

@pradyunsg
Copy link
Member

pradyunsg commented Sep 24, 2021

But first I'd like to make sure we are clear with the BuildPurpose thing.
BuildPurpose could be a flag instead of an enum, no problem with that.

Yup yup. I'm largely ambivalent on whether we make it a enum vs bool (although... a bool is cleaner if we don't expect to ever need an additional "purpose").

However I tried to make it a property of InstallRequirement, and it did not feel right (see first commit in this PR).
Basically I had to do this, after parsing the requirements:

53419b6#diff-0e8a4985186a14b2deceeb18b81dc7aa90accb68480ac485e49a8f1803dd0339L124-L128

Yep yup, I think that loop for setting those attributes is fine. I reviewed this commit-by-commit, so I noticed all the changes between the two commits as well. :)

@pradyunsg
Copy link
Member

pradyunsg commented Sep 24, 2021

I don't understand your worries:

Phrasing that in terms of supports_pep660 was a mistake on my part. I'm thinking of a project that uses setuptools and has a pyproject.toml:

  • 21.2: pip will call setup.py develop directly.
  • 21.3: pip will try to create a build environment w/ build-system.requires, check for the hook on setuptools.build_meta, fail and fallback to the setup.py call (due to how the try-except falls through to the legacy case).

This is the "jumping" the boundaries of a pyproject.toml based build system vs setup.py based build system I was referring to. It's also a bunch of additional work that brings absolutely no behavior change for the user except for an additional slowdown.

@sbidoul
Copy link
Member Author

sbidoul commented Sep 24, 2021

Yup yup. The trouble is that we'll create an entire build environment, make a call to setuptools, note that it's missing a hook, and then fallback to just calling setup.py develop -- basically doing an additional bunch of work, for absolutely no benefit whatsoever.

It's also a bunch of additional work that brings absolutely no behavior change for the user except for an additional slowdown.

Understood. I don't see any alternative though. We can't even do something if we detect a setup.py because we recently started supporting editables with setup.cfg only. And there is no fast mechanism to query build backend capabilities.

I guess at some point we'll have to work on build environment creation performance (with caching or something, I don't know).

@dholth
Copy link
Member

dholth commented Sep 24, 2021

If we make PEP 660 faster than the old way, maybe the problem will eventually solve itself.

@sbidoul
Copy link
Member Author

sbidoul commented Sep 25, 2021

I added a spinner message around legacy metadata preparation

  • so the fallback to setup.py egg_info when the backend does not support PEP 660 shows something meaningful (before it was silent and it was confusing to have a log saying we did prepare editable metadata using pyproject.toml)
  • for symmetry with pyproject.toml metadata preparation, and it will also help users understanding what happens when metadata preparation is slow

@sbidoul
Copy link
Member Author

sbidoul commented Sep 25, 2021

@pradyunsg I handled (most of) your review comments :)

@github-actions github-actions bot added the needs rebase or merge PR has conflicts with current master label Sep 26, 2021
Copy link
Member

@pradyunsg pradyunsg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit sad at how things are gonna work with existing setup.py-based projects, but not sad enough to block this; since they're still going to work. All of my concerns are non-blocking now and we can tackle them separately.

I do think we're taking on a bunch of technical debt along with this improvement (notably, around the tests and around the build logic), but it's definitely more than worthwhile. We do have to figure out how to pay that down though! :)

src/pip/_internal/commands/install.py Outdated Show resolved Hide resolved
news/8212.feature.rst Outdated Show resolved Hide resolved
@pradyunsg
Copy link
Member

This is gonna need a rebase and a squashing of the fixup commits.

@pradyunsg
Copy link
Member

Wait, where are my manners!? I failed to touch on all the important bits in my get-the-code-stuff-done mode. 😅

I'm genuinely excited that after, uhm... quite a while... we're finally able to fill the hole that we had left in PEP 517 (for good reason, as the length of the discussion for PEP 660 proved!). This PR is the culmination of a lot of work and I'm really glad that we're here now.

@sbidoul I really appreciate you being receptive and responsive to all of my feedback here; even if a bunch of it has seemed a bit odd to you. :)

@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Sep 28, 2021
@sbidoul
Copy link
Member Author

sbidoul commented Sep 28, 2021

I do think we're taking on a bunch of technical debt along with this improvement

Well, I did not have the impression to make the code a lot harder to read or maintain than it is.
But I remain open to improvements suggestions to make in follow-ups - short of rewriting the full build logic. :)

Rebased and squashed. Thanks again for the review. Feel free to merge when green.

@pfmoore
Copy link
Member

pfmoore commented Sep 28, 2021

I'd also like to say I'm really pleased to see this getting in. Sorry I haven't had time to review the PR, but it's great to see it land.

I have skimmed the PR, and I don't feel the technical debt is that bad - it's mainly around the whole need to support legacy projects, and we're going to have to live with that until setuptools implements PEP 660. Unfortunately, I'm not sure there's a lot of motivation in the setuptools project to implement PEP 660, but that's out of our control.

Thanks @sbidoul for all your work on this!

@sbidoul sbidoul merged commit 348d884 into pypa:main Sep 29, 2021
@sbidoul sbidoul deleted the pep517-editable-sbi branch September 29, 2021 09:36
inmantaci pushed a commit to inmanta/inmanta-core that referenced this pull request Oct 12, 2021
Bumps [pip](https://github.com/pypa/pip) from 21.2.4 to 21.3.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/pypa/pip/blob/main/NEWS.rst">pip's changelog</a>.</em></p>
<blockquote>
<h1>21.3 (2021-10-11)</h1>
<h2>Deprecations and Removals</h2>
<ul>
<li>Improve deprecation warning regarding the copying of source trees when installing from a local directory. (<code>[#10128](pypa/pip#10128) &lt;https://github.com/pypa/pip/issues/10128&gt;</code>_)</li>
<li>Suppress location mismatch warnings when pip is invoked from a Python source
tree, so <code>ensurepip</code> does not emit warnings on CPython <code>make install</code>. (<code>[#10270](pypa/pip#10270) &lt;https://github.com/pypa/pip/issues/10270&gt;</code>_)</li>
<li>On Python 3.10 or later, the installation scheme backend has been changed to use
<code>sysconfig</code>. This is to anticipate the deprecation of <code>distutils</code> in Python
3.10, and its scheduled removal in 3.12. For compatibility considerations, pip
installations running on Python 3.9 or lower will continue to use <code>distutils</code>. (<code>[#10358](pypa/pip#10358) &lt;https://github.com/pypa/pip/issues/10358&gt;</code>_)</li>
<li>Remove the <code>--build-dir</code> option and aliases, one last time. (<code>[#10485](pypa/pip#10485) &lt;https://github.com/pypa/pip/issues/10485&gt;</code>_)</li>
<li>In-tree builds are now the default. <code>--use-feature=in-tree-build</code> is now
ignored. <code>--use-deprecated=out-of-tree-build</code> may be used temporarily to ease
the transition. (<code>[#10495](pypa/pip#10495) &lt;https://github.com/pypa/pip/issues/10495&gt;</code>_)</li>
<li>Un-deprecate source distribution re-installation behaviour. (<code>[#8711](pypa/pip#8711) &lt;https://github.com/pypa/pip/issues/8711&gt;</code>_)</li>
</ul>
<h2>Features</h2>
<ul>
<li>Replace vendored appdirs with platformdirs. (<code>[#10202](pypa/pip#10202) &lt;https://github.com/pypa/pip/issues/10202&gt;</code>_)</li>
<li>Support <code>PEP 610 &lt;https://www.python.org/dev/peps/pep-0610/&gt;</code>_ to detect
editable installs in <code>pip freeze</code> and  <code>pip list</code>. The <code>pip list</code> column output
has a new <code>Editable project location</code> column, and the JSON output has a new
<code>editable_project_location</code> field. (<code>[#10249](pypa/pip#10249) &lt;https://github.com/pypa/pip/issues/10249&gt;</code>_)</li>
<li><code>pip freeze</code> will now always fallback to reporting the editable project
location when it encounters a VCS error while analyzing an editable
requirement. Before, it sometimes reported the requirement as non-editable. (<code>[#10410](pypa/pip#10410) &lt;https://github.com/pypa/pip/issues/10410&gt;</code>_)</li>
<li><code>pip show</code> now sorts <code>Requires</code> and <code>Required-By</code> alphabetically. (<code>[#10422](pypa/pip#10422) &lt;https://github.com/pypa/pip/issues/10422&gt;</code>_)</li>
<li>Do not raise error when there are no files to remove with <code>pip cache purge/remove</code>.
Instead log a warning and continue (to log that we removed 0 files). (<code>[#10459](pypa/pip#10459) &lt;https://github.com/pypa/pip/issues/10459&gt;</code>_)</li>
<li>When backtracking during dependency resolution, prefer the dependencies which are involved in the most recent conflict. This can significantly reduce the amount of backtracking required. (<code>[#10479](pypa/pip#10479) &lt;https://github.com/pypa/pip/issues/10479&gt;</code>_)</li>
<li>Cache requirement objects, to improve performance reducing reparses of requirement strings. (<code>[#10550](pypa/pip#10550) &lt;https://github.com/pypa/pip/issues/10550&gt;</code>_)</li>
<li>Support editable installs for projects that have a <code>pyproject.toml</code> and use a
build backend that supports :pep:<code>660</code>. (<code>[#8212](pypa/pip#8212) &lt;https://github.com/pypa/pip/issues/8212&gt;</code>_)</li>
<li>When a revision is specified in a Git URL, use git's partial clone feature to speed up source retrieval. (<code>[#9086](pypa/pip#9086) &lt;https://github.com/pypa/pip/issues/9086&gt;</code>_)</li>
<li>Add a <code>--debug</code> flag, to enable a mode that doesn't log errors and propagates them to the top level instead. This is primarily to aid with debugging pip's crashes. (<code>[#9349](pypa/pip#9349) &lt;https://github.com/pypa/pip/issues/9349&gt;</code>_)</li>
<li>If a host is explicitly specified as trusted by the user (via the --trusted-host option), cache HTTP responses from it in addition to HTTPS ones. (<code>[#9498](pypa/pip#9498) &lt;https://github.com/pypa/pip/issues/9498&gt;</code>_)</li>
</ul>
<h2>Bug Fixes</h2>
<ul>
<li>Present a better error message, when a <code>file:</code> URL is not found. (<code>[#10263](pypa/pip#10263) &lt;https://github.com/pypa/pip/issues/10263&gt;</code>_)</li>
<li>Fix the auth credential cache to allow for the case in which
the index url contains the username, but the password comes
from an external source, such as keyring. (<code>[#10269](pypa/pip#10269) &lt;https://github.com/pypa/pip/issues/10269&gt;</code>_)</li>
<li>Fix double unescape of HTML <code>data-requires-python</code> and <code>data-yanked</code> attributes. (<code>[#10378](pypa/pip#10378) &lt;https://github.com/pypa/pip/issues/10378&gt;</code>_)</li>
<li>New resolver: Fixes depth ordering of packages during resolution, e.g. a dependency 2 levels deep will be ordered before a dependecy 3 levels deep. (<code>[#10482](pypa/pip#10482) &lt;https://github.com/pypa/pip/issues/10482&gt;</code>_)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/pypa/pip/commit/abec8a701bfa66aa15fedf4c898011aa2d95f29e"><code>abec8a7</code></a> Bump for release</li>
<li><a href="https://github.com/pypa/pip/commit/68a70486c9224f9d25be3cbf56c73d8a33c6a713"><code>68a7048</code></a> Update AUTHORS.txt</li>
<li><a href="https://github.com/pypa/pip/commit/9f18a403ca41f4e42fbb89d286b6571a099cb54b"><code>9f18a40</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/pypa/pip/issues/10481">#10481</a> from notatallshaw/prefer_failures</li>
<li><a href="https://github.com/pypa/pip/commit/db496cbce518fa159476695db0cd4f1c1a8ab6f5"><code>db496cb</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/pypa/pip/issues/10563">#10563</a> from pradyunsg/shorter-timeout</li>
<li><a href="https://github.com/pypa/pip/commit/4fac2b90a5d200b46e7b576013bb25f4ebb3f937"><code>4fac2b9</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/pypa/pip/issues/10550">#10550</a> from jbylund/joe/cache_requirement_creation</li>
<li><a href="https://github.com/pypa/pip/commit/786957cf85a641d49b4cfcceef717ef229ac8238"><code>786957c</code></a> Use a shorter timeout, to ensure that this fails more often</li>
<li><a href="https://github.com/pypa/pip/commit/1e3c127d4a938643aca1bbc25e6581493e316476"><code>1e3c127</code></a> Avoid passing <code>.</code> to vendoring</li>
<li><a href="https://github.com/pypa/pip/commit/610424f9f8ad1f99d0a48bf9a53e7a9df4242304"><code>610424f</code></a> Quote &quot;PreferenceInformation&quot; to avoid runtime NameError</li>
<li><a href="https://github.com/pypa/pip/commit/c01b5c6d8a4858cf733408b4b020933f902dda9e"><code>c01b5c6</code></a> Update a test for resolvelib 0.8.0</li>
<li><a href="https://github.com/pypa/pip/commit/394a24eb1a5f9af5da7d4d2452ed5fe952de5db2"><code>394a24e</code></a> Upgrade resolvelib to 0.8.0</li>
<li>Additional commits viewable in <a href="https://github.com/pypa/pip/compare/21.2.4...21.3">compare view</a></li>
</ul>
</details>
<br />

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pip&package-manager=pip&previous-version=21.2.4&new-version=21.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

</details>
mergify bot pushed a commit to andrewbolster/bolster that referenced this pull request Oct 12, 2021
Bumps [pip](https://github.com/pypa/pip) from 21.2.4 to 21.3.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/pypa/pip/blob/main/NEWS.rst">pip's changelog</a>.</em></p>
<blockquote>
<h1>21.3 (2021-10-11)</h1>
<h2>Deprecations and Removals</h2>
<ul>
<li>Improve deprecation warning regarding the copying of source trees when installing from a local directory. (<code>[#10128](pypa/pip#10128) &lt;https://github.com/pypa/pip/issues/10128&gt;</code>_)</li>
<li>Suppress location mismatch warnings when pip is invoked from a Python source
tree, so <code>ensurepip</code> does not emit warnings on CPython <code>make install</code>. (<code>[#10270](pypa/pip#10270) &lt;https://github.com/pypa/pip/issues/10270&gt;</code>_)</li>
<li>On Python 3.10 or later, the installation scheme backend has been changed to use
<code>sysconfig</code>. This is to anticipate the deprecation of <code>distutils</code> in Python
3.10, and its scheduled removal in 3.12. For compatibility considerations, pip
installations running on Python 3.9 or lower will continue to use <code>distutils</code>. (<code>[#10358](pypa/pip#10358) &lt;https://github.com/pypa/pip/issues/10358&gt;</code>_)</li>
<li>Remove the <code>--build-dir</code> option and aliases, one last time. (<code>[#10485](pypa/pip#10485) &lt;https://github.com/pypa/pip/issues/10485&gt;</code>_)</li>
<li>In-tree builds are now the default. <code>--use-feature=in-tree-build</code> is now
ignored. <code>--use-deprecated=out-of-tree-build</code> may be used temporarily to ease
the transition. (<code>[#10495](pypa/pip#10495) &lt;https://github.com/pypa/pip/issues/10495&gt;</code>_)</li>
<li>Un-deprecate source distribution re-installation behaviour. (<code>[#8711](pypa/pip#8711) &lt;https://github.com/pypa/pip/issues/8711&gt;</code>_)</li>
</ul>
<h2>Features</h2>
<ul>
<li>Replace vendored appdirs with platformdirs. (<code>[#10202](pypa/pip#10202) &lt;https://github.com/pypa/pip/issues/10202&gt;</code>_)</li>
<li>Support <code>PEP 610 &lt;https://www.python.org/dev/peps/pep-0610/&gt;</code>_ to detect
editable installs in <code>pip freeze</code> and  <code>pip list</code>. The <code>pip list</code> column output
has a new <code>Editable project location</code> column, and the JSON output has a new
<code>editable_project_location</code> field. (<code>[#10249](pypa/pip#10249) &lt;https://github.com/pypa/pip/issues/10249&gt;</code>_)</li>
<li><code>pip freeze</code> will now always fallback to reporting the editable project
location when it encounters a VCS error while analyzing an editable
requirement. Before, it sometimes reported the requirement as non-editable. (<code>[#10410](pypa/pip#10410) &lt;https://github.com/pypa/pip/issues/10410&gt;</code>_)</li>
<li><code>pip show</code> now sorts <code>Requires</code> and <code>Required-By</code> alphabetically. (<code>[#10422](pypa/pip#10422) &lt;https://github.com/pypa/pip/issues/10422&gt;</code>_)</li>
<li>Do not raise error when there are no files to remove with <code>pip cache purge/remove</code>.
Instead log a warning and continue (to log that we removed 0 files). (<code>[#10459](pypa/pip#10459) &lt;https://github.com/pypa/pip/issues/10459&gt;</code>_)</li>
<li>When backtracking during dependency resolution, prefer the dependencies which are involved in the most recent conflict. This can significantly reduce the amount of backtracking required. (<code>[#10479](pypa/pip#10479) &lt;https://github.com/pypa/pip/issues/10479&gt;</code>_)</li>
<li>Cache requirement objects, to improve performance reducing reparses of requirement strings. (<code>[#10550](pypa/pip#10550) &lt;https://github.com/pypa/pip/issues/10550&gt;</code>_)</li>
<li>Support editable installs for projects that have a <code>pyproject.toml</code> and use a
build backend that supports :pep:<code>660</code>. (<code>[#8212](pypa/pip#8212) &lt;https://github.com/pypa/pip/issues/8212&gt;</code>_)</li>
<li>When a revision is specified in a Git URL, use git's partial clone feature to speed up source retrieval. (<code>[#9086](pypa/pip#9086) &lt;https://github.com/pypa/pip/issues/9086&gt;</code>_)</li>
<li>Add a <code>--debug</code> flag, to enable a mode that doesn't log errors and propagates them to the top level instead. This is primarily to aid with debugging pip's crashes. (<code>[#9349](pypa/pip#9349) &lt;https://github.com/pypa/pip/issues/9349&gt;</code>_)</li>
<li>If a host is explicitly specified as trusted by the user (via the --trusted-host option), cache HTTP responses from it in addition to HTTPS ones. (<code>[#9498](pypa/pip#9498) &lt;https://github.com/pypa/pip/issues/9498&gt;</code>_)</li>
</ul>
<h2>Bug Fixes</h2>
<ul>
<li>Present a better error message, when a <code>file:</code> URL is not found. (<code>[#10263](pypa/pip#10263) &lt;https://github.com/pypa/pip/issues/10263&gt;</code>_)</li>
<li>Fix the auth credential cache to allow for the case in which
the index url contains the username, but the password comes
from an external source, such as keyring. (<code>[#10269](pypa/pip#10269) &lt;https://github.com/pypa/pip/issues/10269&gt;</code>_)</li>
<li>Fix double unescape of HTML <code>data-requires-python</code> and <code>data-yanked</code> attributes. (<code>[#10378](pypa/pip#10378) &lt;https://github.com/pypa/pip/issues/10378&gt;</code>_)</li>
<li>New resolver: Fixes depth ordering of packages during resolution, e.g. a dependency 2 levels deep will be ordered before a dependecy 3 levels deep. (<code>[#10482](pypa/pip#10482) &lt;https://github.com/pypa/pip/issues/10482&gt;</code>_)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/pypa/pip/commit/abec8a701bfa66aa15fedf4c898011aa2d95f29e"><code>abec8a7</code></a> Bump for release</li>
<li><a href="https://github.com/pypa/pip/commit/68a70486c9224f9d25be3cbf56c73d8a33c6a713"><code>68a7048</code></a> Update AUTHORS.txt</li>
<li><a href="https://github.com/pypa/pip/commit/9f18a403ca41f4e42fbb89d286b6571a099cb54b"><code>9f18a40</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/pypa/pip/issues/10481">#10481</a> from notatallshaw/prefer_failures</li>
<li><a href="https://github.com/pypa/pip/commit/db496cbce518fa159476695db0cd4f1c1a8ab6f5"><code>db496cb</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/pypa/pip/issues/10563">#10563</a> from pradyunsg/shorter-timeout</li>
<li><a href="https://github.com/pypa/pip/commit/4fac2b90a5d200b46e7b576013bb25f4ebb3f937"><code>4fac2b9</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/pypa/pip/issues/10550">#10550</a> from jbylund/joe/cache_requirement_creation</li>
<li><a href="https://github.com/pypa/pip/commit/786957cf85a641d49b4cfcceef717ef229ac8238"><code>786957c</code></a> Use a shorter timeout, to ensure that this fails more often</li>
<li><a href="https://github.com/pypa/pip/commit/1e3c127d4a938643aca1bbc25e6581493e316476"><code>1e3c127</code></a> Avoid passing <code>.</code> to vendoring</li>
<li><a href="https://github.com/pypa/pip/commit/610424f9f8ad1f99d0a48bf9a53e7a9df4242304"><code>610424f</code></a> Quote &quot;PreferenceInformation&quot; to avoid runtime NameError</li>
<li><a href="https://github.com/pypa/pip/commit/c01b5c6d8a4858cf733408b4b020933f902dda9e"><code>c01b5c6</code></a> Update a test for resolvelib 0.8.0</li>
<li><a href="https://github.com/pypa/pip/commit/394a24eb1a5f9af5da7d4d2452ed5fe952de5db2"><code>394a24e</code></a> Upgrade resolvelib to 0.8.0</li>
<li>Additional commits viewable in <a href="https://github.com/pypa/pip/compare/21.2.4...21.3">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pip&package-manager=pip&previous-version=21.2.4&new-version=21.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 15, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
C: editable Editable installations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants