uv icon indicating copy to clipboard operation
uv copied to clipboard

Print installation path when running `uv pip install`

Open danielhollas opened this issue 1 year ago • 11 comments

Hey :wave:

Small feature request: It would be great if uv printed the path where it is installing the packages when running uv pip install. I am currently debugging a weird issue in GHA while using uv pip install --system and it is not clear how to check where uv ends up installing stuff.

danielhollas avatar Mar 04 '24 14:03 danielhollas

Have you tried running with --verbose?

charliermarsh avatar Mar 04 '24 14:03 charliermarsh

Yeah, indeed running with verbose prints this:

 uv_interpreter::python_query::find_default_python 
      0.004003s   0ms DEBUG uv_interpreter::python_query Starting interpreter discovery for default Python
      0.004109s   0ms DEBUG uv_interpreter::interpreter Probing interpreter info for: /opt/hostedtoolcache/Python/3.10.13/x64/bin/python3
      0.039094s  35ms DEBUG uv_interpreter::interpreter Found Python 3.10.13 for: /opt/hostedtoolcache/Python/3.10.13/x64/bin/python3
    0.039395s DEBUG uv::commands::pip_install Using Python 3.10.13 environment at /opt/hostedtoolcache/Python/3.10.13/x64/bin/python3

To me, this is not very easy to parse, and even find among the rest of the huge debug output. At least for the --system flag seems like a good info to print by default, especially given the number of issues / corner cases that have been reported (and fixed!) for this particular option. But of course opinions might vary. :-)

danielhollas avatar Mar 04 '24 23:03 danielhollas

it is not clear how to check where uv ends up installing stuff.

I've already been bitten multiple times by this, installing stuff in the wrong venv. Because I have 100 venvs on my system,
and I really dislike activating a venv (because it's an anti-patteren creating state in that specific shell.)

with actual pip, it's not really an issue, because you are always using the pip from inside the virtualenv

> uv pip install pytest
Resolved 4 packages in 286ms
Downloaded 1 package in 64ms
Installed 4 packages in 21ms
 + iniconfig==2.0.0
 + pytest==8.0.2
  ...

A much more userfriendly output would be to include the path somewhere

> uv pip install pytest
Resolved 4 packages.                                <- I don't care about how many millisecs it takes,  it's visual pollution
Downloaded 1 package.                           <- which one?  what if I don't expect to download anything new?
Installed 4 packages in /tmp/foo/.venv/   <- include path
  ...
  + iniconfig==2.0.0
 + pytest==8.0.2  (dowloaded)

woutervh avatar Mar 05 '24 12:03 woutervh

So, I love the new more concise verbose output (-v), however, I will still lobby for uv to print the install location by default. :blush:

As previous commenter pointed out, it's too easy to make a mistake and not notice it (e.g. forgetting to deactivate the environment, switch to different directory with its own .venv, and then running uv pip install)

danielhollas avatar Mar 18 '24 22:03 danielhollas

Considering starting by showing the path if it's not .venv (i.e., a virtualenv in the current working directory).

charliermarsh avatar Mar 26 '24 03:03 charliermarsh

Considering starting by showing the path if it's not .venv (i.e., a virtualenv in the current working directory).

I think this would be really useful. I was just caught out by uv unexpectedly installing things into my ~dev/.venv environment, rather than my ~dev/project/env environment, because I didn't have the latter activated, and uv searched up through the directory structure until it found a virtual environment called .venv.

AlexWaygood avatar Mar 26 '24 14:03 AlexWaygood

another separate, but related nicety would be printing out the Location column that pip list --verbose prints:

$ pip list --verbose
Package            Version     Location                                                            Installer
------------------ ----------- ------------------------------------------------------------------- ---------
asttokens          2.4.1       /Users/chankang/.pyenv/versions/3.12.2/lib/python3.12/site-packages uv
build              1.2.1       /Users/chankang/.pyenv/versions/3.12.2/lib/python3.12/site-packages uv

ChannyClaus avatar Apr 22 '24 21:04 ChannyClaus

I think it'd be reasonable to start with this: https://github.com/astral-sh/uv/issues/2155#issuecomment-2019302112

zanieb avatar Jul 01 '24 21:07 zanieb

Hi! I wanted to look into this - would it be a matter of updating the line in uv/src/commands/pip/operations.rs to something like:

        writeln!(
            printer.stderr(),
            "{}",
            format!(
                "Installed {} in {} to {}",
                format!("{} package{}", wheels.len(), s).bold(),
                elapsed(start.elapsed()),
                venv.python_executable().display()
            )
            .dimmed()
        )?;

Based on the test results it looks correct (although it looks like we would need to update the snapshots)

Installed 3 packages in [TIME] to /private/var/folders/7s/q0mx5qbs78bfgpclqx_8tknm0000gn/T/.tmpRu7Vx5/.venv/bin/python3

danielenricocahall avatar Jul 04 '24 16:07 danielenricocahall

We'd want to only display the path if it's not in the working directory which would require some sort of if/else. As a minor note, we use .user_display() for paths. Otherwise that seems like a reasonable place to start. Maybe we should print

Installing to environment at {path}

before this message instead of adding to the end of it?

zanieb avatar Jul 04 '24 16:07 zanieb

Sure! I have something like this:

        let python_executable = venv.python_executable();
        let venv_dir_canonical = fs::canonicalize(".venv").unwrap_or(PathBuf::from(".venv"));
        let is_outside_working_directory = !(python_executable.starts_with(&venv_dir_canonical));
        if is_outside_working_directory {
            writeln!(
                printer.stderr(),
                "{}",
                format!(
                    "Installing to environment at {}",
                    python_executable.user_display()
                )
            )?;
        }

I wasn't sure the best way to check for being in .venv so definitely open to suggestions there

danielenricocahall avatar Jul 04 '24 20:07 danielenricocahall