Repository navigation
Implement Pylint #970
Description
Activity
- addedruleImplementing or modifying a lint ruleImplementing or modifying a lint rule
on 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.I vote for
PYEas it would keep the same categories and the migration would be easier.I'll work on
unneeded-notthis weekend.Reacted by Siddharth MitraI would suggest
PLas the pylint prefix (PLE->PyLintError). I thinkPYEmight be a bit ambiguous withPYflakes,PYdocstyle, etc.Reacted by Nikolai Røed Kristiansen, layday, Martin Bernstorff, Muhammad Yasirroni, Charles Coggins, Charles Hall, Shatakshi Mishra, Joseph Wilson, Remi Le Priol, Frank Harrison and 3 moreWould 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.
Reacted by Joseph Wilson and Israel Fruchter@relsunkaev 👍 Went with
PLE! The first code is checked in asPLE1142(matchingE1142from Pylint).Reacted by Noopur Ramakant Phalak@MartinBernstorff - Definitely. The multi-file stuff will come, just not as quickly.
Reacted by Martin Bernstorff, Nikolai Røed Kristiansen, jgsimard, Lasse Hansen, buster-blue, Siddharth Mitra, Colin Delahunty, Pedro Algarvio, Thomas Wimmer, Bryan Hoang and 1 moreReacted by Martin Bernstorff, Colin Delahunty, Pedro Algarvio, danieleades and JerryReacted by Israel FruchterNot 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,
class Foo: def validate(self): """Doc.""" ... class Bar(Foo): def validate(self): ...
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.
Reacted by sigma67, Lucas Steinmann and David- addedpluginImplementing a known but unsupported Ruff pluginImplementing a known but unsupported Ruff pluginand removedruleImplementing or modifying a lint ruleImplementing or modifying a lint rule
on Dec 31, 2022 I'd like to get
pointless-statement,unnecessary-ellipsis, andunnecessary-passin.Relevant source for defining a
pointless-statement: https://github.com/PyCQA/pylint/blob/56121344f6c9c223d8e4477c0cdb58c46c840b4b/pylint/checkers/base/basic_checker.py#L447A 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
Reacted by Leah Einhorn, Ruan Comelli and zahidpichenI'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:
- A Rust-implemented type checkers for Python. Short of a large company writing and maintaining this I doubt it'll keep up with the other big dogs
- Having the type information be seeded to ruff. Aside from the overhead and protocol, this actually seems feasible.
Reacted by Andrew Shannon Brown, Neil Girdhar and Christopher Barber441 remaining items
Load more actions@charliermarsh What do you think about
bad-except-order(https://pylint.readthedocs.io/en/latest/user_guide/messages/error/bad-except-order.html)? Can I give it a try on implementing it?Checked the code, seems like there is nothing like this yet.
And maybe you can also suggest what else (besides this) can be freely implemented?
I'm thinking about
using-constant-test(https://pylint.readthedocs.io/en/latest/user_guide/messages/warning/using-constant-test.html),consider-using-enumerate(https://pylint.readthedocs.io/en/latest/user_guide/messages/convention/consider-using-enumerate.html),bad-chained-comparison(https://pylint.readthedocs.io/en/latest/user_guide/messages/warning/bad-chained-comparison.html) and maybedict-init-mutate(https://pylint.readthedocs.io/en/latest/user_guide/messages/convention/dict-init-mutate.html)- added 11 commits that reference this issue
on May 1, 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.
Reacted by Oluf Lorenzen, Kyle Gottfried, Jack McIvor, Andrew Sansom, BLKSerene, Sam Theisens, James Braza, Clément Schreiner, KimythAnly and Nicky McCurdyPR for W0105 (pointless-string-statement): #27253
- added a commit that references this issue
on Aug 28, 2026
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 withmissing-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.
Error
abstract-class-instantiated/E0110access-member-before-definition/E0203assigning-non-slot/E0237(PLE0237)assignment-from-no-return/E1111assignment-from-none/E1128await-outside-async/E1142(PLE1142)bad-configuration-section/E0014bad-except-order/E0701bad-exception-cause/E0705bad-format-character/E1300(PLE1300)bad-plugin-value/E0013bad-reversed-sequence/E0111bad-str-strip-call/E1310(PLE1310)bad-string-format-type/E1307(PLE1307)(mainly targets Python 2)bad-super-call/E1003bidirectional-unicode/E2502(PLE2502)broken-collections-callable/E6005broken-noreturn/E6004catching-non-exception/E0712class-variable-slots-conflict/E0242continue-in-finally/E0116(PLE0116)dict-iter-missing-items/E1141duplicate-argument-name/E0108duplicate-bases/E0241(PLE0241)format-needs-mapping/E1303(F502)function-redefined/E0102(F811)import-error/E0401inconsistent-mro/E0240inherit-non-class/E0239init-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/E2511invalid-character-esc/E2513(PLE2513)invalid-character-nul/E2514(PLE2514)invalid-character-sub/E2512(PLE2512)invalid-character-zero-width-space/E2515(PLE2515)invalid-class-object/E0243invalid-enum-extension/E0244invalid-envvar-value/E1507invalid-format-returned/E0311invalid-getnewargs-ex-returned/E0313invalid-getnewargs-returned/E0312invalid-hash-returned/E0309(PLE0309)invalid-index-returned/E0305(PLE0305)invalid-length-hint-returned/E0310invalid-length-returned/E0303(PLE0303)invalid-metaclass/E1139invalid-repr-returned/E0306invalid-sequence-index/E1126invalid-slice-index/E1127invalid-slice-step/E1144invalid-slots/E0238invalid-slots-object/E0236invalid-star-assignment-target/E0113invalid-str-returned/E0307invalid-unary-operand-type/E1130invalid-unicode-codec/E2501logging-format-truncated/E1201logging-too-few-args/E1206(PLE1206)logging-too-many-args/E1205(PLE1205)logging-unsupported-format/E1200method-hidden/E0202misplaced-bare-raise/E0704(PLE0704)misplaced-format-function/E0119missing-format-string-key/E1304(F524)missing-kwoa/E1125mixed-format-string/E1302(F506)modified-iterating-dict/E4702modified-iterating-set/E4703(PLE4703)no-member/E1101no-method-argument/E0211no-name-in-module/E0611no-self-argument/E0213(N805)no-value-for-parameter/E1120non-iterator-returned/E0301nonexistent-operator/E0107(B002)nonlocal-and-global/E0115(PLE0115)nonlocal-without-binding/E0117(PLE0117)not-a-mapping/E1134not-an-iterable/E1133not-async-context-manager/E1701not-callable/E1102not-context-manager/E1129not-in-loop/E0103(F701,F702)notimplemented-raised/E0711(F901)potential-index-error/E0643(PLE0643)raising-bad-type/E0702raising-non-exception/E0710redundant-keyword-arg/E1124relative-beyond-top-level/E0402(TID252)repeated-keyword/E1132(PLE1132)return-arg-in-generator/E0106return-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/E1121too-many-star-expressions/E0112(F622)truncated-format-string/E1301(F501)undefined-all-variable/E0603(F822)undefined-variable/E0602(F821)unexpected-keyword-arg/E1123unexpected-special-method-signature/E0302(PLE0302)unhashable-member/E1143unpacking-non-sequence/E0633unsubscriptable-object/E1136unsupported-assignment-operation/E1137unsupported-binary-operation/E1131unsupported-delete-operation/E1138unsupported-membership-test/E1135used-before-assignment/E0601(F821)used-prior-global-declaration/E0118(PLE0118)yield-inside-async-function/E1700(PLE1700)yield-outside-function/E0105(F704)Warning
abstract-method/W0223anomalous-backslash-in-string/W1401(W605)anomalous-unicode-escape-in-string/W1402arguments-differ/W0221arguments-out-of-order/W1114arguments-renamed/W0237assert-on-string-literal/W0129(PLW0129)assert-on-tuple/W0199(F631)attribute-defined-outside-init/W0201bad-builtin/W0141bad-chained-comparison/W3601bad-dunder-name/W3201(PLW3201)bad-format-string/W1302(F521)bad-format-string-key/W1300bad-indentation/W0311(E111)bad-open-mode/W1501(PLW1501)bad-staticmethod-argument/W0211(PLW0211)bad-thread-instantiation/W1506bare-except/W0702(E722)binary-op-exception/W0711(PLW0711)boolean-datetime/W1502broad-exception-caught/W0718(BLE001)broad-exception-raised/W0719(TRY002)cell-var-from-loop/W0640(B023)comparison-with-callable/W0143confusing-with-statement/W0124consider-ternary-expression/W0160(SIM108)dangerous-default-value/W0102(B006)deprecated-argument/W4903deprecated-class/W4904deprecated-decorator/W4905deprecated-method/W4902deprecated-module/W4901deprecated-typing-alias/W6001differing-param-doc/W9017differing-type-doc/W9018duplicate-except/W0705(B014)duplicate-key/W0109(F601)duplicate-string-formatting-argument/W1308duplicate-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/W0601implicit-str-concat/W1404(ISC001)import-self/W0406(PLW0406)inconsistent-quotes/W1405(Q000)invalid-envvar-default/W1508(PLW1508)invalid-format-index/W1307invalid-overridden-method/W0236isinstance-second-argument-not-valid-type/W1116keyword-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/W9021missing-format-argument-key/W1303(F524)missing-format-attribute/W1306missing-param-doc/W9015missing-parentheses-for-call-in-test/W0126missing-raises-doc/W9006(Pylint extension)missing-return-doc/W9011missing-return-type-doc/W9012missing-timeout/W3101missing-type-doc/W9016missing-yield-doc/W9013missing-yield-type-doc/W9014modified-iterating-list/W4701multiple-constructor-doc/W9005named-expr-without-context/W0131(PLW0131)nan-comparison/W0177(PLW0177)nested-min-max/W3301(PLW3301)non-ascii-file-name/W2402(N999)non-parent-init-called/W0233non-str-assignment-to-dunder-name/W1115overlapping-except/W0714overridden-final-method/W0239pointless-exception-statement/W0133(PLW0133)pointless-statement/W0104(B018)pointless-string-statement/W0105possibly-unused-variable/W0641preferred-module/W0407protected-access/W0212(SLF001)raise-missing-from/W0707(B904)raising-format-tuple/W0715redeclared-assigned-name/W0128redefined-builtin/W0622(A001)redefined-loop-name/W2901(PLW2901)redefined-outer-name/W0621redefined-slots-in-subclass/W0244redundant-returns-doc/W9008redundant-u-string-prefix/W1406(UP025)redundant-unittest-assert/W1503redundant-yields-doc/W9010reimported/W0404(F811)self-assigning-variable/W0127(PLW0127)self-cls-assignment/W0642shallow-copy-environ/W1507signature-differs/W0222subclassed-final-class/W0240subprocess-popen-preexec-fn/W1509(PLW1509)subprocess-run-check/W1510(PLW1510)super-init-not-called/W0231super-without-brackets/W0245(PLW0245)too-many-try-statements/W0717try-except-raise/W0706(TRY302)unbalanced-dict-unpacking/W0644unbalanced-tuple-unpacking/W0632undefined-loop-variable/W0631unknown-option-value/W0012unnecessary-ellipsis/W2301(`PIE790)unnecessary-lambda/W0108(PLW0108)unnecessary-pass/W0107(PIE790)unnecessary-semicolon/W0301(E703)unreachable/W0101unspecified-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/W0238unused-variable/W0612(F841)unused-wildcard-import/W0614useless-else-on-loop/W0120(PLW0120)useless-param-doc/W9019useless-parent-delegation/W0246useless-type-doc/W9020useless-with-lock/W2101(PLW2101)using-constant-test/W0125using-f-string-in-unsupported-version/W2601using-final-decorator-in-unsupported-version/W2602while-used/W0149wildcard-import/W0401(F403)wrong-exception-operation/W0716Convention
bad-classmethod-argument/C0202(N804)bad-docstring-quotes/C0198(Q002)bad-file-encoding/C2503bad-mcs-classmethod-argument/C0204bad-mcs-method-argument/C0203compare-to-empty-string/C1901(PLC1901)compare-to-zero/C2001consider-iterating-dictionary/C0201(SIM118)consider-using-any-or-all/C0501(SIM110,SIM111)consider-using-dict-items/C0206(PLC0206)consider-using-enumerate/C0200consider-using-f-string/C0209dict-init-mutate/C3401disallowed-name/C0104docstring-first-line-empty/C0199(D210)empty-docstring/C0112(D419)import-outside-toplevel/C0415(PLC0415)import-private-name/C2701(PLC2701)invalid-characters-in-docstring/C0403invalid-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/C0327multiple-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/C0302trailing-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/C0328ungrouped-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/C1803use-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/C0401wrong-spelling-in-docstring/C0402Refactor
chained-comparison/R1716comparison-of-constants/R0133(PLR0133)comparison-with-itself/R0124(PLR0124)condition-evals-to-constant/R1727confusing-consecutive-elif/R5601consider-alternative-union-syntax/R6003(UP007)consider-merging-isinstance/R1701(SIM101)consider-swap-variables/R1712(PLR1712)consider-using-alias/R6002(UP006)consider-using-assignment-expr/R6103consider-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/R1713consider-using-min-builtin/R1730(PLR1730)consider-using-max-builtin/R1731(PLR1730)consider-using-namedtuple-or-dataclass/R6101consider-using-set-comprehension/R1718(C401)consider-using-sys-exit/R1722(PLR1722)consider-using-ternary/R1706(PLR1706)consider-using-tuple/R6102consider-using-with/R1732(SIM115)cyclic-import/R0401duplicate-code/R0801else-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/R0204simplifiable-condition/R1726simplifiable-if-expression/R1719(SIM210,SIM211)simplifiable-if-statement/R1703(SIM108)simplify-boolean-expression/R1709stop-iteration-return/R1708super-with-arguments/R1725(UP008)too-complex/R1260(C901)too-few-public-methods/R0903too-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/R0902too-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/R0022useless-return/R1711(PLR1711)