huggingface / huggingface/transformers-mlinter
Cutoff exemption should follow inheritance: a new model is flagged for a base class owned by a grandfathered model
- Dominant language
- Python
- Stars
- 6
- Forks
- 12
- Avg merge
- 10h 28m
- Merged PRs (30d)
- 19
Description
Reported by devs
> Imo the cut off date especially led to some weird interactions, e.g. when the parent is wrong but saved by the cutoff date and now the new model is flagged.
>
> For example autodocstrings should be at top level models but based on older models we skip too graciously and building on top of them now has a weird dependency chain
This is a real defect rather than the cutoff being too gracious, and it is worth fixing on its own.
## Diagnosis
`is_exempt_by_cutoff()` keys on **the file being linted**, not on **where the offending code was authored**. Rules that resolve a base class into another model's directory therefore report the violation against whichever model happens to subclass it — which is always the newer, non-exempt one — while the model that actually owns the structure stays grandfathered.
Concrete, from a `transformers` checkout of 2026-08-25 with cutoffs neutralised (13 TRF034 findings of this shape):
- `DFineRepVggBlock(RTDetrRepVggBlock)`, `DFineAIFILayer(RTDetrAIFILayer)`, `DFineDecoderLayer(RTDetrDecoderLayer)` — the bases are plain `nn.Module` in `rt_detr`
- `Deimv2ConvNormLayer(DFineConvNormLayer)`, `Deimv2RepVggBlock`, `Deimv2AIFILayer` — bases in `d_fine`
- `PPLCNetV3ConvLayer`, `PPOCRV5ServerRecConvLayer`, `SLANetConvLayer` — bases in `pp_lcnet`, `convnext`, `resnet`
The author of the new model cannot fix any of these without editing the parent model, which is out of scope for their PR — so the only ways out are a model-wide allowlist entry or a suppression comment, both of which mute the rule permanently for a model that did nothing wrong.
TRF057 (`@auto_docstring`, 393 findings hidden by the cutoff) has the same shape through modular inheritance, which is the case the feedback names directly.
## Proposal
Make the exemption follow inheritance: when a rule resolves a base class into another model's directory and the verdict comes from that base, evaluate the exemption against **the file where the base is defined**, not the file being linted. Concretely, a helper next to `is_exempt_by_cutoff()` that takes the defining file, plus use of it in the rules that already walk cross-model bases (TRF034 today; TRF057 and any future inheritance-resolving rule).
This loosens nothing that is currently enforced: the parent's own file is still checked under the parent's own cutoff and allowlist. It only stops attributing inherited structure to the wrong model.
## Related
- TRF034 has a second, unrelated cause (the `Layer`/`Block` suffix heuristic) tracked in #54.
- The separate question of whether the cutoff hides too much is tracked in #57.
Contributor guide
Assessment
This issue has not been assessed yet.