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 venv fails to create a venv if the directory if not empty #1863

Open
woutervh opened this issue Feb 22, 2024 · 3 comments
Open

uv venv fails to create a venv if the directory if not empty #1863

woutervh opened this issue Feb 22, 2024 · 3 comments

Comments

@woutervh
Copy link

woutervh commented Feb 22, 2024

tested with:

  • uv --version 0.1.6
  • uv --version 0.1.7
> mkdir -p /tmp/foo
> cd /tmp/foo
> touch makefile
> uv venv .
Using Python 3.11.6 interpreter at /opt/tools/pyenv/var/repo/versions/3.11.6/bin/python3
Creating virtualenv at: .
uv::venv::creation

  × Failed to create virtualenv
  ╰─▶ The directory `.` exists, but it's not a virtualenv

The fail-message is trivially correct and expected in this case, but should not be an error
th venv-creation would not overwrite any existing files or dirs.

but no problem with virtualenv:

> virtualenv .
created virtual environment CPython3.11.5.final.0-64 in 170ms
  creator CPython3Posix(dest=/tmp/foo, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/opt/tools/virtualenv/var/cache)
    added seed packages: pip==23.3.2, setuptools==69.0.3, wheel==0.42.0
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
@charliermarsh
Copy link
Member

Can you say more about the use-case here?

@woutervh
Copy link
Author

woutervh commented Feb 22, 2024

When not developing a python project (where the venv is managed by tools like poetry),
"." is probably the most common directory I use when manually creating a venv (usually via makefile/justfile).

Working on multiple laptops, and various distributions and different temporary WSL-distros
and needing to support others, I see myself re-installing the same tools all the time.

I simplified my workflow to install (non-system packaged) tools to "make install".
The fact that several of these tools I want to install are python-based is not important.
The goal is only to make some executables available (using direct symlinks , without shims & without activation)

I moved away from tools like pipx and pipenv
and I want to avoid the hidden nature of .venv or .local/share/...

my tools-repo is public:

> git clone https://github.com/libranet/libranet-tools/  /opt /tools
> cd /opt/tools/<application>
> make install

> cd /opt/tools/nvm
> make install

> cd /opt/tools/poetry
> make install

> cd /opt/tools/rye
> make install

> cd /opt/tools/virtualenv
> make install

# resulting in
> /opt/tools/<application/bin<executables>

The needed excutables are then symlinked to /opt/tools/bin which is the only dir put on $PATH

Currently most-used uv-based initial workflow is:

> uv venv foo
> cd foo
> ln -s . .venv
> uv pip install ...

But when foo is a checkout-dir with a makefile, refuses to create the venv, where 'python-m venv' or 'virtualenv' don't object.

@charlesnicholson
Copy link

I encountered this issue as well, with a slightly different use case:

We use the ninja build system to build C/C++ and also manage Python dependencies via tasks: "Create a venv", "Install these requirements", "Editable-install package A", "Editable-install package B", "run A tests", "run B tests", "Wheel A", etc.

Ninja uses file timestamps to determine if a target is up-to-date, so we have "proxy" timestamp files that represent things like "this requirements.txt file was installed" because it's otherwise hard to tell whether it happened by looking at the filesystem. If pip install -r requirements.txt succeeds (as one of many examples), we'll stamp an empty file out.

We put these timestamp files inside the venv directory, inside a build_timestamps subdirectory. ninja likes to make sure that all of the output directories exist before it does its work, though, so it creates the our_venv/build_timestamps directory, which causes uv venv to then fail. I had to do some silly filesystem scripting to delete it inside the task that runs uv venv so that uv venv would see no venv directory and create it.

Anyway, it's kind of a niche corner case, but it's also very nice in that if you just want to rm -rf venv the timestamp files vanish with it, and the next invocation of ninja sees that all of the python / venv targets are dirty.

Maybe something like uv venv --permissive that skips the "directory already exists" check, indicating that "yeah, I hear what you're saying but I know some filesystem things you don't so please go ahead anyway?"

That would be safer than build-system shutil.rmtree shenanigans... :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants