Repository: wntrblm/nox
Pull request #805 (2024-03-29 06:17:15)

ci: use uv
Use uv for most (but not all) the jobs in CI.



Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c6033c2..21a824b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -17,6 +17,7 @@ jobs:
   build:
     runs-on: ${{ matrix.os }}
     strategy:
+      fail-fast: false
       matrix:
         os: [ubuntu-20.04, windows-latest, macos-latest]
         python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
@@ -26,6 +27,9 @@ jobs:
         uses: actions/setup-python@v5
         with:
           python-version: ${{ matrix.python-version }}
+      - name: Setup uv
+        uses: yezz123/setup-uv@v4
+        if: matrix.python-version != '3.7'
       - name: Set up Miniconda
         uses: conda-incubator/setup-miniconda@v3
         with:
@@ -33,9 +37,12 @@ jobs:
           python-version: ${{ matrix.python-version }}
           miniforge-variant: Mambaforge
           use-mamba: true
-      - name: Install Nox-under-test
-        run: |
-          python -m pip install --disable-pip-version-check .
+      - name: Install Nox-under-test (uv)
+        if: matrix.python-version != '3.7'
+        run:  uv pip install --system .
+      - name: Install Nox-under-test (pip)
+        if: matrix.python-version == '3.7'
+        run: python -m pip install --disable-pip-version-check .
       - name: Run tests on ${{ matrix.os }} (tox <4)
         run: nox --non-interactive --error-on-missing-interpreter --session "tests(python='${{ matrix.python-version }}', tox_version='<4')" -- --full-trace
       - name: Run tox-to-nox tests on ${{ matrix.os }} (tox latest)
@@ -56,9 +63,10 @@ jobs:
         uses: actions/setup-python@v5
         with:
           python-version: "3.11"
+      - name: Setup uv
+        uses: yezz123/setup-uv@v4
       - name: Install Nox-under-test
-        run: |
-          python -m pip install --disable-pip-version-check .
+        run:  uv pip install --system .
       - name: Download individual coverage reports
         uses: actions/download-artifact@v4
         with:
@@ -78,8 +86,7 @@ jobs:
         with:
           python-version: 3.9
       - name: Install Nox-under-test
-        run: |
-          python -m pip install --disable-pip-version-check .
+        run: python -m pip install --disable-pip-version-check .
       - name: Lint
         run: nox --non-interactive --error-on-missing-interpreter --session "lint"
   docs:
@@ -90,9 +97,10 @@ jobs:
         uses: actions/setup-python@v5
         with:
           python-version: 3.9
+      - name: Setup uv
+        uses: yezz123/setup-uv@v4
       - name: Install Nox-under-test
-        run: |
-          python -m pip install --disable-pip-version-check .
+        run:  uv pip install --system .
       - name: Docs
         run: nox --non-interactive --error-on-missing-interpreter --session "docs"
   deploy:
diff --git a/docs/usage.rst b/docs/usage.rst
index f29dc42..887b4d1 100644
--- a/docs/usage.rst
+++ b/docs/usage.rst
@@ -156,13 +156,6 @@ Note that using this option does not change the backend for sessions where ``ven
    as ``uv pip`` is used to install programs instead. If you need to manually
    interact with pip, you should install it with ``session.install("pip")``.
 
-.. warning::
-
-   Currently the ``uv`` backend requires the ``<program name> @ .`` syntax to
-   install a local folder in non-editable mode; it does not (yet) compute the
-   name from the install process like pip does if the name is omitted. Editable
-   installs do not require a name.
-
 Backends that could be missing (``uv``, ``conda``, and ``mamba``) can have a fallback using ``|``, such as ``uv|virtualenv`` or ``mamba|conda``. This will use the first item that is available on the users system.
 
 If you need to check to see which backend was selected, you can access it via
diff --git a/nox/virtualenv.py b/nox/virtualenv.py
index 64560b8..b561054 100644
--- a/nox/virtualenv.py
+++ b/nox/virtualenv.py
@@ -75,14 +75,18 @@ class ProcessEnv(abc.ABC):
     allowed_globals: ClassVar[tuple[Any, ...]] = ()
 
     def __init__(
-        self, bin_paths: None = None, env: Mapping[str, str] | None = None
+        self, bin_paths: None = None, env: Mapping[str, str | None] | None = None
     ) -> None:
         self._bin_paths = bin_paths
         self.env = os.environ.copy()
         self._reused = False
+        env = env or {}
 
-        if env is not None:
-            self.env.update(env)
+        for k, v in env.items():
+            if v is None:
+                self.env.pop(k, None)
+            else:
+                self.env[k] = v
 
         for key in _BLACKLISTED_ENV_VARS:
             self.env.pop(key, None)
@@ -249,7 +253,7 @@ class CondaEnv(ProcessEnv):
         self.reuse_existing = reuse_existing
         self.venv_params = venv_params or []
         self.conda_cmd = conda_cmd
-        super().__init__(env={"CONDA_PREFIX": self.location})
+        super().__init__(env={"CONDA_PREFIX": self.location, "VIRTUAL_ENV": None})
 
     def _clean_location(self) -> bool:
         """Deletes existing conda environment"""
@@ -379,7 +383,7 @@ class VirtualEnv(ProcessEnv):
         if venv_backend not in {"virtualenv", "venv", "uv"}:
             msg = f"venv_backend {venv_backend} not recognized"
             raise ValueError(msg)
-        super().__init__(env={"VIRTUAL_ENV": self.location})
+        super().__init__(env={"VIRTUAL_ENV": self.location, "CONDA_PREFIX": None})
 
     def _clean_location(self) -> bool:
         """Deletes any existing virtual environment"""
diff --git a/noxfile.py b/noxfile.py
index 6b4de3a..a151e5b 100644
--- a/noxfile.py
+++ b/noxfile.py
@@ -27,6 +27,9 @@ import nox
 
 ON_WINDOWS_CI = "CI" in os.environ and platform.system() == "Windows"
 
+nox.needs_version = ">=2024.3.2"
+nox.options.default_venv_backend = "uv|virtualenv"
+
 # Skip 'conda_tests' if user doesn't have conda installed
 nox.options.sessions = ["tests", "cover", "lint", "docs"]
 if shutil.which("conda"):
@@ -76,7 +79,7 @@ def tests(session: nox.Session, tox_version: str) -> None:
             con.execute("DELETE FROM file WHERE SUBSTR(path, 2, 1) == ':'")
 
 
-@nox.session(python=["3.7", "3.8", "3.9", "3.10"], venv_backend="conda")
+@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"], venv_backend="conda")
 def conda_tests(session: nox.Session) -> None:
     """Run test suite with pytest."""
     session.create_tmp()  # Fixes permission errors on Windows


Test patch:
diff --git a/tests/test_virtualenv.py b/tests/test_virtualenv.py
index 12d41c5..340c2f9 100644
--- a/tests/test_virtualenv.py
+++ b/tests/test_virtualenv.py
@@ -364,9 +364,15 @@ def test_bin_windows(make_one):
 
 
 def test_create(monkeypatch, make_one):
+    monkeypatch.setenv("CONDA_PREFIX", "no-prefix-allowed")
+    monkeypatch.setenv("NOT_CONDA_PREFIX", "something-else")
+
     venv, dir_ = make_one()
     venv.create()
 
+    assert "CONDA_PREFIX" not in venv.env
+    assert "NOT_CONDA_PREFIX" in venv.env
+
     if IS_WINDOWS:
         assert dir_.join("Scripts", "python.exe").check()
         assert dir_.join("Scripts", "pip.exe").check()