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

uv pip uninstall uv does not remove the uv script from a venv #2330

Closed
layday opened this issue Mar 10, 2024 · 22 comments · Fixed by #2348
Closed

uv pip uninstall uv does not remove the uv script from a venv #2330

layday opened this issue Mar 10, 2024 · 22 comments · Fixed by #2348
Assignees
Labels
bug Something isn't working needs-mre Needs more information for reproduction

Comments

@layday
Copy link

layday commented Mar 10, 2024

$ uv pip install uv
Resolved 1 package in 26ms
Installed 1 package in 11ms
 + uv==0.1.16
$ python -c 'import uv'
$ which uv
/Users/dimitris/code/python-packaging/build/venv/bin/uv
$ uv pip uninstall uv
Uninstalled 1 package in 557ms
 - uv==0.1.16
$ python -c 'import uv'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'uv'
[1]$ which uv
/Users/dimitris/code/python-packaging/build/venv/bin/uv
$ uv --version
uv 0.1.16 (9f1452cb7 2024-03-07)
$ uname
Darwin
@charliermarsh
Copy link
Member

How is which uv resolving to the version in your virtualenv? You use uv in the first line, but then the subsequent invocations hit the version in your virtualenv without activating it?

@layday
Copy link
Author

layday commented Mar 10, 2024

The venv is loaded on $PATH. The first invocation is using an outer uv from pipx.

@layday
Copy link
Author

layday commented Mar 10, 2024

This doesn't happen if uv is installed with pip:

$ pip install uv
Collecting uv
  Obtaining dependency information for uv from https://files.pythonhosted.org/packages/23/bd/3b9903bfe592d56e3f69aa3f4aea05c3ccae7dc0c485d288efac54201aac/uv-0.1.16-py3-none-macosx_10_12_x86_64.whl.metadata
  Using cached uv-0.1.16-py3-none-macosx_10_12_x86_64.whl.metadata (20 kB)
Using cached uv-0.1.16-py3-none-macosx_10_12_x86_64.whl (9.9 MB)
Installing collected packages: uv
Successfully installed uv-0.1.16

[notice] A new release of pip is available: 23.2.1 -> 24.0
[notice] To update, run: pip install --upgrade pip
$ cat venv/lib/python3.12/site-packages/uv-0.1.16.dist-info/RECORD
../../../bin/uv,sha256=Z70VmXLN-6IZ7SX3CeSNyxB0cMW4f-Gmx_pCt5zm2gk,24062288
uv-0.1.16.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
uv-0.1.16.dist-info/METADATA,sha256=lJtEXoPUCoaPaOmvua6SfL9ZLtnrNpycmhY9_ukSVGk,20860
uv-0.1.16.dist-info/RECORD,,
uv-0.1.16.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
uv-0.1.16.dist-info/WHEEL,sha256=XZs7YqiZZBVwjUJFDH_4SF9SM8QS2rSqm6iPIRrU0Oc,103
uv-0.1.16.dist-info/license_files/LICENSE-APACHE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
uv-0.1.16.dist-info/license_files/LICENSE-MIT,sha256=F5Z0Cpu8QWyblXwXhrSo0b9WmYXQxd1LwLjVLJZwbiI,1077
uv/__init__.py,sha256=zlgkDW2Sj6yTQT9qLPSSoQfVbPPwFT7edvToFy0xUK8,806
uv/__main__.py,sha256=LlzA8yRVILsEFDn5drFaTiopWuZ1K-_lnb2DK4P81qw,927
uv/__pycache__/__init__.cpython-312.pyc,,
uv/__pycache__/__main__.cpython-312.pyc,,
uv/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
$ uv --verbose pip uninstall uv
    0.000276s DEBUG uv_client::registry_client Using registry request timeout of 300s
 uv::requirements::from_source source=uv
    0.366555s DEBUG uv_interpreter::python_environment Found a virtualenv through VIRTUAL_ENV at: /Users/dimitris/code/python-packaging/build/venv
    0.366933s DEBUG uv_interpreter::interpreter Cached interpreter info for Python 3.12.1, skipping probing: /Users/dimitris/code/python-packaging/build/venv/bin/python
    0.366976s DEBUG uv::commands::pip_uninstall Using Python 3.12.1 environment at /Users/dimitris/code/python-packaging/build/venv/bin/python
    0.370778s DEBUG uv::commands::pip_uninstall Uninstalled uv (13 files, 4 directories)
Uninstalled 1 package in 370ms
 - uv==0.1.16
$ uv pip install uv
Resolved 1 package in 2ms
Installed 1 package in 12ms
 + uv==0.1.16
$ cat venv/lib/python3.12/site-packages/uv-0.1.16.dist-info/RECORD
/Users/dimitris/code/python-packaging/build/venv/bin/uv,sha256=bkGzI3Chbexd_nreYkHHjVyq-FS8BkdywctL1ZRs6_Y,46890608
uv-0.1.16.dist-info/INSTALLER,sha256=5hhM4Q4mYTT9z6QB6PGpUAW81PGNFrYrdXMj4oM_6ak,2
uv-0.1.16.dist-info/INSTALLER,sha256=5seyjfYzlik3jO5wuNTen-ixJCoE5KfxUnhni_eb_Oc,16
uv-0.1.16.dist-info/METADATA,sha256=lJtEXoPUCoaPaOmvua6SfL9ZLtnrNpycmhY9_ukSVGk,20860
uv-0.1.16.dist-info/RECORD,,
uv-0.1.16.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
uv-0.1.16.dist-info/WHEEL,sha256=UKfJlVeDYE_8s37Vzf6MLY2dQV893BQmlKJY1DZ8Qbk,145
uv-0.1.16.dist-info/license_files/LICENSE-APACHE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
uv-0.1.16.dist-info/license_files/LICENSE-MIT,sha256=F5Z0Cpu8QWyblXwXhrSo0b9WmYXQxd1LwLjVLJZwbiI,1077
uv/__init__.py,sha256=zlgkDW2Sj6yTQT9qLPSSoQfVbPPwFT7edvToFy0xUK8,806
uv/__main__.py,sha256=LlzA8yRVILsEFDn5drFaTiopWuZ1K-_lnb2DK4P81qw,927
uv/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
$ uv --verbose pip uninstall uv
    0.000455s DEBUG uv_client::registry_client Using registry request timeout of 300s
 uv::requirements::from_source source=uv
    0.367006s DEBUG uv_interpreter::python_environment Found a virtualenv through VIRTUAL_ENV at: /Users/dimitris/code/python-packaging/build/venv
    0.367281s DEBUG uv_interpreter::interpreter Cached interpreter info for Python 3.12.1, skipping probing: /Users/dimitris/code/python-packaging/build/venv/bin/python
    0.367316s DEBUG uv::commands::pip_uninstall Using Python 3.12.1 environment at /Users/dimitris/code/python-packaging/build/venv/bin/python
    0.372060s DEBUG uv::commands::pip_uninstall Uninstalled uv (10 files, 3 directories)
Uninstalled 1 package in 371ms
 - uv==0.1.16

Comparing the RECORD written by pip vs uv's:

diff --git a/pip.diff b/uv.diff
index ece3d6a..2d5861c 100644
--- a/pip.diff
+++ b/uv.diff
@@ -1,13 +1,12 @@
-../../../bin/uv,sha256=Z70VmXLN-6IZ7SX3CeSNyxB0cMW4f-Gmx_pCt5zm2gk,24062288
-uv-0.1.16.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+/Users/dimitris/code/python-packaging/build/venv/bin/uv,sha256=bkGzI3Chbexd_nreYkHHjVyq-FS8BkdywctL1ZRs6_Y,46890608
+uv-0.1.16.dist-info/INSTALLER,sha256=5hhM4Q4mYTT9z6QB6PGpUAW81PGNFrYrdXMj4oM_6ak,2
+uv-0.1.16.dist-info/INSTALLER,sha256=5seyjfYzlik3jO5wuNTen-ixJCoE5KfxUnhni_eb_Oc,16
 uv-0.1.16.dist-info/METADATA,sha256=lJtEXoPUCoaPaOmvua6SfL9ZLtnrNpycmhY9_ukSVGk,20860
 uv-0.1.16.dist-info/RECORD,,
 uv-0.1.16.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-uv-0.1.16.dist-info/WHEEL,sha256=XZs7YqiZZBVwjUJFDH_4SF9SM8QS2rSqm6iPIRrU0Oc,103
+uv-0.1.16.dist-info/WHEEL,sha256=UKfJlVeDYE_8s37Vzf6MLY2dQV893BQmlKJY1DZ8Qbk,145
 uv-0.1.16.dist-info/license_files/LICENSE-APACHE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
 uv-0.1.16.dist-info/license_files/LICENSE-MIT,sha256=F5Z0Cpu8QWyblXwXhrSo0b9WmYXQxd1LwLjVLJZwbiI,1077
 uv/__init__.py,sha256=zlgkDW2Sj6yTQT9qLPSSoQfVbPPwFT7edvToFy0xUK8,806
 uv/__main__.py,sha256=LlzA8yRVILsEFDn5drFaTiopWuZ1K-_lnb2DK4P81qw,927
-uv/__pycache__/__init__.cpython-312.pyc,,
-uv/__pycache__/__main__.cpython-312.pyc,,
 uv/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

The two notable differences appear to be that the script path is absolute for uv and that it has a duplicate INSTALLER record (though obviously only one file on disk). The shasums are different because pip installs the x64 wheel whereas uv opts for universal2.

@charliermarsh
Copy link
Member

Thanks!

@charliermarsh
Copy link
Member

Found the duplicate INSTALLER, just an oversight. I need to figure out how we could end up with an absolute path there. I don’t think it happens in general because we have a debug assert that the path is relative… I’ll look into it today.

@charliermarsh
Copy link
Member

I have one idea for how it happens.

@charliermarsh charliermarsh self-assigned this Mar 10, 2024
@charliermarsh
Copy link
Member

Also, I think we should be preferring the x86 wheels, right? That seems wrong too.

@charliermarsh
Copy link
Member

Struggling to see how this would happen. Would you mind running

in your interpreter within the virtualenv and sharing the results?

@layday
Copy link
Author

layday commented Mar 10, 2024

{
  "markers": {
    "implementation_name": "cpython",
    "implementation_version": "3.12.1",
    "os_name": "posix",
    "platform_machine": "x86_64",
    "platform_python_implementation": "CPython",
    "platform_release": "21.6.0",
    "platform_system": "Darwin",
    "platform_version": "Darwin Kernel Version 21.6.0: Mon Feb 19 20:24:34 PST 2024; root:xnu-8020.240.18.707.4~1/RELEASE_X86_64",
    "python_full_version": "3.12.1",
    "python_version": "3.12",
    "sys_platform": "darwin"
  },
  "base_prefix": "/nix/store/g7gr0av2rkj57fqaklimdp769alxcfg1-python3-3.12.1",
  "base_exec_prefix": "/nix/store/g7gr0av2rkj57fqaklimdp769alxcfg1-python3-3.12.1",
  "prefix": "/Users/dimitris/code/python-packaging/build/venv",
  "base_executable": "/nix/store/g7gr0av2rkj57fqaklimdp769alxcfg1-python3-3.12.1/bin/python3.12",
  "sys_executable": "/Users/dimitris/code/python-packaging/build/venv/bin/python",
  "stdlib": "/nix/store/g7gr0av2rkj57fqaklimdp769alxcfg1-python3-3.12.1/lib/python3.12",
  "scheme": {
    "platlib": "/Users/dimitris/code/python-packaging/build/venv/lib/python3.12/site-packages",
    "purelib": "/Users/dimitris/code/python-packaging/build/venv/lib/python3.12/site-packages",
    "include": "/Users/dimitris/code/python-packaging/build/venv/include/site/python3.12",
    "scripts": "/Users/dimitris/code/python-packaging/build/venv/bin",
    "data": "/Users/dimitris/code/python-packaging/build/venv"
  },
  "virtualenv": {
    "purelib": "lib/python3.12/site-packages",
    "platlib": "lib/python3.12/site-packages",
    "include": "include/site/python3.12",
    "scripts": "bin",
    "data": ""
  }
}

@charliermarsh
Copy link
Member

Oh the x86 vs. universal might be a Nix thing. This has been reported before on Nix.

@layday
Copy link
Author

layday commented Mar 10, 2024

I'm not sure if #1952 is related - I haven't installed uv with nix.

@charliermarsh
Copy link
Member

I don't think it would matter how you install uv. The issue is what we query from the running environment and the Python interpreter.

@charliermarsh
Copy link
Member

I have absolutely no clue how an absolute path is ending up in there though. If both scheme.scripts and scheme.platlib are absolute, I don't see how it could happen.

@charliermarsh charliermarsh added bug Something isn't working needs-mre Needs more information for reproduction labels Mar 10, 2024
@layday
Copy link
Author

layday commented Mar 10, 2024

Is there anything I can do to help, keeping in mind that I know next to nothing about Rust? 😛

@charliermarsh
Copy link
Member

If I put up a branch, is there any chance you'd be willing to check it out, cargo build, and run with some debug logging?

@layday
Copy link
Author

layday commented Mar 10, 2024

Sure!

@charliermarsh
Copy link
Member

Ok let me make sure I cover everything that might be useful 😂

@layday
Copy link
Author

layday commented Mar 10, 2024

FWIW I'm able to repro this with scripts from other packages. For non-script data files, the path is kept relative. Unsure if this is of any help, but if I'm reading the code in

let target_path = bin_rel().join(file.file_name());
correctly, then it doesn't matter what the sysconfig paths are - the bin directory path is hardcoded per plat.

@charliermarsh
Copy link
Member

Oh sorry, I think I was only looking at entrypoints, and not files in data. Let me revisit...

(BTW, I think the version you linked is stale. That line doesn't exist on main.)

@charliermarsh
Copy link
Member

Okay I think I can reproduce.

@charliermarsh
Copy link
Member

Now just trying to figure out why I couldn't reproduce this earlier. Maybe I made a mistake earlier. Anyway I can fix this now! Thanks.

@charliermarsh
Copy link
Member

Fixed in the next release, thank you and sorry for the confusion, I think my earlier debugging led me astray but pointing to that codepath was helpful.

charliermarsh added a commit that referenced this issue Mar 10, 2024
## Summary

In #2000, I shipped a regression whereby we stopped writing relative
paths for scripts within `data` directories. The net effect here is that
we aren't _uninstalling_ binaries in all cases. (This does _not_ apply
to entrypoints, only scripts in `data` directories.)

Closes #2330.

## Test Plan

Most Python packages ship entrypoints, not binaries, so I don't know how
to test this cheaply. But I did test it locally by verifying that `uv`
is now removed from the `bin` directory after an uninstall.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs-mre Needs more information for reproduction
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants