PyTorch: Allow `matches` in `[[sub-config]]` to accept a list of paths/globs
- Dominant language
- Rust
- Stars
- 7k
- Forks
- 516
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
In `pyrefly.toml`, a `[[sub-config]]` block's `matches` key takes a single string. That string can be a glob, but there is no way to give one sub-config several distinct (unglobbed) file paths. The only workaround is to copy the entire `[sub-config.errors]` block once per file, which makes real-world configs enormously repetitive.
## Motivation / real example
The PyTorch pyrefly config (`pyrefly.toml`, based on `mypy.ini`) has **36 `[[sub-config]]` blocks**, and **31 of them have a byte-identical error body**:
```toml
[[sub-config]]
matches = "torch/_numpy/linalg.py"
[sub-config.errors]
implicit-import = false
implicit-any = true
bad-param-name-override = false
unannotated-return = true
unannotated-parameter = true
unannotated-attribute = true
[[sub-config]]
matches = "torch/_numpy/_reductions_impl.py"
[sub-config.errors]
implicit-import = false
implicit-any = true
bad-param-name-override = false
unannotated-return = true
unannotated-parameter = true
unannotated-attribute = true
# ... 29 more copies of the same six lines
```
Another 4 blocks share a different identical body:
```toml
[[sub-config]]
matches = "torch/_dynamo/**" # and torch/_dispatch/**, torch/_subclasses/**, torch/_functorch/**
[sub-config.errors]
implicit-import = false
implicit-any = true
```
The files being listed are genuinely unrelated paths (`torch/_numpy/*.py`, `torch/_export/**`, `torch/utils/_sympy/*.py`, `torch/optim/*.py`, `torch/_lazy/**`, ...), so a single glob cannot express the set — and a broad glob like `torch/_numpy/**` would be wrong, because it would pull in files that aren't ready for the stricter settings yet. So the duplication isn't a stylistic choice; it's forced.
Consequences:
- ~200 lines of copy-paste in one config file.
- Changing the shared policy (e.g. enabling `unannotated-attribute` in a later version, as the TODO in the dynamo section anticipates) means a 31-site edit, and any missed site silently diverges.
- Adding a newly-clean file to the strict set means pasting a 7-line stanza rather than adding one entry.
## Proposed fix
Let `matches` accept either a string or an array of strings, with array semantics being "this sub-config applies if any entry matches":
```toml
[[sub-config]]
matches = [
"torch/fx/**",
"torch/_lazy/**",
"torch/_inductor/fx_passes/serialized_patterns/**",
"torch/_numpy/linalg.py",
"torch/_numpy/_reductions_impl.py",
"torch/_numpy/fft.py",
# ...
"torch/optim/_functional.py",
]
[sub-config.errors]
implicit-import = false
implicit-any = true
bad-param-name-override = false
unannotated-return = true
unannotated-parameter = true
unannotated-attribute = true
```
That collapses the PyTorch config's 36 sub-configs down to roughly 3.
This mirrors what `project-includes` / `project-excludes` already do (both are lists of paths-or-globs), so the config language stays internally consistent and users don't have to remember which keys are scalar and which are lists.
## Notes / open questions
- Backwards compatible: a bare string should keep working, so existing configs are untouched. In serde terms this is an untagged `enum { One(String), Many(Vec) }` (or `#[serde(with = "string_or_seq")]`) on the `matches` field, plus updating the matcher to test any-of. This looks like a small, contained change — hence "pretty easy fix."
- **Precedence:** when a file is matched by more than one sub-config, the existing precedence rule should apply unchanged; a list entry should behave exactly as if it were its own single-`matches` sub-config with the same body. Worth stating explicitly in the docs, since lists make overlaps more likely.
- **Empty list:** `matches = []` should probably be a config error rather than a silently-inert sub-config.
- Docs for `sub-config` / `matches` need updating alongside the change, and a test covering a multi-entry `matches` plus the string form still parsing.
If a list is undesirable for some reason, the alternative that solves the same problem is named, reusable error profiles (define a settings bundle once, reference it from several sub-configs) — but the list form is the smaller change and matches existing config conventions.
PyTorch file https://github.com/pytorch/pytorch/blob/main/pyrefly.toml
cc @aorenste
Contributor guide
Assessment
This issue has not been assessed yet.