Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
435dc32
hatch: cli: application: Switch to uv
vpetrigo Jan 9, 2025
fc37df4
tests: Update asserts after switching to uv
vpetrigo Jan 9, 2025
f32f360
hatch: tests: Update uv command search
vpetrigo Jan 11, 2025
376784d
hatch: Update to use find_uv_bin()
vpetrigo Jan 11, 2025
c1f2e75
hatch: Update the implementation to use --python switch
vpetrigo Jan 14, 2025
704f1a2
Merge branch 'master' into fix/hardcoded-reliance-on-pip
vpetrigo Sep 27, 2025
0bafeb0
Merge branch 'master' into fix/hardcoded-reliance-on-pip
vpetrigo Oct 8, 2025
f92ca4d
Merge branch 'master' into fix/hardcoded-reliance-on-pip
vpetrigo Oct 20, 2025
4b05ffe
Merge branch 'master' into fix/hardcoded-reliance-on-pip
vpetrigo Nov 10, 2025
860409b
Merge branch 'master' into fix/hardcoded-reliance-on-pip
vpetrigo Nov 13, 2025
a589528
misc: Remove unused pathlib imports and switch to consistent string q…
vpetrigo Nov 14, 2025
a2898f8
Merge branch 'master' into fix/hardcoded-reliance-on-pip
vpetrigo Nov 15, 2025
8c6ca18
Merge branch 'master' into fix/hardcoded-reliance-on-pip
vpetrigo Nov 16, 2025
a07e787
Merge branch 'master' into fix/hardcoded-reliance-on-pip
vpetrigo Nov 16, 2025
f0f5d75
Merge branch 'master' into fix/hardcoded-reliance-on-pip
vpetrigo Nov 26, 2025
27e9218
tests: Use consistent double-quoted strings in conftest.py
vpetrigo Nov 26, 2025
be65450
tests: Handle commands with "hatchling" in conftest.py mock
vpetrigo Nov 26, 2025
b8296f4
Merge branch 'master' into fix/hardcoded-reliance-on-pip
vpetrigo Nov 26, 2025
cdc789b
Merge branch 'master' into fix/hardcoded-reliance-on-pip
vpetrigo Nov 27, 2025
c4c309d
Merge branch 'master' into fix/hardcoded-reliance-on-pip
vpetrigo Nov 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/hatch/cli/application.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great, I was imagining the fix for this would be some complicated piece of work - but this is a really nice, targeted swap of pip for uv pip only in ensure_plugin_dependencies

Copy link
Contributor

@juftin juftin Jan 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EDIT: This test is passing confirming this works, it will fail if you swap git+https://github.com/vpetrigo/hatch.git@fix/hardcoded-reliance-on-pip with hatch

FROM fedora:latest

RUN dnf install -y git

COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

RUN uv python install 3.12
RUN uv tool install git+https://github.com/vpetrigo/hatch.git@fix/hardcoded-reliance-on-pip
ENV PATH="/root/.local/bin:${PATH}"

WORKDIR /work

RUN touch /work/pyproject.toml

RUN cat <<EOF > /work/pyproject.toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "foo"
version = "0.0.1"
dependencies = ["requests"]

[tool.hatch.env]
requires = [
    "hatch-pip-compile"
]

[tool.hatch.envs.default]
installer = "uv"
type = "pip-compile"
pip-compile-resolver = "uv"
pip-compile-installer = "uv"
EOF

RUN mkdir /work/foo
RUN touch /work/foo/__init__.py

CMD ["hatch", "run", "head", "requirements.txt"]
docker build . --tag hatch-pip-compile-test
docker run --rm -it hatch-pip-compile-test
#
# This file is autogenerated by hatch-pip-compile with Python 3.12
#
# - requests
#

certifi==2024.12.14
    # via requests
charset-normalizer==3.4.1
    # via requests

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually fails now since we've replaced sys.executable -m pip with find_uv_bin 😢

Looks like uv doesn't know what environment to install into

error: No virtual environment found; run `uv venv` to create an environment, or pass `--system` to install into a non-virtual environment

Copy link
Author

@vpetrigo vpetrigo Jan 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rolled back for now to [sys.executable, '-u', '-m', 'uv', 'pip'].

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What may work is the following command:

uv_bin = find_uv_bin()
pip_command = [uv_bin, 'pip']

pip_command.extend(['install', '--directory', str(pathlib.Path(sys.executable).parent.parent)])

Not sure if it is more reliable than calling a uv module with venv Python.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed those changes for review just in the case that approach with find_uv_bin is preferable. 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about two options that would work here:

The first option essentially calls python -m uv pip which when invoked as a module discovers the Python environment it belongs to

pip_command = [sys.executable, "-m", "uv", "pip"]
pip_command.extend(["install"])

The second option is to call the find_uv_bin method, but also passes the current Python interpreter using the --python argument

uv_binary = find_uv_bin()
pip_command = [uv_binary, "pip"]
pip_command.extend(["install", "--python", sys.executable])

Honestly, I think both of these options do the same thing 🤷 - I'm fine with whatever you and Ofek like

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the implementation for the last option with passing --python switch as it is more readable and less confusing than passing venv Python directory with --directory switch. Run through the tests in hatch and with the container you prepared - all passed on my end.

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from functools import cached_property
from typing import TYPE_CHECKING, cast

from uv import find_uv_bin

from hatch.cli.terminal import Terminal
from hatch.config.user import ConfigFile, RootConfig
from hatch.project.core import Project
Expand Down Expand Up @@ -163,9 +165,10 @@ def ensure_plugin_dependencies(self, dependencies: list[Dependency], *, wait_mes
if distributions.dependencies_in_sync(dependencies):
return

pip_command = [sys.executable, "-u", "-m", "pip"]
uv_bin = find_uv_bin()
pip_command = [uv_bin, "pip"]

pip_command.extend(["install", "--disable-pip-version-check"])
pip_command.extend(["install", "--disable-pip-version-check", "--python", sys.executable])

# Default to -1 verbosity
add_verbosity_flag(pip_command, self.verbosity, adjustment=-1)
Expand Down
9 changes: 9 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from click.testing import CliRunner as __CliRunner
from filelock import FileLock
from platformdirs import user_cache_dir, user_data_dir
from uv import find_uv_bin

from hatch.config.constants import AppEnvVars, ConfigEnvVars, PublishEnvVars
from hatch.config.user import ConfigFile
Expand Down Expand Up @@ -437,10 +438,18 @@ def mock_plugin_installation(mocker):

def _mock(command, **kwargs):
if isinstance(command, list):
if any(arg.startswith("hatchling") for arg in command):
return subprocess_run(command, **kwargs)

if command[:5] == [sys.executable, "-u", "-m", "pip", "install"]:
mocked_subprocess_run(command, **kwargs)
return mocked_subprocess_run

uv_bin = find_uv_bin()
if command[:3] == [uv_bin, "pip", "install"]:
mocked_subprocess_run(command, **kwargs)
return mocked_subprocess_run

if command[:3] == [sys.executable, "self", "python-path"]:
return mocker.MagicMock(returncode=0, stdout=sys.executable.encode())

Expand Down
8 changes: 5 additions & 3 deletions tests/helpers/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from unittest.mock import call

import tomli_w
from uv import find_uv_bin

from hatch.config.user import RootConfig
from hatch.env.utils import add_verbosity_flag
Expand Down Expand Up @@ -48,13 +49,14 @@ def get_current_timestamp():


def assert_plugin_installation(subprocess_run, dependencies: list[str], *, verbosity=0, count=1):
uv_bin = find_uv_bin()
command = [
sys.executable,
"-u",
"-m",
uv_bin,
"pip",
"install",
"--disable-pip-version-check",
"--python",
sys.executable,
]
add_verbosity_flag(command, verbosity, adjustment=-1)
command.extend(dependencies)
Expand Down