[ty] Allow overriding rules for specific files by MichaReiser · Pull Request #18648 · astral-sh/ruff (original) (raw)
Summary
This PR adds a new [[overrides]] configuration section that allows users to toggle rules at a file/path level.
[tool.ty.rules] division-by-zero = "error"
First override: all test files
[[tool.ty.overrides]] include = ["tests/**"]
[tool.ty.overrides.rules] division-by-zero = "warn"
Second override: specific test file (takes precedence)
[[tool.ty.overrides]] include = ["tests/important.py"]
[tool.ty.overrides.rules] division-by-zero = "ignore"
A file can match zero or many overrides sections. Later overrides take precedence over earlier overrides. Overrides inherit from the global configuration.
I thought long whether we should allow at most one match (always taking the last) or multiple matches. I did some ecosystem research to see how per-file-ignores is used. The most common pattern that I've found is too disable some rules for a sub directory and within that subdirectory, disable more rules for specific files. From airflow:
"src/tests_common/*" = ["S101", "TRY002"]
Test compat imports banned imports to allow testing against older airflow versions
"src/tests_common/test_utils/compat.py" = ["TID251", "F401"] "src/tests_common/pytest_plugin.py" = ["F811"]
This is why I ultimately decided to allow multiple matches. This complicates the implementation a bit but not too much. The main downside is that it will make it harder to warn if combining two overrides results in incompatible options because the validation happens lazily.
The other downside is that it there's no real way override an existing match other than overriding every single. E.g. when the user configuration has an overrides that a project wants to override. I think that this is less common and we could consider introducing an option that would mark an overrides as the "root", so that ty doesn't apply any more overrides.
Closes astral-sh/ty#178
Glob syntax
I decided to use the same include and exclude syntax as we use at the src level. Technically, a single include option that allows both positive and negative patterns would be enough (and negative excludes doesn't really make sense). However, I opted for the src syntax because I think a familiar syntax is important: It woudl be confusing if we allow different glob patterns in different include fields.
Naming
I went with overrides, similar to what mypy uses (although mypy filters on modules not paths). I think the name is fine but overrides are something entirely different in uv.
I'm curious to hear more opinions. Alternatives are:
filessub_configurations- ...?