pypa / hatch

Modern, extensible Python project management
https://hatch.pypa.io/latest/
MIT License
5.83k stars 288 forks source link

Nested project-local venv paths #715

Open hynek opened 1 year ago

hynek commented 1 year ago

Since we've bruised this topic a few times including Twitter, I think it's better to open a proper issue.

To reiterate: for packages, I need predictable paths such that my way of measuring coverage works in dev-mode=false. With tox, I've solved it by setting:

[tool.coverage.paths]
source = ["src", ".tox/py*/**/site-packages"]

With Hatch, the venvs live somewhere else entirely.

Now you've mentioned a few times that I can use virtual's path option.

But I just can't make it work. Consider this pyproject.toml:

[tool.hatch.envs.default]
type = "virtual"
path = ".hatch-venvs"
dev-mode = false

[tool.hatch.envs.tests]
features = ["tests"]

[[tool.hatch.envs.tests.matrix]]
python = ["3.7", "3.8", "3.9", "3.10", "3.11"]

[tool.hatch.envs.tests.scripts]
all = "python -m pytest"

When I run hatch run tests:all, Hatch claims to be running tests.py3.10 etc, however what happens is that it creates a single Python 3.7 venv at .hatch-venvs and uses it for all tests. So the matrix is really just a for loop. Independently from my use-case this looks like a bug.

I see mentions of flat virtualenvs to placate IDEs but they seem to be contradicting other docs.

So, it is possible to have a matrix with an in-project venv tree at all?

I tried moving the path setting to the tests table, but that doesn't help either.


To clarify, what I'd like to see with the config above is the following:

.hatch-venvs/tests.py3.7
.hatch-venvs/tests.py3.8
.hatch-venvs/tests.py3.9
.hatch-venvs/tests.py3.10
.hatch-venvs/tests.py3.11
ofek commented 1 year ago

Option 2 of https://hatch.pypa.io/latest/plugins/environment/virtual/#location

hynek commented 1 year ago

You mean:

A directory named after the environment within the configured virtual environment directory if the directory resides somewhere within the project root or if it is set to a .virtualenvs directory within the user's home directory

?

I honestly do not understand what that means. It reads like "what I want is impossible, because the path points to the project directory" so I'm double-checking.

ofek commented 1 year ago

Sorry work is really busy right now but here's a full example https://hatch.pypa.io/latest/blog/2022/10/08/hatch-v160/#virtual-environment-location

hynek commented 1 year ago

Right, but that requires setting a global configuration option to work.

Would you consider adding a way to set the matrix path per-project too? Otherwise I can't use Hatch's Environments features with public packages.

hynek commented 1 year ago

To elaborate a little, to me and my workflows, the current logic is kinda inverted of what I want.

I'm not in the business of telling people where to keep their project venvs in general. So a user might want to configure that globally for themselves. Either leave it centralized or use a well-known project-local venv path:

[dirs.env]
virtual = ".virtualenv"

But when doing Tox-style nested matrixes with coverage run --parallel, I want to be able to overwrite it:

[tool.hatch.envs.tests]
features = ["tests"]
path = ".hatch-matrix"

[[tool.hatch.envs.tests.matrix]]
python = ["3.7", "3.8", "3.9", "3.10", "3.11"]

[tool.hatch.envs.tests.scripts]
all = "python -m coverage run --parallel pytest"

And then refer to it using:

[tool.coverage.paths]
source = ["src", ".hatch-matrix/tests.*/**/site-packages"]

That would be the ideal solution for me. Does that make sense to you?

No worries about busy, I have [tn]ox for the time being. :)

johannesloibl commented 1 year ago

I feel this is somehow supposed to work when using the env_name context variable inside the path option, like path = ".hatch/{env_name}". Nevertheless the string does not get formatted. This might be because the environment formatter at https://github.com/pypa/hatch/blob/master/src/hatch/env/context.py#L29 seem to be nowhere applied in the entire project.