Repository: tox-dev/tox-uv

Issue:
`uv_sync_flags` and tox 4.21 native toml configuration
I tested passing groups to `uv_sync_flags` with this configuration (with the new [tox 4.21 native toml configuration support](https://github.com/tox-dev/tox/issues/999)), as suggested in #113, but without success at the moment:

```toml
[tool.tox.env.doc]
runner = "uv-venv-lock-runner"
uv_sync_flags = ["--group=doc"]
commands = [
    ["sphinx-build", "--builder", "html", "doc", "build/sphinx/html"],
    ["sphinx-build", "--builder", "man", "doc", "build/sphinx/html"],
]
```

It fails with `TypeError: '--group=doc' is not list`.

When passing a simple string like `uv_sync_flags = "--group=doc"` it also fails with the same error message.

_Originally posted by @azmeuk in https://github.com/tox-dev/tox-uv/discussions/114#discussioncomment-11084270_

Discussion:

Patch:
diff --git a/README.md b/README.md
index ab251b7..a877124 100644
--- a/README.md
+++ b/README.md
@@ -99,6 +99,10 @@ A list of string that selects, which extra groups you want to install with `uv s
 
 A boolean flag to toggle installation of the `uv` development dependencies. By default, it is false.
 
+### `dependency_groups`
+
+Specify [PEP 735 – Dependency Groups](https://peps.python.org/pep-0735/) to install.
+
 ### `uv_sync_flags`
 
 A list of strings, containing additional flags to pass to uv sync (useful because some flags are not configurable via
diff --git a/src/tox_uv/_run_lock.py b/src/tox_uv/_run_lock.py
index 9dafafd..cac5eb3 100644
--- a/src/tox_uv/_run_lock.py
+++ b/src/tox_uv/_run_lock.py
@@ -3,7 +3,7 @@
 from __future__ import annotations
 
 from pathlib import Path
-from typing import TYPE_CHECKING, cast
+from typing import TYPE_CHECKING, List, Set, cast  # noqa: UP035
 
 from tox.execute.request import StdinSource
 from tox.tox_env.python.package import SdistPackage, WheelPackage
@@ -44,9 +44,15 @@ class UvVenvLockRunner(UvVenv, RunToxEnv):
             default=False,
             desc="Install dev dependencies or not",
         )
+        self.conf.add_config(
+            keys=["dependency_groups"],
+            of_type=Set[str],  # noqa: UP006
+            default=set(),
+            desc="dependency groups to install of the target package",
+        )
         self.conf.add_config(
             keys=["uv_sync_flags"],
-            of_type=list[str],
+            of_type=List[str],  # noqa: UP006
             default=[],
             desc="Additional flags to pass to uv sync (for flags not configurable via environment variables)",
         )
@@ -64,6 +70,8 @@ class UvVenvLockRunner(UvVenv, RunToxEnv):
             cmd.append("--no-install-project")
         if self.options.verbosity > 3:  # noqa: PLR2004
             cmd.append("-v")
+        for group in sorted(self.conf["dependency_groups"]):
+            cmd.extend(("--group", group))
         cmd.extend(self.conf["uv_sync_flags"])
         show = self.options.verbosity > 2  # noqa: PLR2004
         outcome = self.execute(cmd, stdin=StdinSource.OFF, run_id="uv-sync", show=show)


Test patch:
diff --git a/tests/test_tox_uv_lock.py b/tests/test_tox_uv_lock.py
index dd42f25..1539d88 100644
--- a/tests/test_tox_uv_lock.py
+++ b/tests/test_tox_uv_lock.py
@@ -167,3 +167,69 @@ def test_uv_sync_extra_flags(tox_project: ToxProjectCreator) -> None:
         ("py", "commands[0]", ["python", "hello"]),
     ]
     assert calls == expected
+
+
+def test_uv_sync_extra_flags_toml(tox_project: ToxProjectCreator) -> None:
+    project = tox_project({
+        "tox.toml": """
+    [env_run_base]
+    runner = "uv-venv-lock-runner"
+    with_dev = true
+    uv_sync_flags = ["--no-editable", "--inexact"]
+    commands = [["python", "hello"]]
+    """
+    })
+    execute_calls = project.patch_execute(lambda r: 0 if r.run_id != "venv" else None)
+    result = project.run()
+    result.assert_success()
+
+    calls = [(i[0][0].conf.name, i[0][3].run_id, i[0][3].cmd) for i in execute_calls.call_args_list]
+    uv = find_uv_bin()
+
+    expected = [
+        (
+            "py",
+            "venv",
+            [uv, "venv", "-p", sys.executable, "--allow-existing", str(project.path / ".tox" / "py")],
+        ),
+        (
+            "py",
+            "uv-sync",
+            ["uv", "sync", "--frozen", "--no-editable", "--inexact"],
+        ),
+        ("py", "commands[0]", ["python", "hello"]),
+    ]
+    assert calls == expected
+
+
+def test_uv_sync_dependency_groups(tox_project: ToxProjectCreator) -> None:
+    project = tox_project({
+        "tox.toml": """
+    [env_run_base]
+    runner = "uv-venv-lock-runner"
+    with_dev = true
+    dependency_groups = ["test", "type"]
+    commands = [["python", "hello"]]
+    """
+    })
+    execute_calls = project.patch_execute(lambda r: 0 if r.run_id != "venv" else None)
+    result = project.run()
+    result.assert_success()
+
+    calls = [(i[0][0].conf.name, i[0][3].run_id, i[0][3].cmd) for i in execute_calls.call_args_list]
+    uv = find_uv_bin()
+
+    expected = [
+        (
+            "py",
+            "venv",
+            [uv, "venv", "-p", sys.executable, "--allow-existing", str(project.path / ".tox" / "py")],
+        ),
+        (
+            "py",
+            "uv-sync",
+            ["uv", "sync", "--frozen", "--group", "test", "--group", "type"],
+        ),
+        ("py", "commands[0]", ["python", "hello"]),
+    ]
+    assert calls == expected