tach icon indicating copy to clipboard operation
tach copied to clipboard

FR: add support for dependency-groups

Open sk- opened this issue 11 months ago β€’ 3 comments

Now that PEP 735 has been accepted, it would be great to support it in tach. Specially given that uv already supports dependency-groups.

In our use case we have several groups to better control out dependencies, for example we have a test group and a scripts group.

We are currently checking external dependencies with the command uv run tach check-external -e "**/*test*,**/scripts", because otherwise tach complains that pytest and other dependencies are not available.

My proposal is to add support for dependency groups in the following way to the tach.toml config file:

[external.groups]
scripts = ["**/scripts"]
test = ["**/*test*.py"]

Which would mean that files matching **/scripts would also have access to the dependencies defined in the scripts group.

Note that in the proposal above, dependencies present in the default group will be available to all files.

I could see how that may not fit all use cases, and maybe a more flexible approach would be to define it the other way around, as in

[external.groups]
"**/scripts" = ["scripts", "default"]
"**/*test*.py" = ["test", "default"]
"*" = ["default"]

In that approach, we would map file patterns to available groups, where patterns are matched from the top.

sk- avatar Jan 24 '25 14:01 sk-

I know this issue has been open a while, but we are closer to supporting this. Recent work gives us a more natural way to handle config from pyproject.toml, and we have globbing in module paths, so the way I would think about this is like:

[[modules]]
path = "**.scripts"
external_depends_on = ["@scripts"]

where external_depends_on would need to be implemented as an analog to depends_on, and "@scripts" would be resolved to a 'scripts' dependency group from the package containing each module matching "**.scripts"

emdoyle avatar Feb 28 '25 18:02 emdoyle

Thanks @emdoyle for the update. I have a follow up question, how would this work for tests?

In our case we have the tests inside the modules, in a folder called test (eg module_a/test/). In other places I've seen tests to be next to the source code within the module (eg module_a/some_logic_test.py).

Finally, that would mean that for the toplevel conftest.py, we would need to define it's own module?

sk- avatar Mar 03 '25 14:03 sk-

@sk- I generally exclude test files using exclude, which also accepts globs, and is a top-level configuration option in tach.toml. However, you can also 'overwrite' module configuration for tests by defining something like:

[[modules]]
path = "**.*test*

near the bottom of your tach.toml (later definitions take precedence over earlier definitions). This definition would match a module at any level which includes "test" in its name. This would allow you to have test-specific configuration, even when the test files would have otherwise matched earlier globs.

There is no way to refer to dynamic values like 'sibling' or 'parent' modules within a globbed definition at this moment though.

Does this answer your questions?

emdoyle avatar Mar 04 '25 06:03 emdoyle