Repository navigation
Description
This is the parent issue for tracking parity with Pylint. Below, we've enumerated all Pylint rules.
Rules that are checked off have been implemented in Ruff already (either as a Pylint rule, e.g., PLE0237, or by way of overlap with another linter like Pyflakes, as with missing-format-string-key).
Rules that are crossed out have been removed some consideration. (In most cases, crossed-out rules represent Pylint specific rules, e.g., rules related to Pylint configuration.)
At time of writing, many of the remaining rules require type inference and/or multi-file analysis, and aren't ready to be implemented in Ruff. (See: #970 (comment) for an enumeration.) If you're looking to start work on a specific rule, I'd suggest commenting in the issue, to get some input on whether Ruff is capable of supporting it at present.
For guidance on getting started, see the Contributing documentation.
Note: Don't implement rules that are part of Pylint extension until #1774 is completed. Don't implement rules that mainly target Python 2.
Error
-
abstract-class-instantiated/E0110 -
access-member-before-definition/E0203 -
assigning-non-slot/E0237(PLE0237) -
assignment-from-no-return/E1111 -
assignment-from-none/E1128 -
await-outside-async/E1142(PLE1142) -
bad-configuration-section/E0014 -
bad-except-order/E0701 -
bad-exception-cause/E0705 -
bad-format-character/E1300(PLE1300) -
bad-plugin-value/E0013 -
bad-reversed-sequence/E0111 -
bad-str-strip-call/E1310(PLE1310) -
bad-string-format-type/E1307(PLE1307) -
(mainly targets Python 2)bad-super-call/E1003 -
bidirectional-unicode/E2502(PLE2502) -
broken-collections-callable/E6005 -
broken-noreturn/E6004 -
catching-non-exception/E0712 -
class-variable-slots-conflict/E0242 -
continue-in-finally/E0116(PLE0116) -
dict-iter-missing-items/E1141 -
duplicate-argument-name/E0108 -
duplicate-bases/E0241(PLE0241) -
format-needs-mapping/E1303(F502) -
function-redefined/E0102(F811) -
import-error/E0401 -
inconsistent-mro/E0240 -
inherit-non-class/E0239 -
init-is-generator/E0100(PLE0100) -
invalid-all-format/E0605(PLE0605) -
invalid-all-object/E0604(PLE0604) -
invalid-bool-returned/E0304(PLE0304) -
invalid-bytes-returned/E0308(PLE0308) -
invalid-character-backspace/E2510(PLE2510) -
invalid-character-carriage-return/E2511 -
invalid-character-esc/E2513(PLE2513) -
invalid-character-nul/E2514(PLE2514) -
invalid-character-sub/E2512(PLE2512) -
invalid-character-zero-width-space/E2515(PLE2515) -
invalid-class-object/E0243 -
invalid-enum-extension/E0244 -
invalid-envvar-value/E1507 -
invalid-format-returned/E0311 -
invalid-getnewargs-ex-returned/E0313 -
invalid-getnewargs-returned/E0312 -
invalid-hash-returned/E0309(PLE0309) -
invalid-index-returned/E0305(PLE0305) -
invalid-length-hint-returned/E0310 -
invalid-length-returned/E0303(PLE0303) -
invalid-metaclass/E1139 -
invalid-repr-returned/E0306 -
invalid-sequence-index/E1126 -
invalid-slice-index/E1127 -
invalid-slice-step/E1144 -
invalid-slots/E0238 -
invalid-slots-object/E0236 -
invalid-star-assignment-target/E0113 -
invalid-str-returned/E0307 -
invalid-unary-operand-type/E1130 -
invalid-unicode-codec/E2501 -
logging-format-truncated/E1201 -
logging-too-few-args/E1206(PLE1206) -
logging-too-many-args/E1205(PLE1205) -
logging-unsupported-format/E1200 -
method-hidden/E0202 -
misplaced-bare-raise/E0704(PLE0704) -
misplaced-format-function/E0119 -
missing-format-string-key/E1304(F524) -
missing-kwoa/E1125 -
mixed-format-string/E1302(F506) -
modified-iterating-dict/E4702 -
modified-iterating-set/E4703(PLE4703) -
no-member/E1101 -
no-method-argument/E0211 -
no-name-in-module/E0611 -
no-self-argument/E0213(N805) -
no-value-for-parameter/E1120 -
non-iterator-returned/E0301 -
nonexistent-operator/E0107(B002) -
nonlocal-and-global/E0115(PLE0115) -
nonlocal-without-binding/E0117(PLE0117) -
not-a-mapping/E1134 -
not-an-iterable/E1133 -
not-async-context-manager/E1701 -
not-callable/E1102 -
not-context-manager/E1129 -
not-in-loop/E0103(F701,F702) -
notimplemented-raised/E0711(F901) -
potential-index-error/E0643(PLE0643) -
raising-bad-type/E0702 -
raising-non-exception/E0710 -
redundant-keyword-arg/E1124 -
relative-beyond-top-level/E0402(TID252) -
repeated-keyword/E1132(PLE1132) -
return-arg-in-generator/E0106 -
return-in-init/E0101(PLE0101) -
return-outside-function/E0104(F706) -
singledispatch-method/E1519(PLE1519) -
singledispatchmethod-function/E1520(PLE1520) -
star-needs-assignment-target/E0114(syntax error in preview) -
syntax-error/E0001(always enabled) -
too-few-format-args/E1306(F524) -
too-many-format-args/E1305(F522) -
too-many-function-args/E1121 -
too-many-star-expressions/E0112(F622) -
truncated-format-string/E1301(F501) -
undefined-all-variable/E0603(F822) -
undefined-variable/E0602(F821) -
unexpected-keyword-arg/E1123 -
unexpected-special-method-signature/E0302(PLE0302) -
unhashable-member/E1143 -
unpacking-non-sequence/E0633 -
unsubscriptable-object/E1136 -
unsupported-assignment-operation/E1137 -
unsupported-binary-operation/E1131 -
unsupported-delete-operation/E1138 -
unsupported-membership-test/E1135 -
used-before-assignment/E0601(F821) -
used-prior-global-declaration/E0118(PLE0118) -
yield-inside-async-function/E1700(PLE1700) -
yield-outside-function/E0105(F704)
Warning
-
abstract-method/W0223 -
anomalous-backslash-in-string/W1401(W605) -
anomalous-unicode-escape-in-string/W1402 -
arguments-differ/W0221 -
arguments-out-of-order/W1114 -
arguments-renamed/W0237 -
assert-on-string-literal/W0129(PLW0129) -
assert-on-tuple/W0199(F631) -
attribute-defined-outside-init/W0201 -
bad-builtin/W0141 -
bad-chained-comparison/W3601 -
bad-dunder-name/W3201(PLW3201) -
bad-format-string/W1302(F521) -
bad-format-string-key/W1300 -
bad-indentation/W0311(E111) -
bad-open-mode/W1501(PLW1501) -
bad-staticmethod-argument/W0211(PLW0211) -
bad-thread-instantiation/W1506 -
bare-except/W0702(E722) -
binary-op-exception/W0711(PLW0711) -
boolean-datetime/W1502 -
broad-exception-caught/W0718(BLE001) -
broad-exception-raised/W0719(TRY002) -
cell-var-from-loop/W0640(B023) -
comparison-with-callable/W0143 -
confusing-with-statement/W0124 -
consider-ternary-expression/W0160(SIM108) -
dangerous-default-value/W0102(B006) -
deprecated-argument/W4903 -
deprecated-class/W4904 -
deprecated-decorator/W4905 -
deprecated-method/W4902 -
deprecated-module/W4901 -
deprecated-typing-alias/W6001 -
differing-param-doc/W9017 -
differing-type-doc/W9018 -
duplicate-except/W0705(B014) -
duplicate-key/W0109(F601) -
duplicate-string-formatting-argument/W1308 -
duplicate-value/W0130(B033) -
eq-without-hash/W1641(PLW1641) -
eval-used/W0123(S307) -
exec-used/W0122(S102) -
expression-not-assigned/W0106(B018) -
f-string-without-interpolation/W1309(F541) -
fixme/W0511(FIX001,FIX002,FIX003,FIX004) -
forgotten-debug-statement/W1515(T100) -
format-combined-specification/W1305(F525) -
format-string-without-interpolation/W1310(F541) -
global-at-module-level/W0604(PLW0604) -
global-statement/W0603(PLW0603) -
global-variable-not-assigned/W0602(PLW0602) -
global-variable-undefined/W0601 -
implicit-str-concat/W1404(ISC001) -
import-self/W0406(PLW0406) -
inconsistent-quotes/W1405(Q000) -
invalid-envvar-default/W1508(PLW1508) -
invalid-format-index/W1307 -
invalid-overridden-method/W0236 -
isinstance-second-argument-not-valid-type/W1116 -
keyword-arg-before-vararg/W1113(B026) -
logging-format-interpolation/W1202(G001) -
logging-fstring-interpolation/W1203(G004) -
logging-not-lazy/W1201(G002) -
lost-exception/W0150(B012) -
method-cache-max-size-none/W1518(B019) -
misplaced-future/W0410(F404) -
missing-any-param-doc/W9021 -
missing-format-argument-key/W1303(F524) -
missing-format-attribute/W1306 -
missing-param-doc/W9015 -
missing-parentheses-for-call-in-test/W0126 -
missing-raises-doc/W9006 -
(Pylint extension)missing-return-doc/W9011 -
missing-return-type-doc/W9012 -
missing-timeout/W3101 -
missing-type-doc/W9016 -
missing-yield-doc/W9013 -
missing-yield-type-doc/W9014 -
modified-iterating-list/W4701 -
multiple-constructor-doc/W9005 -
named-expr-without-context/W0131(PLW0131) -
nan-comparison/W0177(PLW0177) -
nested-min-max/W3301(PLW3301) -
non-ascii-file-name/W2402(N999) -
non-parent-init-called/W0233 -
non-str-assignment-to-dunder-name/W1115 -
overlapping-except/W0714 -
overridden-final-method/W0239 -
pointless-exception-statement/W0133(PLW0133) -
pointless-statement/W0104(B018) -
pointless-string-statement/W0105 -
possibly-unused-variable/W0641 -
preferred-module/W0407 -
protected-access/W0212(SLF001) -
raise-missing-from/W0707(B904) -
raising-format-tuple/W0715 -
redeclared-assigned-name/W0128 -
redefined-builtin/W0622(A001) -
redefined-loop-name/W2901(PLW2901) -
redefined-outer-name/W0621 -
redefined-slots-in-subclass/W0244 -
redundant-returns-doc/W9008 -
redundant-u-string-prefix/W1406(UP025) -
redundant-unittest-assert/W1503 -
redundant-yields-doc/W9010 -
reimported/W0404(F811) -
self-assigning-variable/W0127(PLW0127) -
self-cls-assignment/W0642 -
shallow-copy-environ/W1507 -
signature-differs/W0222 -
subclassed-final-class/W0240 -
subprocess-popen-preexec-fn/W1509(PLW1509) -
subprocess-run-check/W1510(PLW1510) -
super-init-not-called/W0231 -
super-without-brackets/W0245(PLW0245) -
too-many-try-statements/W0717 -
try-except-raise/W0706(TRY302) -
unbalanced-dict-unpacking/W0644 -
unbalanced-tuple-unpacking/W0632 -
undefined-loop-variable/W0631 -
unknown-option-value/W0012 -
unnecessary-ellipsis/W2301(`PIE790) -
unnecessary-lambda/W0108(PLW0108) -
unnecessary-pass/W0107(PIE790) -
unnecessary-semicolon/W0301(E703) -
unreachable/W0101 -
unspecified-encoding/W1514(PLW1514) -
unused-argument/W0613(ARG001) -
unused-format-string-argument/W1304(F507) -
unused-format-string-key/W1301(F504) -
unused-import/W0611(F401) -
unused-private-member/W0238 -
unused-variable/W0612(F841) -
unused-wildcard-import/W0614 -
useless-else-on-loop/W0120(PLW0120) -
useless-param-doc/W9019 -
useless-parent-delegation/W0246 -
useless-type-doc/W9020 -
useless-with-lock/W2101(PLW2101) -
using-constant-test/W0125 -
using-f-string-in-unsupported-version/W2601 -
using-final-decorator-in-unsupported-version/W2602 -
while-used/W0149 -
wildcard-import/W0401(F403) -
wrong-exception-operation/W0716
Convention
-
bad-classmethod-argument/C0202(N804) -
bad-docstring-quotes/C0198(Q002) -
bad-file-encoding/C2503 -
bad-mcs-classmethod-argument/C0204 -
bad-mcs-method-argument/C0203 -
compare-to-empty-string/C1901(PLC1901) -
compare-to-zero/C2001 -
consider-iterating-dictionary/C0201(SIM118) -
consider-using-any-or-all/C0501(SIM110,SIM111) -
consider-using-dict-items/C0206(PLC0206) -
consider-using-enumerate/C0200 -
consider-using-f-string/C0209 -
dict-init-mutate/C3401 -
disallowed-name/C0104 -
docstring-first-line-empty/C0199(D210) -
empty-docstring/C0112(D419) -
import-outside-toplevel/C0415(PLC0415) -
import-private-name/C2701(PLC2701) -
invalid-characters-in-docstring/C0403 -
invalid-name/C0103(N815) -
line-too-long/C0301(E501) -
misplaced-comparison-constant/C2201(SIM300) -
missing-class-docstring/C0115(D101) -
missing-final-newline/C0304(W292) -
missing-function-docstring/C0116(D103) -
missing-module-docstring/C0114(D100) -
mixed-line-endings/C0327 -
multiple-imports/C0410(E401) -
multiple-statements/C0321(E701,E702) -
non-ascii-module-import/C2403(PLC2403) -
non-ascii-name/C2401(PLC2401) -
single-string-used-for-slots/C0205(PLC0205) -
singleton-comparison/C0121(E711,E712) -
superfluous-parens/C0325 -
(not compatible with the formatter)too-many-lines/C0302 -
trailing-newlines/C0305(W391) -
trailing-whitespace/C0303(W291) -
typevar-double-variance/C0131(PLC0131) -
typevar-name-incorrect-variance/C0105(PLC0105) -
typevar-name-mismatch/C0132(PLC0132) -
unexpected-line-ending-format/C0328 -
ungrouped-imports/C0412(I001) -
unidiomatic-typecheck/C0123(E721) -
unnecessary-direct-lambda-call/C3002(PLC3002) -
unnecessary-dunder-call/C2801(PLC2801) -
unnecessary-lambda-assignment/C3001(E731) -
unneeded-not/C0113(SIM208) -
use-implicit-booleaness-not-comparison/C1803 -
use-implicit-booleaness-not-len/C1802(PLC1802) -
use-maxsplit-arg/C0207(PLC0207) -
use-sequence-for-iteration/C0208(PLC0208) -
useless-import-alias/C0414(PLC0414) -
wrong-import-order/C0411(I001) -
wrong-import-position/C0413(E402) -
wrong-spelling-in-comment/C0401 -
wrong-spelling-in-docstring/C0402
Refactor
-
chained-comparison/R1716 -
comparison-of-constants/R0133(PLR0133) -
comparison-with-itself/R0124(PLR0124) -
condition-evals-to-constant/R1727 -
confusing-consecutive-elif/R5601 -
consider-alternative-union-syntax/R6003(UP007) -
consider-merging-isinstance/R1701(SIM101) -
consider-swap-variables/R1712(PLR1712) -
consider-using-alias/R6002(UP006) -
consider-using-assignment-expr/R6103 -
consider-using-augmented-assign/R6104(PLR6104) -
consider-using-dict-comprehension/R1717(C402) -
consider-using-from-import/R0402(PLR0402) -
consider-using-generator/R1728(C417) -
consider-using-get/R1715(SIM401) -
consider-using-in/R1714(PLR1714) -
consider-using-join/R1713 -
consider-using-min-builtin/R1730(PLR1730) -
consider-using-max-builtin/R1731(PLR1730) -
consider-using-namedtuple-or-dataclass/R6101 -
consider-using-set-comprehension/R1718(C401) -
consider-using-sys-exit/R1722(PLR1722) -
consider-using-ternary/R1706(PLR1706) -
consider-using-tuple/R6102 -
consider-using-with/R1732(SIM115) -
cyclic-import/R0401 -
duplicate-code/R0801 -
else-if-used/R5501(PLR5501) -
empty-comment/R2044(PLR2044) -
inconsistent-return-statements/R1710(RET501,RET502) -
literal-comparison/R0123(F632) -
magic-value-comparison/R2004(PLR2004) -
no-classmethod-decorator/R0202(PLR0202) -
no-else-break/R1723(RET508) -
no-else-continue/R1724(RET507) -
no-else-raise/R1720(RET506) -
no-else-return/R1705(RET505) -
no-self-use/R6301(PLR6301) -
no-staticmethod-decorator/R0203(PLR0203) -
property-with-parameters/R0206(PLR0206) -
redefined-argument-from-local/R1704(PLR1704) -
redefined-variable-type/R0204 -
simplifiable-condition/R1726 -
simplifiable-if-expression/R1719(SIM210,SIM211) -
simplifiable-if-statement/R1703(SIM108) -
simplify-boolean-expression/R1709 -
stop-iteration-return/R1708 -
super-with-arguments/R1725(UP008) -
too-complex/R1260(C901) -
too-few-public-methods/R0903 -
too-many-ancestors/R0901(requires multifile analysis) -
too-many-arguments/R0913(PLR0913) -
too-many-boolean-expressions/R0916(PLR0916) -
too-many-positional-arguments/R0917(PLR0917) -
too-many-branches/R0912(PLR0912) -
(requires Rule categorization #1774)too-many-instance-attributes/R0902 -
too-many-locals/R0914(PLR0914) -
too-many-nested-blocks/R1702(PLR1702) -
too-many-public-methods/R0904(PLR0904) -
too-many-return-statements/R0911(PLR0911) -
too-many-statements/R0915(PLR0915) -
trailing-comma-tuple/R1707(COM818) -
unnecessary-comprehension/R1721(C416) -
use-a-generator/R1729(C419) -
unnecessary-dict-index-lookup/R1733(PLR1733) -
use-list-literal/R1734(C405) -
use-dict-literal/R1735(C406) -
unnecessary-list-index-lookup/R1736(PLR1736) -
use-yield-from/R1737(UP028) -
use-set-for-membership/R6201(PLR6201) -
useless-object-inheritance/R0205(UP004) -
useless-option-value/R0022 -
useless-return/R1711(PLR1711)
Activity
charliermarsh commentedon Nov 30, 2022
Need to figure out what the right "check code" approach is here. We could just start to put these under
RUF. Or we could doPYEfor "Pylint Error", and so on. Or we could usePYLfor all of them. In either case, though, we have to allow four-digit codes, as opposed to our current three-digit codes.JonathanPlasse commentedon Nov 30, 2022
I vote for
PYEas it would keep the same categories and the migration would be easier.harupy commentedon Dec 1, 2022
I'll work on
unneeded-notthis weekend.relsunkaev commentedon Dec 1, 2022
I would suggest
PLas the pylint prefix (PLE->PyLintError). I thinkPYEmight be a bit ambiguous withPYflakes,PYdocstyle, etc.MartinBernstorff commentedon Dec 1, 2022
Would absolutely love to see this happen. I know flake8 intentionally decided not to implement e.g.
unexpected-keyword-argbecause it required looking outside of the current file for imported functions.I expect you've already considered this, and really hope this won't stop ruff from implementing it, but just wanted to raise it.
charliermarsh commentedon Dec 1, 2022
@relsunkaev 👍 Went with
PLE! The first code is checked in asPLE1142(matchingE1142from Pylint).charliermarsh commentedon Dec 1, 2022
@MartinBernstorff - Definitely. The multi-file stuff will come, just not as quickly.
hmc-cs-mdrissi commentedon Dec 8, 2022
Not sure if it should be separate issue, but looking at missing-function-docstring rule (C0116), pylint's version of it is different. It only requires that a function has docstring some in class hierarchy and does not require over-ridden methods to have a docstring. As an example,
gives no errors in pylint even though second validate is missing docstring being pylint allows inheriting one. This is very useful when implementing interface and the docstring would really be same for all things that subclass.
charliermarsh commentedon Jan 5, 2023
I'd like to get
pointless-statement,unnecessary-ellipsis, andunnecessary-passin.charliermarsh commentedon Jan 5, 2023
Relevant source for defining a
pointless-statement: https://github.com/PyCQA/pylint/blob/56121344f6c9c223d8e4477c0cdb58c46c840b4b/pylint/checkers/base/basic_checker.py#L447thejcannon commentedon Jan 12, 2023
A while ago I set out to find all the pylint codes make redundant by type checking.
Unfortunately that code got lost to the sands of time.
You might consider skipping those as type checking tools are very sophisticated, if you can do the effort of compiling that list
thejcannon commentedon Jan 12, 2023
I've also thought very long and hard about the fact that pylint appears very sophisticated when it comes to types because it builds on
astroidwhich works very hard to infer types based on code (pre-type-annotations)Ideally ruff (or any modern linter) is type-aware to be as helpful as possible, but that requires either:
444 remaining items
Implement pylint import-outside-toplevel rule (C0415) (#5180)
[pylint] Implement redefined-argument-from-local (R1704) (#8159)
[`pylint`] Add PLE1141 `DictIterMissingItems` (#9845)
[`pylint`] Implement `if-stmt-min-max` (`PLR1730`, `PLR1731`) (#10002)
[`pylint`] Implement `invalid-bytes-returned` (`E0308`) (#10959)
[`pylint`] Implement `invalid-length-returned` (`E0303`) (#10963)
[`pylint`] Implement `invalid-hash-returned` (`PLE0309`) (#10961)
[`pylint`] Implement `invalid-index-returned` (`PLE0305`) (#10962)
[`pylint`] Implement `missing-maxsplit-arg` (`PLC0207`) (#17454)
NeilGirdhar commentedon May 23, 2026
Now that Ty is very usable, it might be worth it to check off everything that Ty does. Also, this issue is so long that it might be worth starting a new one with an updated list of Pylint codes.
oehlschl commentedon Jul 28, 2026
PR for W0105 (pointless-string-statement): #27253
[`pylint`] Implement `missing-maxsplit-arg` (`PLC0207`) (#17454)
feat(#4): configure pylint to defer to ruff's enabled rules and mirro…
[`pylint`] Implement `no-method-argument` (`PLE0211`) (#29748)
BLKSerene commentedon Nov 13, 2026
no-method-argument/E0211(PLE0211) could be checked off now, as it was implemented in #29748 and released in Ruff 0.17.5.possibly-used-before-assignment/E0606is missing from the list (mentioned in several comments above).The following rules are missing the corresponding Ruff rule (mentioned somewhere above):
dict-iter-missing-items/E1141(PLE1141)invalid-envvar-value/E1507(PLE1507)invalid-str-returned/E0307(PLE0307)redefined-slots-in-subclass/W0244(PLW0244)self-cls-assignment/W0642(PLW0642)shallow-copy-environ/W1507(PLW1507)stop-iteration-return/R1708(PLR1708)And a bit of nitpicking:
unnecessary-ellipsis/W2301(`PIE790) is missing one backtick (afterPIE790).wrong-import-position/C0413(E402) is not formatted properly (extra space afterE402).singleton-comparison/C0121(E711,E712) is not formatted properly (extra space afterE711).