TRF029

A module taking config must not also take arguments that live on the config.

   
Default Enabled
Scope Models added on or after 2026-06-20
Source mlinter/trf029.py
Show in terminal mlinter --rule TRF029

What it does

In modeling_*.py and modular_*.py, flags an __init__ that accepts config alongside an argument whose name is unambiguously a config field (hidden_size, num_attention_heads, intermediate_size, head_dim, num_hidden_layers, embed_dim, dropout, eps, patch_size, rope_theta, …). kosmos2 is allowlisted because its doc page (kosmos-2.md) cannot be derived from the directory name, so the cutoff cannot grandfather it.

Why is this bad?

The same number now has two sources of truth and the caller decides which one wins, so editing the config no longer changes the model that gets built. It also makes every call site carry architecture knowledge that belongs inside the module, which is why reviewers ask for it on new models over and over.

Example

 class AcmeAttention(nn.Module):
-    def __init__(self, config, embed_dim, num_heads, dropout):
+    def __init__(self, config, layer_idx=None):
         super().__init__()
-        self.embed_dim = embed_dim
-        self.num_heads = num_heads
+        self.embed_dim = config.hidden_size
+        self.num_heads = config.num_attention_heads

Suppressing this rule

Add a # trf-ignore: TRF029 comment on the flagged line or the line directly above it. See Suppressing rules for whole-file directives and when a suppression is the wrong answer.

Allowlisted models

1 model are exempt from TRF029 in mlinter/rules.toml, because they predate the convention and cannot be changed without breaking backward compatibility.

Show the 1 allowlisted model
  • kosmos2