mirror of
				https://github.com/astral-sh/uv.git
				synced 2025-11-04 13:38:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			136 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
 | 
						|
"""
 | 
						|
Install packages on multiple versions of uv to check for cache compatibility errors.
 | 
						|
"""
 | 
						|
 | 
						|
from __future__ import annotations
 | 
						|
 | 
						|
import argparse
 | 
						|
import logging
 | 
						|
import os
 | 
						|
import subprocess
 | 
						|
import sys
 | 
						|
import tempfile
 | 
						|
 | 
						|
DEFAULT_TEST_PACKAGES = [
 | 
						|
    # anyio is used throughout our test suite as a minimal dependency
 | 
						|
    "anyio",
 | 
						|
    # flask is another standard test dependency for us, but bigger than anyio
 | 
						|
    "flask",
 | 
						|
]
 | 
						|
 | 
						|
if sys.platform == "linux":
 | 
						|
    DEFAULT_TEST_PACKAGES += [
 | 
						|
        # homeassistant has a lot of dependencies and should be built from source
 | 
						|
        # this requires additional dependencies on macOS so we gate it to Linux
 | 
						|
        "homeassistant",
 | 
						|
    ]
 | 
						|
 | 
						|
 | 
						|
def install_package(*, uv: str, package: str, flags: list[str]):
 | 
						|
    """Install a package"""
 | 
						|
 | 
						|
    logging.info(f"Installing the package {package!r} with {uv!r}.")
 | 
						|
    subprocess.run(
 | 
						|
        [uv, "pip", "install", package, "--cache-dir", os.path.join(temp_dir, "cache")]
 | 
						|
        + flags,
 | 
						|
        cwd=temp_dir,
 | 
						|
        check=True,
 | 
						|
    )
 | 
						|
 | 
						|
    logging.info(f"Checking that `{package}` is available.")
 | 
						|
    code = subprocess.run([uv, "pip", "show", package], cwd=temp_dir)
 | 
						|
    if code.returncode != 0:
 | 
						|
        raise Exception(f"Could not show {package}.")
 | 
						|
 | 
						|
 | 
						|
def clean_cache(*, uv: str):
 | 
						|
    subprocess.run(
 | 
						|
        [uv, "cache", "clean", "--cache-dir", os.path.join(temp_dir, "cache")],
 | 
						|
        cwd=temp_dir,
 | 
						|
        check=True,
 | 
						|
    )
 | 
						|
 | 
						|
 | 
						|
def check_cache_with_package(
 | 
						|
    *,
 | 
						|
    uv_current: str,
 | 
						|
    uv_previous: str,
 | 
						|
    package: str,
 | 
						|
):
 | 
						|
    # The coverage here is rough and not particularly targeted — we're just performing various
 | 
						|
    # operations in the hope of catching cache load issues. As cache problems are discovered in
 | 
						|
    # the future, we should expand coverage with targeted cases.
 | 
						|
 | 
						|
    # First, install with the previous uv to populate the cache
 | 
						|
    install_package(uv=uv_previous, package=package, flags=[])
 | 
						|
 | 
						|
    # Audit with the current uv, this shouldn't hit the cache but is fast
 | 
						|
    install_package(uv=uv_current, package=package, flags=[])
 | 
						|
 | 
						|
    # Reinstall with the current uv
 | 
						|
    install_package(uv=uv_current, package=package, flags=["--reinstall"])
 | 
						|
 | 
						|
    # Reinstall with the current uv and refresh a single entry
 | 
						|
    install_package(
 | 
						|
        uv=uv_current,
 | 
						|
        package=package,
 | 
						|
        flags=["--reinstall-package", package, "--refresh-package", package],
 | 
						|
    )
 | 
						|
 | 
						|
    # Reinstall with the current uv post refresh
 | 
						|
    install_package(uv=uv_current, package=package, flags=["--reinstall"])
 | 
						|
 | 
						|
    # Reinstall with the current uv post refresh
 | 
						|
    install_package(uv=uv_previous, package=package, flags=["--reinstall"])
 | 
						|
 | 
						|
    # Clear the cache
 | 
						|
    clean_cache(uv=uv_previous)
 | 
						|
 | 
						|
    # Install with the previous uv to populate the cache
 | 
						|
    # Use `--no-binary` to force a local build of the wheel
 | 
						|
    install_package(uv=uv_previous, package=package, flags=["--no-binary", package])
 | 
						|
 | 
						|
    # Reinstall with the current uv
 | 
						|
    install_package(uv=uv_current, package=package, flags=["--reinstall"])
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
 | 
						|
 | 
						|
    parser = argparse.ArgumentParser(description="Check a Python interpreter.")
 | 
						|
    parser.add_argument(
 | 
						|
        "-c", "--uv-current", help="Path to a current uv binary.", required=True
 | 
						|
    )
 | 
						|
    parser.add_argument(
 | 
						|
        "-p", "--uv-previous", help="Path to a previous uv binary.", required=True
 | 
						|
    )
 | 
						|
    parser.add_argument(
 | 
						|
        "-t",
 | 
						|
        "--test-package",
 | 
						|
        action="append",
 | 
						|
        type=str,
 | 
						|
        help="A package to test. May be provided multiple times.",
 | 
						|
    )
 | 
						|
    args = parser.parse_args()
 | 
						|
 | 
						|
    uv_current = os.path.abspath(args.uv_current)
 | 
						|
    uv_previous = os.path.abspath(args.uv_previous)
 | 
						|
    test_packages = args.test_package or DEFAULT_TEST_PACKAGES
 | 
						|
 | 
						|
    # Create a temporary directory.
 | 
						|
    with tempfile.TemporaryDirectory() as temp_dir:
 | 
						|
        logging.info("Creating a virtual environment.")
 | 
						|
        code = subprocess.run(
 | 
						|
            [uv_current, "venv"],
 | 
						|
            cwd=temp_dir,
 | 
						|
        )
 | 
						|
 | 
						|
        for package in test_packages:
 | 
						|
            logging.info(f"Testing with {package!r}.")
 | 
						|
            check_cache_with_package(
 | 
						|
                uv_current=uv_current,
 | 
						|
                uv_previous=uv_previous,
 | 
						|
                package=package,
 | 
						|
            )
 |