pip: pip cannot uninstall an editable install in some cases

Description

When a project that contains only pyproject.toml is installed in editable mode, pip cannot uninstall it.

pip version

21.3.1

Python version

3.9

OS

Ubuntu

How to Reproduce

$ git clone git@github.com:NeilGirdhar/tjax.git
Cloning into 'tjax'...
remote: Enumerating objects: 1819, done.
remote: Counting objects: 100% (223/223), done.
remote: Compressing objects: 100% (134/134), done.
remote: Total 1819 (delta 146), reused 134 (delta 89), pack-reused 1596
Receiving objects: 100% (1819/1819), 526.17 KiB | 3.96 MiB/s, done.
Resolving deltas: 100% (1288/1288), done.

$ pip install -e tjax
Obtaining file:///home/neil/tjax
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: networkx<3.0,>=2.4 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from tjax==0.14.2) (2.6.3)
Requirement already satisfied: yapf>=0.31 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from tjax==0.14.2) (0.31.0)
Requirement already satisfied: jax<0.3.0,>=0.2.21 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from tjax==0.14.2) (0.2.22)
Requirement already satisfied: optax<1,>=0 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from tjax==0.14.2) (0.0.9)
Requirement already satisfied: numpy>=1.21 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from tjax==0.14.2) (1.21.2)
Requirement already satisfied: matplotlib<4.0,>=3.3 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from tjax==0.14.2) (3.4.3)
Requirement already satisfied: colorful<0.6.0,>=0.5.4 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from tjax==0.14.2) (0.5.4)
Requirement already satisfied: absl-py in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from jax<0.3.0,>=0.2.21->tjax==0.14.2) (0.13.0)
Requirement already satisfied: opt_einsum in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from jax<0.3.0,>=0.2.21->tjax==0.14.2) (3.3.0)
Requirement already satisfied: scipy>=1.2.1 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from jax<0.3.0,>=0.2.21->tjax==0.14.2) (1.7.1)
Requirement already satisfied: pyparsing>=2.2.1 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from matplotlib<4.0,>=3.3->tjax==0.14.2) (2.4.7)
Requirement already satisfied: pillow>=6.2.0 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from matplotlib<4.0,>=3.3->tjax==0.14.2) (8.3.2)
Requirement already satisfied: python-dateutil>=2.7 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from matplotlib<4.0,>=3.3->tjax==0.14.2) (2.8.2)
Requirement already satisfied: kiwisolver>=1.0.1 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from matplotlib<4.0,>=3.3->tjax==0.14.2) (1.3.2)
Requirement already satisfied: cycler>=0.10 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from matplotlib<4.0,>=3.3->tjax==0.14.2) (0.10.0)
Requirement already satisfied: jaxlib>=0.1.37 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from optax<1,>=0->tjax==0.14.2) (0.1.71)
Requirement already satisfied: chex>=0.0.4 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from optax<1,>=0->tjax==0.14.2) (0.0.8)
Requirement already satisfied: six in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from absl-py->jax<0.3.0,>=0.2.21->tjax==0.14.2) (1.16.0)
Requirement already satisfied: dm-tree>=0.1.5 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from chex>=0.0.4->optax<1,>=0->tjax==0.14.2) (0.1.6)
Requirement already satisfied: toolz>=0.9.0 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from chex>=0.0.4->optax<1,>=0->tjax==0.14.2) (0.11.1)
Requirement already satisfied: flatbuffers<3.0,>=1.12 in ./.pyenv/versions/3.9.6/lib/python3.9/site-packages (from jaxlib>=0.1.37->optax<1,>=0->tjax==0.14.2) (2.0)
Installing collected packages: tjax
  Running setup.py develop for tjax
Successfully installed tjax

$ pip uninstall tjax
WARNING: Skipping tjax as it is not installed.

$ cat /home/neil/.pyenv/versions/3.9.6/lib/python3.9/site-packages/easy-install.pth
/home/neil/tjax

This uninstalls it:

$ cat /dev/null > /home/neil/.pyenv/versions/3.9.6/lib/python3.9/site-packages/easy-install.pth

Also, for some reason, the egg in ~/tjax is called “UNKNOWN.egg-info”, but pyproject.toml clearly specifies the name “tjax”.

Code of Conduct

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Comments: 23 (16 by maintainers)

Most upvoted comments

@NeilGirdhar both would be compatibility-breaking changes for pip, unfortunately.

if it’s going to install a project as editable using setuptools, it should use the name that Setuptools resolves for the package

Setuptools handle all the installation when being used to install an editable, and the project name is resolved by only setuptools, pip does not do anything here.

I agree with your earlier point there’s something pip can do to make things more sensible though. It’s true that a project can be setup.cfg-only, but a setup.cfg-only project without an explicit backend declaration in pyproject.toml is arguably more likely to be a user error than intentionally configured.

  • consequently, pip tries to fallback on a setuptools based editable install, which it thinks it can do because there is a setup.cfg

I do think there’s something pip could do here. If the pyproject.toml specifies a build backend, it should not invoke setuptools. In fact I’d go further and say that pip should not fall back to building with Setuptools unless there’s a setup.py file. It’s true that Setuptools projects can be defined by setup.cfg only, but if that’s what the user wants, they should specify setuptools as the backend.

Maybe that’s not possible, given current assumptions (projects are allowed to specify one backend, but expect to use setuptools as a fallback for editable).

There’s something else pip could do - if it’s going to install a project as editable using setuptools, it should use the name that Setuptools resolves for the package, regardless what pip might expect by reading pyproject.toml.

Thanks. I’m just asking which project should be giving the error now though. If I don’t change anything, I should still be getting an error, right? Where should that be coming from?

@NeilGirdhar As I said above, setuptools, IMHO.