Following on from the discussion on #746, this is a draft proposal to start disabling certain messages by default. Furthermore, to make it easier to run pylint side by side with flake8, we want to document which messages are duplicated in flake8 and possible make them easier to disable as a group.
The following table contains every pylint message excluding those from plugins and py3k checks. For each message it is noted whether it is a style check or a functional check (by functional I mean it validates some sort of run time behaviour of the code being linted or checks for programmer mistakes) or other (when it's technically a style check but I don't think we would want to disable it when a user opts out of style checks, or if the message doesn't fit in the other categories), whether it duplicates a message in flake8, and my opinion on whether I think it should be disabled by default so that we can use it as a discussion point. I normally prefer the linter to be quite strict so it might be worth gathering user feedback on this. Another option would be to give messages levels of strictness and you pick a level to lint at.
Message Name | Message ID | Style or Functional or Other | flake8 ID | Disable by Default | Notes
--- | --- | --- | --- | --- | ---
blacklisted-name | C0102 | S | | N |
invalid-name | C0103 | S | | N |
empty-docstring | C0112 | S | | Y |
unneeded-not | C0113 | O | F713 | N |
missing-module-docstring | C0114 | S | "D100,D104" | Y |
missing-class-docstring | C0115 | S | "D101,D106" | Y |
missing-function-docstring | C0116 | S | "D102,D103,D105" | Y |
singleton-comparison | C0121 | S | | N |
misplaced-comparison-constant | C0122 | S | | N |
unidiomatic-typecheck | C0123 | F | | N |
non-ascii-name | C0144 | F | | N |
consider-using-enumerate | C0200 | O | | N |
consider-iterating-dictionary | C0201 | O | | N |
bad-classmethod-argument | C0202 | O | | Y |
bad-mcs-method-argument | C0203 | O | | N |
bad-mcs-classmethod-argument | C0204 | O | | Y |
single-string-used-for-slots | C0205 | F | | N |
line-too-long | C0301 | S | E501 | N |
too-many-lines | C0302 | S | | N |
trailing-whitespace | C0303 | S | "W291,W293" | N |
missing-final-newline | C0304 | S | W292 | N |
trailing-newlines | C0305 | S | | N |
multiple-statements | C0321 | O | E701 | N |
superfluous-parens | C0325 | S | | N |
bad-whitespace | C0326 | S | "E201,E202,E225" | Remove |
mixed-line-endings | C0327 | O | | N |
unexpected-line-ending-format | C0328 | O | | N |
bad-continuation | C0330 | S | E129 | Remove |
wrong-spelling-in-comment | C0401 | O | | Y | Sort of disabled by default already because it requires enchant
wrong-spelling-in-docstring | C0402 | O | | Y | Sort of disabled by default already because it requires enchant
invalid-characters-in-docstring | C0403 | O | | Y | Sort of disabled by default already because it requires enchant
multiple-imports | C0410 | O | | N |
wrong-import-order | C0411 | S | I202 | Y |
ungrouped-imports | C0412 | S | | Y |
wrong-import-position | C0413 | S | | Y |
useless-import-alias | C0414 | O | | N |
import-outside-toplevel | C0415 | O | | N |
len-as-condition | C1801 | O | | N |
syntax-error | E0001 | F | | N |
unrecognized-inline-option | E0011 | F | | N |
bad-option-value | E0012 | F | | N |
init-is-generator | E0100 | F | | N |
return-in-init | E0101 | F | | N |
function-redefined | E0102 | F | | N |
not-in-loop | E0103 | F | | N |
return-outside-function | E0104 | F | | N |
yield-outside-function | E0105 | F | | N |
nonexistent-operator | E0107 | F | | N |
duplicate-argument-name | E0108 | F | | N |
abstract-class-instantiated | E0110 | F | | N |
bad-reversed-sequence | E0111 | F | | N | Check false positive rate?
too-many-star-expressions | E0112 | F | | N |
invalid-star-assignment-target | E0113 | F | | N |
star-needs-assignment-target | E0114 | F | | N |
nonlocal-and-global | E0115 | F | | N |
continue-in-finally | E0116 | F | | N |
nonlocal-without-binding | E0117 | F | | N |
used-prior-global-declaration | E0118 | F | | N |
misplaced-format-function | E0119 | F | | N |
method-hidden | E0202 | F | | N |
access-member-before-definition | E0203 | F | | N |
no-method-argument | E0211 | F | | N |
no-self-argument | E0213 | O | | N |
invalid-slots-object | E0236 | F | | N |
assigning-non-slot | E0237 | F | | N |
invalid-slots | E0238 | F | | N |
inherit-non-class | E0239 | F | | N |
inconsistent-mro | E0240 | F | | N |
duplicate-bases | E0241 | F | | N |
class-variable-slots-conflict | E0242 | F | | N |
non-iterator-returned | E0301 | F | | N |
unexpected-special-method-signature | E0302 | F | | N |
invalid-length-returned | E0303 | F | | N |
invalid-bool-returned | E0304 | F | | N |
invalid-index-returned | E0305 | F | | N |
invalid-repr-returned | E0306 | F | | N |
invalid-str-returned | E0307 | F | | N |
invalid-bytes-returned | E0308 | F | | N |
invalid-hash-returned | E0309 | F | | N |
invalid-length-hint-returned | E0310 | F | | N |
invalid-format-returned | E0311 | F | | N |
invalid-getnewargs-returned | E0312 | F | | N |
invalid-getnewargs-ex-returned | E0313 | F | | N |
import-error | E0401 | F | | Y |
relative-beyond-top-level | E0402 | F | | N |
used-before-assignment | E0601 | F | | N |
undefined-variable | E0602 | F | F821 | N |
undefined-all-variable | E0603 | F | | N |
invalid-all-object | E0604 | F | | N |
no-name-in-module | E0611 | F | | N |
unpacking-non-sequence | E0633 | | | |
bad-except-order | E0701 | F | | N |
raising-bad-type | E0702 | F | | N |
bad-exception-context | E0703 | F | | N |
misplaced-bare-raise | E0704 | F | | N |
raising-non-exception | E0710 | F | | N |
notimplemented-raised | E0711 | F | | N |
catching-non-exception | E0712 | F | | N |
bad-super-call | E1003 | F | | N |
no-member | E1101 | F | | Y | Raises lots of false positives
not-callable | E1102 | F | | N |
assignment-from-no-return | E1111 | O | | N |
no-value-for-parameter | E1120 | F | | N |
too-many-function-args | E1121 | F | | N |
unexpected-keyword-arg | E1123 | F | | N |
redundant-keyword-arg | E1124 | F | | N |
missing-kwoa | E1125 | F | | N |
invalid-sequence-index | E1126 | F | | N |
invalid-slice-index | E1127 | F | | N |
assignment-from-none | E1128 | F | | N |
not-context-manager | E1129 | F | | N |
invalid-unary-operand-type | E1130 | F | | N |
unsupported-binary-operation | E1131 | F | | N |
repeated-keyword | E1132 | F | | N |
not-an-iterable | E1133 | F | | N |
not-a-mapping | E1134 | F | | N |
unsupported-membership-test | E1135 | F | | N |
unsubscriptable-object | E1136 | F | | N |
unsupported-assignment-operation | E1137 | F | | N |
unsupported-delete-operation | E1138 | F | | N |
invalid-metaclass | E1139 | F | | N |
unhashable-dict-key | E1140 | F | | N |
dict-iter-missing-items | E1141 | F | | N |
logging-unsupported-format | E1200 | F | | N |
logging-format-truncated | E1201 | F | | N |
logging-too-many-args | E1205 | F | | N |
logging-too-few-args | E1206 | F | | N |
bad-format-character | E1300 | F | | N |
truncated-format-string | E1301 | F | | N |
mixed-format-string | E1302 | F | | N |
format-needs-mapping | E1303 | F | | N |
missing-format-string-key | E1304 | F | | N |
too-many-format-args | E1305 | F | | N |
too-few-format-args | E1306 | F | | N |
bad-string-format-type | E1307 | F | | N |
bad-str-strip-call | E1310 | F | | N |
invalid-envvar-value | E1507 | F | | N |
yield-inside-async-function | E1700 | F | | N |
not-async-context-manager | E1701 | F | | N |
fatal | F0001 | F | | N |
astroid-error | F0002 | F | | N |
parse-error | F0010 | F | | N |
method-check-failed | F0202 | F | | N |
raw-checker-failed | I0001 | F | | N |
bad-inline-option | I0010 | F | | N |
locally-disabled | I0011 | F | | N |
file-ignored | I0013 | F | | N |
suppressed-message | I0020 | F | | N |
useless-suppression | I0021 | F | | N |
deprecated-pragma | I0022 | F | | N |
use-symbolic-message-instead | I0023 | F | | N |
c-extension-no-member | I1101 | F | | Y | Raises lots of false positives without configuration
literal-comparison | R0123 | F | | N |
comparison-with-itself | R0124 | F | | N |
no-self-use | R0201 | F | | N |
no-classmethod-decorator | R0202 | O | | N |
no-staticmethod-decorator | R0203 | O | | N |
useless-object-inheritance | R0205 | O | | N | "Worth documenting disabling this in a ""supporting Python 2"" section?"
property-with-parameters | R0206 | O | | N |
cyclic-import | R0401 | F | | N |
duplicate-code | R0801 | O | | Y | I find this creates false positives (for things like import groups) more than it helps find duplicate code.
too-many-ancestors | R0901 | O | | Y | "It's often too hard to fix this without making significant design changes which often is not possible."
too-many-instance-attributes | R0902 | O | | Y | "It's often too hard to fix this without making significant design changes which often is not possible."
too-few-public-methods | R0903 | O | | Y | I agree with this one but some find it opinionated.
too-many-public-methods | R0904 | O | | Y | "It's often too hard to fix this without making significant design changes which often is not possible."
too-many-return-statements | R0911 | O | | Y | I find this is often fixed by arbitrarily splitting up the function in more functions that do not add value.
too-many-branches | R0912 | O | C901 | Y | I find this is often fixed by arbitrarily splitting up the function in more functions that do not add value.
too-many-arguments | R0913 | O | | Y | "It's often too hard to fix this without making significant design changes which often is not possible."
too-many-locals | R0914 | O | | Y |
too-many-statements | R0915 | O | | Y |
too-many-boolean-expressions | R0916 | O | | Y |
consider-merging-isinstance | R1701 | O | | N |
too-many-nested-blocks | R1702 | O | | Y |
simplifiable-if-statement | R1703 | O | | N |
redefined-argument-from-local | R1704 | F | | N |
no-else-return | R1705 | O | | N |
consider-using-ternary | R1706 | O | | N |
trailing-comma-tuple | R1707 | F | | N |
stop-iteration-return | R1708 | F | | N |
simplify-boolean-expression | R1709 | O | | N |
inconsistent-return-statements | R1710 | S | | Y |
useless-return | R1711 | S | | N |
consider-swap-variables | R1712 | O | | N |
consider-using-join | R1713 | O | | N |
consider-using-in | R1714 | O | | N |
consider-using-get | R1715 | O | | N |
chained-comparison | R1716 | O | | N |
consider-using-dict-comprehension | R1717 | O | | N |
consider-using-set-comprehension | R1718 | O | | N |
simplifiable-if-expression | R1719 | O | | N |
no-else-raise | R1720 | O | | N |
unnecessary-comprehension | R1721 | O | | N |
consider-using-sys-exit | R1722 | O | | N |
no-else-break | R1723 | O | | N |
no-else-continue | R1724 | O | | N |
else-if-used | R5501 | O | | N |
unreachable | W0101 | F | | N |
dangerous-default-value | W0102 | F | | N |
pointless-statement | W0104 | F | | N |
pointless-string-statement | W0105 | F | | N |
expression-not-assigned | W0106 | F | | N |
unnecessary-pass | W0107 | O | | N |
unnecessary-lambda | W0108 | F | | |
duplicate-key | W0109 | F | | |
assign-to-new-keyword | W0111 | F | | N |
useless-else-on-loop | W0120 | F | | N |
exec-used | W0122 | F | | N | Arguably opinionated?
eval-used | W0123 | F | | N | Arguably opinionated?
confusing-with-statement | W0124 | F | | N |
using-constant-test | W0125 | F | | N |
missing-parentheses-for-call-in-test | W0126 | F | | N |
self-assigning-variable | W0127 | F | | N |
redeclared-assigned-name | W0128 | F | | N |
assert-on-string-literal | W0129 | F | | N |
comparison-with-callable | W0143 | F | | N | Check false positive rate?
lost-exception | W0150 | F | | N |
assert-on-tuple | W0199 | F | | N |
attribute-defined-outside-init | W0201 | F | | N |
bad-staticmethod-argument | W0211 | O | | N |
protected-access | W0212 | F | | N |
arguments-differ | W0221 | F | | N |
signature-differs | W0222 | F | | N |
abstract-method | W0223 | F | | N |
super-init-not-called | W0231 | F | | N |
no-init | W0232 | F | | N |
non-parent-init-called | W0233 | F | | N |
useless-super-delegation | W0235 | O | | N |
invalid-overridden-method | W0236 | F | | N |
unnecessary-semicolon | W0301 | S | E703 | N |
bad-indentation | W0311 | S | E111 | Y |
mixed-indentation | W0312 | S | W191 | Remove |
wildcard-import | W0401 | F | | N |
deprecated-module | W0402 | F | | N |
reimported | W0404 | F | | N |
import-self | W0406 | F | | N |
preferred-module | W0407 | F | | N |
misplaced-future | W0410 | F | | N |
fixme | W0511 | O | | Y |
global-variable-undefined | W0601 | F | | N |
global-variable-not-assigned | W0602 | O | | N |
global-statement | W0603 | O | | Y |
global-at-module-level | W0604 | F | | Y |
unused-import | W0611 | F | F401 | N |
unused-variable | W0612 | F | F841 | N |
unused-argument | W0613 | F | | N |
unused-wildcard-import | W0614 | F | | N |
redefined-outer-name | W0621 | F | | N |
redefined-builtin | W0622 | F | | N |
redefine-in-handler | W0623 | F | | N |
undefined-loop-variable | W0631 | F | | N |
unbalanced-tuple-unpacking | W0632 | F | | N |
cell-var-from-loop | W0640 | F | | N |
possibly-unused-variable | W0641 | F | | N |
self-cls-assignment | W0642 | F | | N |
bare-except | W0702 | F | E722 | N |
broad-except | W0703 | F | | N |
duplicate-except | W0705 | F | | N |
try-except-raise | W0706 | F | | N |
binary-op-exception | W0711 | F | | N |
raising-format-tuple | W0715 | F | | N |
wrong-exception-operation | W0716 | F | | N |
keyword-arg-before-vararg | W1113 | F | | N |
arguments-out-of-order | W1114 | F | | N |
non-str-assignment-to-dunder-name | W1115 | F | | N |
isinstance-second-argument-not-valid-type | W1116 | F | | N |
logging-not-lazy | W1201 | F | | N |
logging-format-interpolation | W1202 | F | | N |
logging-fstring-interpolation | W1203 | F | | N |
bad-format-string-key | W1300 | F | | N |
unused-format-string-key | W1301 | F | | N |
bad-format-string | W1302 | F | | N |
missing-format-argument-key | W1303 | F | | N |
unused-format-string-argument | W1304 | F | | N |
format-combined-specification | W1305 | O | | N |
missing-format-attribute | W1306 | F | | N |
invalid-format-index | W1307 | F | | N |
duplicate-string-formatting-argument | W1308 | O | | N |
f-string-without-interpolation | W1309 | O | | N |
anomalous-backslash-in-string | W1401 | O | | N |
anomalous-unicode-escape-in-string | W1402 | O | | N |
implicit-str-concat | W1404 | O | | N |
inconsistent-quotes | W1405 | S | | Y |
bad-open-mode | W1501 | F | | N |
boolean-datetime | W1502 | F | | N |
redundant-unittest-assert | W1503 | F | | N |
deprecated-method | W1505 | F | | N |
bad-thread-instantiation | W1506 | F | | N |
shallow-copy-environ | W1507 | F | | N |
invalid-envvar-default | W1508 | F | | N |
subprocess-popen-preexec-fn | W1509 | F | | N |
subprocess-run-check | W1510 | O | | N |
Great issue, I think we could add a column for "remove entirely". For example, I think that everything regarding formatting that can be done by black could be safely removed from the codebase. Black fix it automatically, are we ever going to want to report errors that can be fixed automatically by a tool? Someone that does not know about black could take a painfully long time to apply pep8 manually. At the very least we should tell users to install black to do it (maybe in the score to not spam it in every message).
Also, everything that has false-positive should really be disabled until it's fixed, because it makes adoption harder for most people and because Pylint is not supposed to be a linter that annoys you :)
I very much agree with the comment on the ticket you linked that we should create multiple configuration profiles. Maybe even disable message when we detect the presence of installed package (isort, flake8 and black, maybe others ?)
The automatic disabling based on what's installed is a good idea. I like that. We should implement a way of disabling that behaviour but that should be easy enough to do.
Hey @AWhetter This is a great list, thank you so much for working on it!
Here are some of my notes regarding checks that could be disabled by default or removed entirely:
bad-classmethod-argument and bad-mcs-classmethod-argument Disable by default.bad-whitespace and bad-continuationwrong-import-order and related import order checks
Disable by default. Requires isort to be up-to-date regarding to what is a third party import or not.
import-outside-toplevel
This is actually useful, why do you think it should be disabled by default? In the codebases that I've worked with, it was always better to move the imports at the top, especially since a lot of them were stdlib ones.
import-error Disable by default. Requires a much better import engine to figure out when something actually doesn't exist. Maybe it can be lumped together with no-member.
no-member Agree that we should disable it by default as it has perhaps the most false positives in our checks.raw-checker-failed You marked as disabled by default, but why? It indicates to the user that a module could not be checked since it's not pure Python. too-few-* and too-many-* With some of them I agree that they should be disabled by default, but too-few-public-methods usually indicates that a class can just be a function.fixme Maybe we should remove this entirely.global-at-module-level and global-used What's wrong with these ones? mixed-indentation Can be removed entirely at this point.To answer @Pierre-Sassoulas I don't believe we should remove the formatting category wholesale regardless if the community aggregated around the use of black.
There are still folks out there that would want black to be more configurable, especially since it has some dubious choices in terms of what kind of refactoring it yields in certain contexts.
If I'd remove something from the formatting checks it would definitely be bad-whitespace and bad-indentation. I believe they don't add that much value and they always require some fiddling around to support whatever PEP 8 suggests. Tools like pycodestyle and black should deal with this mess.
In the long term, a stages solution similar to the one suggested in #746 is definitely my preferred solution, but for now disabling or removing some of these checks works as well.
but too-few-public-methods usually indicates that a class can just be a function.
When the framework expects a class to modify a base behavior (like Django for model's Metaclass) you can't do that. Or see this answer on Stack with 30+ upvote that tells you to disable too-few-public-methods without thinking every time you inherit from a class. I think there is a lot of false positive for this one.
I might have got a little carried away with removing all the formatting messages. Probably not everyone uses black+flake8+isort :)
Also, I agree that the stages gamify the lint even more and that's probably a good thing to be able to do. But I also like the standard style proposed here. Because in an IDE you won't be able to do 4 steps (Unless pylint switch stage alone ? It would be confusing to have errors appear. Just imagine having a junior create a "core" error in order to make the next stage errors disappear.).
That would probably mean pylint is a lot harder to integrate and understand. I read a blog article aimed toward beginner that said, and I paraphrase, "pylint is useless without configuration, so just use flake8". To address this I think pylint should be easier to use for first-time users or if you don't even know you're using pylint because it's integrated in your IDE. The very knowledgable users are already tailoring it to their need so we can just keep taking their pylintrc into account.
So being able to be able to say that you want to follow the "well-known company" style and have pylint behave accordingly would be a huge simplification. I also think the stages are great when you launch pylint yourself, but will be very hard to integrate in an IDE.
@PCManticore Thanks for checking through the list. I've incorporated some of your changes:
bad-classmethod-argument and bad-mcs-classmethod-argument are disabled by default.
bad-whitespace and bad-continuation we're doing in #3571
wrong-import-order and friends are disabled by default.
import-outside-toplevel is enabled by default. I don't know why I put is as disabled.
import-error is disabled by default.
raw-checker-failed is enabled. I misunderstood what this check was doing.
too-few-public-methods: As @Pierre-Sassoulas mentioned, I know that for a long time it would get raised on a class that inherited from something else. But this case is fine because usually you're trying to override some behaviour of the base class. I don't know if this is still the case? If not then I agree that we should keep this enabled.
fixme: I think this has value for some people but it's hard to say without usage metrics. I don't use it.
global-at-module-level and global-used were disabled because I think globals are used often enough that some people find this check is an opinionated one. I don't like globals. I think they cause problems and I would turn this check back on. But if enough people find it annoying then I think it makes sense to make it an opt-in check.
mixed-indentation is marked as removable.
To address this I think pylint should be easier to use for first-time users
I agree with this whole heartedly.
This list includes errors from flake8-docstrings and flake8-import-order so it should probably denote those and also add error codes from pep8-naming
In addition having an automatic checker that turns off duplicate errors from other install checkers would be awesome but in the meantime, just a page in the docs that shows which to turn off with each checker would be supremely helpful.
Just to add to the discussion as to a sane / useful default configuration. My current config has led to very few false positives and make pylint a joy for me.
--disable=design, format, bare-except, unneeded-not, undefined-variable, unused-import, unused-variable, missing-module-docstring, missing-class-docstring, missing-function-docstring, no-self-argument, invalid-name, bad-classmethod-argument, bad-mcs-classmethod-argument
Design section is false positives galore for me.... so disabling that got rid of most annoyances of pylint
Format section has been ceded to black
All the rest are duplicate messages with flake8 (mccabe, pep8-naming, and flake8-docstring plugins are enabled)
Since using this config, pylint has close to 100% rate of helpful and useful messages.
It looks like all of the design section in the above table by @AWhetter was marked as "should be disabled by default". Would that be a welcome PR? Looks like a good first issue for me in pylint. Or does more discussion need to happen slash I'm jumping the gun?
I think a PR would be welcome, there seems to be a lot of messages where everyone agrees that it should be disabled by default. Thank you for being willing to contribute to Pylint :)
@Pierre-Sassoulas I don't think we reached a consensus on disabling the design checkers just yet. There are still valuable checks in that category that ought to be enabled by default, and the most contentious ones were too-few-public-methods and those related to class hierarchy.
@PCManticore No worries, I made a PR for if and when a consensus is reached on disabling the design checker.
Which design messages do you think merit being enabled by default? From what I've seen most people who are using them change the default parameters for pretty much all of them. If the messages are that individualistic, I think it makes an argument for them to be enabled on an individual basis.
Following up on this issue. I noticed that in the OP by @AWhetter all the design checker messages are recommend to be disabled by default. I created a PR to disable the category by default #3650 since I find pylint to be infinitely more sane this way. @Pierre-Sassoulas approved my PR but wanted another reviewer before merging. @PCManticore chimed in and didn't think we had a consensus to disable design by default yet. So to spur some more conversation along these lines: Which of the design checks does anyone find should remain enabled? (I can look to modifying my PR to include those).
The messages in questions are: too-few-public-methods, too-many-public-methods, too-many-return-statements, too-many-branches, too-many-arguments, too-many-locals, too-many-statements (all are refactoring related checks)
I might have been unclear, I think too-many-return-statements, too-many-branches, too-many-arguments, too-many-locals, too-many-statements are all useful indication of high level design flaw (maybe encompassed by the Mc Cabe complexity metric though), too-many-public-methods as well. Only, too-few-public-methods is unavoidable if you use inheritance a lot, or if you use django (Meta in Model or Form) and I think this one should be disabled.
Would you say that these checks are highly individualistic depending on the project? It seems that it isn't possible to have good defaults since how many is too-many or too-few varies so much project to project. If a user is going to configure these defaults, they would also be able to enable them. However, for someone who is looking for a pip-and-play option, these messages can be a nuisance. My view is without proper individual configuration these checks ought to be disabled.
I just found this issue while looking for something else and I just wanted to chime in a bit. Ages ago I wrote prospector to wrap around all the various other tools, mostly pylint but including mccabe and flake8 and so on and so on.
One of the things I added was 'profiles' which was designed to do two things:
1) have configurable strictness with some presets which would turn off checks by default, with configurable 'high' and 'low' ones which would add or remove some of the warnings. https://github.com/PyCQA/prospector/tree/master/prospector/profiles/profiles
2) allow inheritance so you could have a project-default and a per-repo default which inherits from it. The idea was that the tool starts with a set of defaults, then you can configure them for your own project, and perhaps specialise further based on company/project principles to add specific behaviour for one repository in that group. See http://prospector.landscape.io/en/master/profiles.html . This might address @danrneal 's point that there is no one-size-fits all - at least, this inheritance was my attempt to deal with that.
Similarly, because prospector ran many tools with overlapping functionality, I ended up creating a 'blender' to try to piece together when two or more tools were giving the same error message. The list of errors and codes from tools representing the same thing is in this file: https://github.com/PyCQA/prospector/blob/master/prospector/blender_combinations.yaml . I'm not sure if this is still up to date but it might serve as a useful starting point.
Prospector has been slowly adding bugfixes and keeping up with the tools it depends on, but hasn't been getting the new features it did when I started writing it. Having said that, pylint and others have adapted the 'quality of life' features I built in to it so there's not as much need any more.
I bring this up as I started putting in several of the concepts in this issue into prospector a while ago, and so there may be useful things to look at and pick through in case there's any useful things.
Most helpful comment
@Pierre-Sassoulas I don't think we reached a consensus on disabling the design checkers just yet. There are still valuable checks in that category that ought to be enabled by default, and the most contentious ones were
too-few-public-methodsand those related to class hierarchy.