Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions docs/config/environment/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,21 @@ You can modify options based on the conditions of different sources like [matrix

The [type](#types) of the selected option determines the types of values.

For options without declared type information, use a table with a `value` key. Known options such as `extra-args` have
declared types and support the standard typed override syntax:

```toml config-example
[tool.hatch.envs.test.overrides]
matrix.mode.extra-args = [
{ value = "-q", if = ["quiet"] },
{ value = "-vv", if = ["verbose"] },
]
```

Each matching entry adds its string to the argument array. Multiple matching entries are applied in order. The previous
single-table form, such as `extra-args = { value = ["-q"], if = ["quiet"] }`, remains supported temporarily and emits a
deprecation warning.

### Platform overrides

Options can be modified based on the current platform using the `platform` source.
Expand Down
1 change: 1 addition & 0 deletions docs/history/hatch.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

***Fixed:***

- Support conditional array values for the built-in `extra-args` environment option
- Fix syncing environment plugin requirements on standalone binaries built to forward to `pip`

## [1.18.1](https://github.com/pypa/hatch/releases/tag/hatch-v1.18.1) - 2026-09-16 ## {: #hatch-v1.18.1 }
Expand Down
19 changes: 19 additions & 0 deletions src/hatch/project/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from functools import cached_property
from os import environ
from typing import TYPE_CHECKING, Any
from warnings import warn

from hatch.utils.platform import get_platform_name

Expand All @@ -19,6 +20,7 @@
"env-exclude": list,
"env-include": list,
"env-vars": dict,
"extra-args": list,
"features": list,
"lock-filename": str,
"locker": str,
Expand Down Expand Up @@ -53,6 +55,23 @@ def apply_overrides(env_name, source, condition, condition_value, options, new_c
_apply_override_to_workspace(
env_name, option, data, source, condition, condition_value, new_config, overwrite
)
elif option == "extra-args" and isinstance(data, dict) and "value" in data:
# Preserve the legacy untyped syntax during the compatibility period.
warn(
"The single-table conditional syntax for `extra-args` is deprecated and will be removed in a "
"future release; use an array of conditional string entries instead.",
DeprecationWarning,
stacklevel=2,
)
value = data["value"]
if not isinstance(value, list) or not all(isinstance(item, str) for item in value):
message = (
f"Option `value` in field `tool.hatch.envs.{env_name}.overrides.{source}."
f"{condition}.{option}` must be an array of strings"
)
raise TypeError(message)
if _resolve_condition(env_name, option, source, condition, condition_value, data):
new_config[option] = value
elif override_type in TYPE_OVERRIDES:
TYPE_OVERRIDES[override_type](
env_name, option, data, source, condition, condition_value, new_config, overwrite
Expand Down
41 changes: 41 additions & 0 deletions tests/project/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,47 @@ def test_overrides_matrix_array_table_conditional(self, isolation, option):
assert project_config.envs == expected_envs
assert project_config.matrices["foo"] == construct_matrix_data("foo", env_config)

def test_overrides_matrix_extra_args_conditional(self, isolation):
env_config = {
"foo": {
"extra-args": ["--base"],
"matrix": [{"mode": ["quiet", "verbose"]}],
"overrides": {
"matrix": {
"mode": {
"extra-args": [
{"value": "-q", "if": ["quiet"]},
{"value": "-vv", "if": ["verbose"]},
]
}
}
},
}
}
project_config = ProjectConfig(isolation, {"envs": env_config}, PluginManager())

assert project_config.envs == {
"default": {"type": "virtual"},
"foo.quiet": {"type": "virtual", "extra-args": ["--base", "-q"]},
"foo.verbose": {"type": "virtual", "extra-args": ["--base", "-vv"]},
}

def test_overrides_matrix_extra_args_legacy_syntax(self, isolation):
env_config = {
"foo": {
"matrix": [{"mode": ["quiet", "verbose"]}],
"overrides": {"matrix": {"mode": {"extra-args": {"value": ["-q"], "if": ["quiet"]}}}},
}
}
project_config = ProjectConfig(isolation, {"envs": env_config}, PluginManager())

with pytest.warns(DeprecationWarning, match="single-table conditional syntax for `extra-args`"):
assert project_config.envs == {
"default": {"type": "virtual"},
"foo.quiet": {"type": "virtual", "extra-args": ["-q"]},
"foo.verbose": {"type": "virtual"},
}

@pytest.mark.parametrize("option", ARRAY_OPTIONS)
def test_overrides_matrix_array_table_conditional_with_platform(self, isolation, option, current_platform):
env_config = {
Expand Down
Loading