Question Details

No question body available.

Tags

python lint ruff

Answers (2)

January 12, 2026 Score: 1 Rep: 21,497 Quality: Medium Completeness: 100%

The closest to "one size fits all" is to simply accept the defaults. I often encourage colleagues to do that, as I feel that a project running ruff check is much better than nothing, and I wouldn't want "false alarms" to annoy engineers to the point that they turn off linting for their project.

There are two important axes to consider:

  1. "old" vs "new" project
  2. level of commitment to Quality that team members have

Enabling tons of "picky" or "pedantic" lint rules on a new project is easy, because nothing will trigger. And next week when you do see some unfamiliar rule start triggering, you can safely decide to ignore it or not, decide whether it is helpful or noise. Essentially, make a value judgement about whether a human PR reviewer would likely have flagged that code.

Enabling lint rules on a mature project is rather more challenging. You have to triage. Maybe "bless" or "grandfather in" code that works but won't lint clean. Maybe apply more rules to newly written modules, and fewer rules to the maintenance edits of mature modules. Maybe devote some time to a cleanup effort.

If team members have diverse levels of code development maturity, there's a good chance that project management will have to lay down the law and say, "Quality matters. Your code will lint clean." The folks doing PR code review prior to merging a feature to main can help with such a culture change. So does a Makefile which will "break the build" on edits that don't lint cleanly. Eventually folks get used to it. Gently ease them into the new pattern, with a smallish set of lint rules, which can be expanded later as team confidence builds.

So the simple best practices answer is, "use the defaults".

The answer you're looking for is, "add rule groups that you find helpful". As you observed, we desire a relatively simple config. Looking at so many configured ignores of D100 through D213, I'd be more inclined to omit the D group entirely, on the grounds that I don't agree with it or it produces unhelpful lint noise.

Note that to get "all" rules, some might require: ruff check --preview

I'm happy to share the set of rules that I routinely use.


nit: I recommend sorting your entries.

I imagine that D213 followed by COM812 relates to the chronological order in which you were exploring the ruff check configuration space. For most aspects of a code base, if "order doesn't matter", then I will try to reveal that to maintenance engineers by lexically sorting. For example, in Emacs it's M-x sort-lines.

That way there is a single, obvious place to insert a new entry. And it reduces git merge conflicts.

On a similar topic, I try to end comma-separated lists with a trailing comma, even when it's not required. It just makes future diffs easier to read.


Other linters to consider: pyright, mypy


In a similar vein, you might want to pay attention to pytest --cov code coverage measurements. It's not hard to achieve 90% coverage of newly written code.

If it does prove hard to cover your new code, there's usually something wrong with it, something you want to fix. If it is "impossible" to get an except clause to run, maybe the Public API is not yet properly parameterized, in a way that would make it possible. Or maybe we shouldn't be catching that exception down at this level at all. And sometimes I will sequester "hard to cover" code into its own module, to simplify reporting and acting on the coverage measurements.

January 12, 2026 Score: 0 Rep: 67,686 Quality: Low Completeness: 40%

Good point if one disables many rule of a type to ignore them all as a starting point. Reading further though the docs, it's possible to ignore all the D-rules but cherry pick specific ones via lint.extend-select = ["Dxxx", "Dyyy"] (xxx and yyy refer to the relevant number of a rule).