Skip to content


Ruff supports over 500 lint rules, many of which are inspired by popular tools like Flake8, isort, pyupgrade, and others. Regardless of the rule's origin, Ruff re-implements every rule in Rust as a first-party feature.

By default, Ruff enables Flake8's E and F rules. Ruff supports all rules from the F category, and a subset of the E category, omitting those stylistic rules made obsolete by the use of an autoformatter, like Black.

If you're just getting started with Ruff, the default rule set is a great place to start: it catches a wide variety of common errors (like unused imports) with zero configuration.

The 🛠 emoji indicates that a rule is automatically fixable by the --fix command-line option.

Pyflakes (F)#

For more, see Pyflakes on PyPI.

Code Name Message Fix
F401 unused-import {name} imported but unused; consider adding to __all__ or using a redundant alias 🛠
F402 import-shadowed-by-loop-var Import {name} from line {line} shadowed by loop variable
F403 import-star from {name} import * used; unable to detect undefined names
F404 late-future-import from __future__ imports must occur at the beginning of the file
F405 import-star-usage {name} may be undefined, or defined from star imports:
F406 import-star-not-permitted from {name} import * only allowed at module level
F407 future-feature-not-defined Future feature {name} is not defined
F501 percent-format-invalid-format %-format string has invalid format string:
F502 percent-format-expected-mapping %-format string expected mapping but got sequence
F503 percent-format-expected-sequence %-format string expected sequence but got mapping
F504 percent-format-extra-named-arguments %-format string has unused named argument(s): 🛠
F505 percent-format-missing-argument %-format string is missing argument(s) for placeholder(s):
F506 percent-format-mixed-positional-and-named %-format string has mixed positional and named placeholders
F507 percent-format-positional-count-mismatch %-format string has {wanted} placeholder(s) but {got} substitution(s)
F508 percent-format-star-requires-sequence %-format string * specifier requires sequence
F509 percent-format-unsupported-format-character %-format string has unsupported format character {char}
F521 string-dot-format-invalid-format .format call has invalid format string:
F522 string-dot-format-extra-named-arguments .format call has unused named argument(s): 🛠
F523 string-dot-format-extra-positional-arguments .format call has unused arguments at position(s):
F524 string-dot-format-missing-arguments .format call is missing argument(s) for placeholder(s):
F525 string-dot-format-mixing-automatic .format string mixes automatic and manual numbering
F541 f-string-missing-placeholders f-string without any placeholders 🛠
F601 multi-value-repeated-key-literal Dictionary key literal {name} repeated 🛠
F602 multi-value-repeated-key-variable Dictionary key {name} repeated 🛠
F621 expressions-in-star-assignment Too many expressions in star-unpacking assignment
F622 two-starred-expressions Two starred expressions in assignment
F631 assert-tuple Assert test is a non-empty tuple, which is always True
F632 is-literal Use == to compare constant literals 🛠
F633 invalid-print-syntax Use of >> is invalid with print function
F634 if-tuple If test is a tuple, which is always True
F701 break-outside-loop break outside loop
F702 continue-outside-loop continue not properly in loop
F704 yield-outside-function {keyword} statement outside of a function
F706 return-outside-function return statement outside of a function/method
F707 default-except-not-last An except block as not the last exception handler
F722 forward-annotation-syntax-error Syntax error in forward annotation: {body}
F811 redefined-while-unused Redefinition of unused {name} from line
F821 undefined-name Undefined name {name}
F822 undefined-export Undefined name {name} in __all__
F823 undefined-local Local variable {name} referenced before assignment
F841 unused-variable Local variable {name} is assigned to but never used 🛠
F842 unused-annotation Local variable {name} is annotated but never used
F901 raise-not-implemented raise NotImplemented should be raise NotImplementedError 🛠

pycodestyle (E, W)#

For more, see pycodestyle on PyPI.

Error (E)#

Code Name Message Fix
E101 mixed-spaces-and-tabs Indentation contains mixed spaces and tabs
E401 multiple-imports-on-one-line Multiple imports on one line
E402 module-import-not-at-top-of-file Module level import not at top of file
E501 line-too-long Line too long ({length} > {limit} characters)
E701 multiple-statements-on-one-line-colon Multiple statements on one line (colon)
E702 multiple-statements-on-one-line-semicolon Multiple statements on one line (semicolon)
E703 useless-semicolon Statement ends with an unnecessary semicolon 🛠
E711 none-comparison Comparison to None should be cond is None 🛠
E712 true-false-comparison Comparison to True should be cond is True 🛠
E713 not-in-test Test for membership should be not in 🛠
E714 not-is-test Test for object identity should be is not 🛠
E721 type-comparison Do not compare types, use isinstance()
E722 bare-except Do not use bare except
E731 lambda-assignment Do not assign a lambda expression, use a def 🛠
E741 ambiguous-variable-name Ambiguous variable name: {name}
E742 ambiguous-class-name Ambiguous class name: {name}
E743 ambiguous-function-name Ambiguous function name: {name}
E902 io-error {message}
E999 syntax-error SyntaxError:

Warning (W)#

Code Name Message Fix
W191 indentation-contains-tabs Indentation contains tabs
W291 trailing-whitespace Trailing whitespace 🛠
W292 no-new-line-at-end-of-file No newline at end of file 🛠
W293 blank-line-contains-whitespace Blank line contains whitespace 🛠
W505 doc-line-too-long Doc line too long ({length} > {limit} characters)
W605 invalid-escape-sequence Invalid escape sequence: \{char} 🛠

mccabe (C90)#

For more, see mccabe on PyPI.

Code Name Message Fix
C901 complex-structure {name} is too complex ({complexity} > {max_complexity})

isort (I)#

For more, see isort on PyPI.

Code Name Message Fix
I001 unsorted-imports Import block is un-sorted or un-formatted 🛠
I002 missing-required-import Missing required import: {name} 🛠

pep8-naming (N)#

For more, see pep8-naming on PyPI.

Code Name Message Fix
N801 invalid-class-name Class name {name} should use CapWords convention
N802 invalid-function-name Function name {name} should be lowercase
N803 invalid-argument-name Argument name {name} should be lowercase
N804 invalid-first-argument-name-for-class-method First argument of a class method should be named cls
N805 invalid-first-argument-name-for-method First argument of a method should be named self
N806 non-lowercase-variable-in-function Variable {name} in function should be lowercase
N807 dunder-function-name Function name should not start and end with __
N811 constant-imported-as-non-constant Constant {name} imported as non-constant {asname}
N812 lowercase-imported-as-non-lowercase Lowercase {name} imported as non-lowercase {asname}
N813 camelcase-imported-as-lowercase Camelcase {name} imported as lowercase {asname}
N814 camelcase-imported-as-constant Camelcase {name} imported as constant {asname}
N815 mixed-case-variable-in-class-scope Variable {name} in class scope should not be mixedCase
N816 mixed-case-variable-in-global-scope Variable {name} in global scope should not be mixedCase
N817 camelcase-imported-as-acronym CamelCase {name} imported as acronym {asname}
N818 error-suffix-on-exception-name Exception name {name} should be named with an Error suffix
N999 invalid-module-name Invalid module name: '{name}'

pydocstyle (D)#

For more, see pydocstyle on PyPI.

Code Name Message Fix
D100 public-module Missing docstring in public module
D101 public-class Missing docstring in public class
D102 public-method Missing docstring in public method
D103 public-function Missing docstring in public function
D104 public-package Missing docstring in public package
D105 magic-method Missing docstring in magic method
D106 public-nested-class Missing docstring in public nested class
D107 public-init Missing docstring in __init__
D200 fits-on-one-line One-line docstring should fit on one line 🛠
D201 no-blank-line-before-function No blank lines allowed before function docstring (found {num_lines}) 🛠
D202 no-blank-line-after-function No blank lines allowed after function docstring (found {num_lines}) 🛠
D203 one-blank-line-before-class 1 blank line required before class docstring 🛠
D204 one-blank-line-after-class 1 blank line required after class docstring 🛠
D205 blank-line-after-summary 1 blank line required between summary line and description 🛠
D206 indent-with-spaces Docstring should be indented with spaces, not tabs
D207 no-under-indentation Docstring is under-indented 🛠
D208 no-over-indentation Docstring is over-indented 🛠
D209 new-line-after-last-paragraph Multi-line docstring closing quotes should be on a separate line 🛠
D210 no-surrounding-whitespace No whitespaces allowed surrounding docstring text 🛠
D211 no-blank-line-before-class No blank lines allowed before class docstring 🛠
D212 multi-line-summary-first-line Multi-line docstring summary should start at the first line 🛠
D213 multi-line-summary-second-line Multi-line docstring summary should start at the second line 🛠
D214 section-not-over-indented Section is over-indented ("{name}") 🛠
D215 section-underline-not-over-indented Section underline is over-indented ("{name}") 🛠
D300 triple-single-quotes Use triple double quotes """
D301 escape-sequence-in-docstring Use r""" if any backslashes in a docstring
D400 ends-in-period First line should end with a period 🛠
D401 non-imperative-mood First line of docstring should be in imperative mood: "{first_line}"
D402 no-signature First line should not be the function's signature
D403 first-line-capitalized First word of the first line should be properly capitalized
D404 docstring-starts-with-this First word of the docstring should not be "This"
D405 capitalize-section-name Section name should be properly capitalized ("{name}") 🛠
D406 new-line-after-section-name Section name should end with a newline ("{name}") 🛠
D407 dashed-underline-after-section Missing dashed underline after section ("{name}") 🛠
D408 section-underline-after-name Section underline should be in the line following the section's name ("{name}") 🛠
D409 section-underline-matches-section-length Section underline should match the length of its name ("{name}") 🛠
D410 blank-line-after-section Missing blank line after section ("{name}") 🛠
D411 blank-line-before-section Missing blank line before section ("{name}") 🛠
D412 no-blank-lines-between-header-and-content No blank lines allowed between a section header and its content ("{name}") 🛠
D413 blank-line-after-last-section Missing blank line after last section ("{name}") 🛠
D414 empty-docstring-section Section has no content ("{name}")
D415 ends-in-punctuation First line should end with a period, question mark, or exclamation point 🛠
D416 section-name-ends-in-colon Section name should end with a colon ("{name}") 🛠
D417 undocumented-param Missing argument description in the docstring: {name}
D418 overload-with-docstring Function decorated with @overload shouldn't contain a docstring
D419 empty-docstring Docstring is empty

pyupgrade (UP)#

For more, see pyupgrade on PyPI.

Code Name Message Fix
UP001 useless-metaclass-type __metaclass__ = type is implied 🛠
UP003 type-of-primitive Use {} instead of type(...) 🛠
UP004 useless-object-inheritance Class {name} inherits from object 🛠
UP005 deprecated-unittest-alias {alias} is deprecated, use {target} 🛠
UP006 deprecated-collection-type Use {} instead of {} for type annotations 🛠
UP007 typing-union Use X \| Y for type annotations 🛠
UP008 super-call-with-parameters Use super() instead of super(__class__, self) 🛠
UP009 utf8-encoding-declaration UTF-8 encoding declaration is unnecessary 🛠
UP010 unnecessary-future-import Unnecessary __future__ import {import} for target Python version 🛠
UP011 lru-cache-without-parameters Unnecessary parameters to functools.lru_cache 🛠
UP012 unnecessary-encode-utf8 Unnecessary call to encode as UTF-8 🛠
UP013 convert-typed-dict-functional-to-class Convert {name} from TypedDict functional to class syntax 🛠
UP014 convert-named-tuple-functional-to-class Convert {name} from NamedTuple functional to class syntax 🛠
UP015 redundant-open-modes Unnecessary open mode parameters 🛠
UP017 datetime-timezone-utc Use datetime.UTC alias 🛠
UP018 native-literals Unnecessary call to {literal_type} 🛠
UP019 typing-text-str-alias typing.Text is deprecated, use str 🛠
UP020 open-alias Use builtin open 🛠
UP021 replace-universal-newlines universal_newlines is deprecated, use text 🛠
UP022 replace-stdout-stderr Sending stdout and stderr to pipe is deprecated, use capture_output 🛠
UP023 rewrite-c-element-tree cElementTree is deprecated, use ElementTree 🛠
UP024 os-error-alias Replace aliased errors with OSError 🛠
UP025 rewrite-unicode-literal Remove unicode literals from strings 🛠
UP026 rewrite-mock-import mock is deprecated, use unittest.mock 🛠
UP027 rewrite-list-comprehension Replace unpacked list comprehension with a generator expression 🛠
UP028 rewrite-yield-from Replace yield over for loop with yield from 🛠
UP029 unnecessary-builtin-import Unnecessary builtin import: {import} 🛠
UP030 format-literals Use implicit references for positional format fields 🛠
UP031 printf-string-formatting Use format specifiers instead of percent format 🛠
UP032 f-string Use f-string instead of format call 🛠
UP033 functools-cache Use @functools.cache instead of @functools.lru_cache(maxsize=None) 🛠
UP034 extraneous-parentheses Avoid extraneous parentheses 🛠
UP035 deprecated-import Import from {target} instead: 🛠
UP036 outdated-version-block Version block is outdated for minimum Python version 🛠
UP037 quoted-annotation Remove quotes from type annotation 🛠
UP038 isinstance-with-tuple Use X \| Y in {} call instead of (X, Y) 🛠

flake8-2020 (YTT)#

For more, see flake8-2020 on PyPI.

Code Name Message Fix
YTT101 sys-version-slice3-referenced sys.version[:3] referenced (python3.10), use sys.version_info
YTT102 sys-version2-referenced sys.version[2] referenced (python3.10), use sys.version_info
YTT103 sys-version-cmp-str3 sys.version compared to string (python3.10), use sys.version_info
YTT201 sys-version-info0-eq3-referenced sys.version_info[0] == 3 referenced (python4), use >=
YTT202 six-py3-referenced six.PY3 referenced (python4), use not six.PY2
YTT203 sys-version-info1-cmp-int sys.version_info[1] compared to integer (python4), compare sys.version_info to tuple
YTT204 sys-version-info-minor-cmp-int sys.version_info.minor compared to integer (python4), compare sys.version_info to tuple
YTT301 sys-version0-referenced sys.version[0] referenced (python10), use sys.version_info
YTT302 sys-version-cmp-str10 sys.version compared to string (python10), use sys.version_info
YTT303 sys-version-slice1-referenced sys.version[:1] referenced (python10), use sys.version_info

flake8-annotations (ANN)#

For more, see flake8-annotations on PyPI.

Code Name Message Fix
ANN001 missing-type-function-argument Missing type annotation for function argument {name}
ANN002 missing-type-args Missing type annotation for *{name}
ANN003 missing-type-kwargs Missing type annotation for **{name}
ANN101 missing-type-self Missing type annotation for {name} in method
ANN102 missing-type-cls Missing type annotation for {name} in classmethod
ANN201 missing-return-type-public-function Missing return type annotation for public function {name}
ANN202 missing-return-type-private-function Missing return type annotation for private function {name}
ANN204 missing-return-type-special-method Missing return type annotation for special method {name} 🛠
ANN205 missing-return-type-static-method Missing return type annotation for staticmethod {name}
ANN206 missing-return-type-class-method Missing return type annotation for classmethod {name}
ANN401 any-type Dynamically typed expressions (typing.Any) are disallowed in {name}

flake8-bandit (S)#

For more, see flake8-bandit on PyPI.

Code Name Message Fix
S101 assert Use of assert detected
S102 exec-builtin Use of exec detected
S103 bad-file-permissions os.chmod setting a permissive mask {mask:#o} on file or directory
S104 hardcoded-bind-all-interfaces Possible binding to all interfaces
S105 hardcoded-password-string Possible hardcoded password: "{}"
S106 hardcoded-password-func-arg Possible hardcoded password: "{}"
S107 hardcoded-password-default Possible hardcoded password: "{}"
S108 hardcoded-temp-file Probable insecure usage of temporary file or directory: "{}"
S110 try-except-pass try-except-pass detected, consider logging the exception
S112 try-except-continue try-except-continue detected, consider logging the exception
S113 request-without-timeout Probable use of requests call with timeout set to {value}
S324 hashlib-insecure-hash-function Probable use of insecure hash functions in hashlib: {string}
S501 request-with-no-cert-validation Probable use of {string} call with verify=False disabling SSL certificate checks
S506 unsafe-yaml-load Probable use of unsafe loader {name} with yaml.load. Allows instantiation of arbitrary objects. Consider yaml.safe_load.
S508 snmp-insecure-version The use of SNMPv1 and SNMPv2 is insecure. Use SNMPv3 if able.
S509 snmp-weak-cryptography You should not use SNMPv3 without encryption. noAuthNoPriv & authNoPriv is insecure.
S608 hardcoded-sql-expression Possible SQL injection vector through string-based query construction
S612 logging-config-insecure-listen Use of insecure logging.config.listen detected
S701 jinja2-autoescape-false Using jinja2 templates with autoescape=False is dangerous and can lead to XSS. Ensure autoescape=True or use the select_autoescape function.

flake8-blind-except (BLE)#

For more, see flake8-blind-except on PyPI.

Code Name Message Fix
BLE001 blind-except Do not catch blind exception: {name}

flake8-boolean-trap (FBT)#

For more, see flake8-boolean-trap on PyPI.

Code Name Message Fix
FBT001 boolean-positional-arg-in-function-definition Boolean positional arg in function definition
FBT002 boolean-default-value-in-function-definition Boolean default value in function definition
FBT003 boolean-positional-value-in-function-call Boolean positional value in function call

flake8-bugbear (B)#

For more, see flake8-bugbear on PyPI.

Code Name Message Fix
B002 unary-prefix-increment Python does not support the unary prefix increment
B003 assignment-to-os-environ Assigning to os.environ doesn't clear the environment
B004 unreliable-callable-check Using hasattr(x, '__call__') to test if x is callable is unreliable. Use callable(x) for consistent results.
B005 strip-with-multi-characters Using .strip() with multi-character strings is misleading the reader
B006 mutable-argument-default Do not use mutable data structures for argument defaults
B007 unused-loop-control-variable Loop control variable {name} not used within loop body 🛠
B008 function-call-argument-default Do not perform function call {name} in argument defaults
B009 get-attr-with-constant Do not call getattr with a constant attribute value. It is not any safer than normal property access. 🛠
B010 set-attr-with-constant Do not call setattr with a constant attribute value. It is not any safer than normal property access. 🛠
B011 assert-false Do not assert False (python -O removes these calls), raise AssertionError() 🛠
B012 jump-statement-in-finally {name} inside finally blocks cause exceptions to be silenced
B013 redundant-tuple-in-exception-handler A length-one tuple literal is redundant. Write except {name} instead of except ({name},). 🛠
B014 duplicate-handler-exception Exception handler with duplicate exception: {name} 🛠
B015 useless-comparison Pointless comparison. This comparison does nothing but waste CPU instructions. Either prepend assert or remove it.
B016 cannot-raise-literal Cannot raise a literal. Did you intend to return it or raise an Exception?
B017 assert-raises-exception assertRaises(Exception) should be considered evil
B018 useless-expression Found useless expression. Either assign it to a variable or remove it.
B019 cached-instance-method Use of functools.lru_cache or functools.cache on methods can lead to memory leaks
B020 loop-variable-overrides-iterator Loop control variable {name} overrides iterable it iterates
B021 f-string-docstring f-string used as docstring. This will be interpreted by python as a joined string rather than a docstring.
B022 useless-contextlib-suppress No arguments passed to contextlib.suppress. No exceptions will be suppressed and therefore this context manager is redundant
B023 function-uses-loop-variable Function definition does not bind loop variable {name}
B024 abstract-base-class-without-abstract-method {name} is an abstract base class, but it has no abstract methods
B025 duplicate-try-block-exception try-except block with duplicate exception {name}
B026 star-arg-unpacking-after-keyword-arg Star-arg unpacking after a keyword argument is strongly discouraged
B027 empty-method-without-abstract-decorator {name} is an empty method in an abstract base class, but has no abstract decorator
B028 no-explicit-stacklevel No explicit stacklevel keyword argument found
B029 except-with-empty-tuple Using except (): with an empty tuple does not handle/catch anything. Add exceptions to handle.
B030 except-with-non-exception-classes except handlers should only be exception classes or tuples of exception classes
B032 unintentional-type-annotation Possible unintentional type annotation (using :). Did you mean to assign (using =)?
B904 raise-without-from-inside-except Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
B905 zip-without-explicit-strict zip() without an explicit strict= parameter

flake8-builtins (A)#

For more, see flake8-builtins on PyPI.

Code Name Message Fix
A001 builtin-variable-shadowing Variable {name} is shadowing a python builtin
A002 builtin-argument-shadowing Argument {name} is shadowing a python builtin
A003 builtin-attribute-shadowing Class attribute {name} is shadowing a python builtin

flake8-commas (COM)#

For more, see flake8-commas on PyPI.

Code Name Message Fix
COM812 trailing-comma-missing Trailing comma missing 🛠
COM818 trailing-comma-on-bare-tuple-prohibited Trailing comma on bare tuple prohibited
COM819 trailing-comma-prohibited Trailing comma prohibited 🛠

flake8-comprehensions (C4)#

For more, see flake8-comprehensions on PyPI.

Code Name Message Fix
C400 unnecessary-generator-list Unnecessary generator (rewrite as a list comprehension) 🛠
C401 unnecessary-generator-set Unnecessary generator (rewrite as a set comprehension) 🛠
C402 unnecessary-generator-dict Unnecessary generator (rewrite as a dict comprehension) 🛠
C403 unnecessary-list-comprehension-set Unnecessary list comprehension (rewrite as a set comprehension) 🛠
C404 unnecessary-list-comprehension-dict Unnecessary list comprehension (rewrite as a dict comprehension) 🛠
C405 unnecessary-literal-set Unnecessary {obj_type} literal (rewrite as a set literal) 🛠
C406 unnecessary-literal-dict Unnecessary {obj_type} literal (rewrite as a dict literal) 🛠
C408 unnecessary-collection-call Unnecessary {obj_type} call (rewrite as a literal) 🛠
C409 unnecessary-literal-within-tuple-call Unnecessary {literal} literal passed to tuple() (rewrite as a tuple literal) 🛠
C410 unnecessary-literal-within-list-call Unnecessary {literal} literal passed to list() (remove the outer call to list()) 🛠
C411 unnecessary-list-call Unnecessary list call (remove the outer call to list()) 🛠
C413 unnecessary-call-around-sorted Unnecessary {func} call around sorted() 🛠
C414 unnecessary-double-cast-or-process Unnecessary {inner} call within {outer}() 🛠
C415 unnecessary-subscript-reversal Unnecessary subscript reversal of iterable within {func}()
C416 unnecessary-comprehension Unnecessary {obj_type} comprehension (rewrite using {obj_type}()) 🛠
C417 unnecessary-map Unnecessary map usage (rewrite using a generator expression) 🛠

flake8-datetimez (DTZ)#

For more, see flake8-datetimez on PyPI.

Code Name Message Fix
DTZ001 call-datetime-without-tzinfo The use of datetime.datetime() without tzinfo argument is not allowed
DTZ002 call-datetime-today The use of is not allowed, use instead
DTZ003 call-datetime-utcnow The use of datetime.datetime.utcnow() is not allowed, use instead
DTZ004 call-datetime-utcfromtimestamp The use of datetime.datetime.utcfromtimestamp() is not allowed, use datetime.datetime.fromtimestamp(ts, tz=) instead
DTZ005 call-datetime-now-without-tzinfo The use of without tz argument is not allowed
DTZ006 call-datetime-fromtimestamp The use of datetime.datetime.fromtimestamp() without tz argument is not allowed
DTZ007 call-datetime-strptime-without-zone The use of datetime.datetime.strptime() without %z must be followed by .replace(tzinfo=) or .astimezone()
DTZ011 call-date-today The use of is not allowed, use instead
DTZ012 call-date-fromtimestamp The use of is not allowed, use datetime.datetime.fromtimestamp(ts, tz=).date() instead

flake8-debugger (T10)#

For more, see flake8-debugger on PyPI.

Code Name Message Fix
T100 debugger Trace found: {name} used

flake8-django (DJ)#

For more, see flake8-django on PyPI.

Code Name Message Fix
DJ001 nullable-model-string-field Avoid using null=True on string-based fields such as
DJ003 locals-in-render-function Avoid passing locals() as context to a render function
DJ006 exclude-with-model-form Do not use exclude with ModelForm, use fields instead
DJ007 all-with-model-form Do not use __all__ with ModelForm, use fields instead
DJ008 model-without-dunder-str Model does not define __str__ method
DJ013 non-leading-receiver-decorator @receiver decorator must be on top of all the other decorators

flake8-errmsg (EM)#

For more, see flake8-errmsg on PyPI.

Code Name Message Fix
EM101 raw-string-in-exception Exception must not use a string literal, assign to variable first
EM102 f-string-in-exception Exception must not use an f-string literal, assign to variable first
EM103 dot-format-in-exception Exception must not use a .format() string directly, assign to variable first

flake8-executable (EXE)#

For more, see flake8-executable on PyPI.

Code Name Message Fix
EXE001 shebang-not-executable Shebang is present but file is not executable
EXE002 shebang-missing-executable-file The file is executable but no shebang is present
EXE003 shebang-python Shebang should contain python
EXE004 shebang-whitespace Avoid whitespace before shebang 🛠
EXE005 shebang-newline Shebang should be at the beginning of the file

flake8-implicit-str-concat (ISC)#

For more, see flake8-implicit-str-concat on PyPI.

Code Name Message Fix
ISC001 single-line-implicit-string-concatenation Implicitly concatenated string literals on one line
ISC002 multi-line-implicit-string-concatenation Implicitly concatenated string literals over multiple lines
ISC003 explicit-string-concatenation Explicitly concatenated string should be implicitly concatenated

flake8-import-conventions (ICN)#

For more, see flake8-import-conventions on GitHub.

Code Name Message Fix
ICN001 unconventional-import-alias {name} should be imported as {asname}

flake8-logging-format (G)#

For more, see flake8-logging-format on PyPI.

Code Name Message Fix
G001 logging-string-format Logging statement uses string.format()
G002 logging-percent-format Logging statement uses %
G003 logging-string-concat Logging statement uses +
G004 logging-f-string Logging statement uses f-string
G010 logging-warn Logging statement uses warn instead of warning 🛠
G101 logging-extra-attr-clash Logging statement uses an extra field that clashes with a LogRecord field: {key}
G201 logging-exc-info Logging .exception(...) should be used instead of .error(..., exc_info=True)
G202 logging-redundant-exc-info Logging statement has redundant exc_info

flake8-no-pep420 (INP)#

For more, see flake8-no-pep420 on PyPI.

Code Name Message Fix
INP001 implicit-namespace-package File {filename} is part of an implicit namespace package. Add an

flake8-pie (PIE)#

For more, see flake8-pie on PyPI.

Code Name Message Fix
PIE790 unnecessary-pass Unnecessary pass statement 🛠
PIE794 dupe-class-field-definitions Class field {name} is defined multiple times 🛠
PIE796 prefer-unique-enums Enum contains duplicate value: {value}
PIE800 unnecessary-spread Unnecessary spread **
PIE802 unnecessary-comprehension-any-all Unnecessary list comprehension. 🛠
PIE804 unnecessary-dict-kwargs Unnecessary dict kwargs
PIE807 prefer-list-builtin Prefer list over useless lambda 🛠
PIE810 single-starts-ends-with Call {attr} once with a tuple 🛠

flake8-print (T20)#

For more, see flake8-print on PyPI.

Code Name Message Fix
T201 print-found print found
T203 p-print-found pprint found

flake8-pyi (PYI)#

For more, see flake8-pyi on PyPI.

Code Name Message Fix
PYI001 prefix-type-params Name of private {kind} must start with _
PYI006 bad-version-info-comparison Use < or >= for version info comparisons
PYI007 unrecognized-platform-check Unrecognized sys.platform check
PYI008 unrecognized-platform-name Unrecognized platform {platform}
PYI009 pass-statement-stub-body Empty body should contain ..., not pass
PYI010 non-empty-stub-body Function body must contain only ...
PYI011 typed-argument-simple-defaults Only simple default values allowed for typed arguments 🛠
PYI014 argument-simple-defaults Only simple default values allowed for arguments
PYI021 docstring-in-stub Docstrings should not be included in stubs
PYI033 type-comment-in-stub Don't use type comments in stub file

flake8-pytest-style (PT)#

For more, see flake8-pytest-style on PyPI.

Code Name Message Fix
PT001 incorrect-fixture-parentheses-style Use @pytest.fixture{expected_parens} over @pytest.fixture{actual_parens} 🛠
PT002 fixture-positional-args Configuration for fixture {function} specified via positional args, use kwargs
PT003 extraneous-scope-function scope='function' is implied in @pytest.fixture() 🛠
PT004 missing-fixture-name-underscore Fixture {function} does not return anything, add leading underscore
PT005 incorrect-fixture-name-underscore Fixture {function} returns a value, remove leading underscore
PT006 parametrize-names-wrong-type Wrong name(s) type in @pytest.mark.parametrize, expected {expected} 🛠
PT007 parametrize-values-wrong-type Wrong values type in @pytest.mark.parametrize expected {values} of {row}
PT008 patch-with-lambda Use return_value= instead of patching with lambda
PT009 unittest-assertion Use a regular assert instead of unittest-style {assertion} 🛠
PT010 raises-without-exception set the expected exception in pytest.raises()
PT011 raises-too-broad pytest.raises({exception}) is too broad, set the match parameter or use a more specific exception
PT012 raises-with-multiple-statements pytest.raises() block should contain a single simple statement
PT013 incorrect-pytest-import Found incorrect import of pytest, use simple import pytest instead
PT015 assert-always-false Assertion always fails, replace with
PT016 fail-without-message No message passed to
PT017 assert-in-except Found assertion on exception {name} in except block, use pytest.raises() instead
PT018 composite-assertion Assertion should be broken down into multiple parts 🛠
PT019 fixture-param-without-value Fixture {name} without value is injected as parameter, use @pytest.mark.usefixtures instead
PT020 deprecated-yield-fixture @pytest.yield_fixture is deprecated, use @pytest.fixture
PT021 fixture-finalizer-callback Use yield instead of request.addfinalizer
PT022 useless-yield-fixture No teardown in fixture {name}, use return instead of yield 🛠
PT023 incorrect-mark-parentheses-style Use @pytest.mark.{mark_name}{expected_parens} over @pytest.mark.{mark_name}{actual_parens} 🛠
PT024 unnecessary-asyncio-mark-on-fixture pytest.mark.asyncio is unnecessary for fixtures 🛠
PT025 erroneous-use-fixtures-on-fixture pytest.mark.usefixtures has no effect on fixtures 🛠
PT026 use-fixtures-without-parameters Useless pytest.mark.usefixtures without parameters 🛠

flake8-quotes (Q)#

For more, see flake8-quotes on PyPI.

Code Name Message Fix
Q000 bad-quotes-inline-string Double quotes found but single quotes preferred 🛠
Q001 bad-quotes-multiline-string Double quote multiline found but single quotes preferred 🛠
Q002 bad-quotes-docstring Double quote docstring found but single quotes preferred 🛠
Q003 avoidable-escaped-quote Change outer quotes to avoid escaping inner quotes 🛠

flake8-raise (RSE)#

For more, see flake8-raise on PyPI.

Code Name Message Fix
RSE102 unnecessary-paren-on-raise-exception Unnecessary parentheses on raised exception 🛠

flake8-return (RET)#

For more, see flake8-return on PyPI.

Code Name Message Fix
RET501 unnecessary-return-none Do not explicitly return None in function if it is the only possible return value 🛠
RET502 implicit-return-value Do not implicitly return None in function able to return non-None value 🛠
RET503 implicit-return Missing explicit return at the end of function able to return non-None value 🛠
RET504 unnecessary-assign Unnecessary variable assignment before return statement
RET505 superfluous-else-return Unnecessary {branch} after return statement
RET506 superfluous-else-raise Unnecessary {branch} after raise statement
RET507 superfluous-else-continue Unnecessary {branch} after continue statement
RET508 superfluous-else-break Unnecessary {branch} after break statement

flake8-self (SLF)#

For more, see flake8-self on PyPI.

Code Name Message Fix
SLF001 private-member-access Private member accessed: {access}

flake8-simplify (SIM)#

For more, see flake8-simplify on PyPI.

Code Name Message Fix
SIM101 duplicate-isinstance-call Multiple isinstance calls for {name}, merge into a single call 🛠
SIM102 collapsible-if Use a single if statement instead of nested if statements 🛠
SIM103 needless-bool Return the condition {condition} directly 🛠
SIM105 use-contextlib-suppress Use contextlib.suppress({exception}) instead of try-except-pass
SIM107 return-in-try-except-finally Don't use return in try/except and finally
SIM108 use-ternary-operator Use ternary operator {contents} instead of if-else-block 🛠
SIM109 compare-with-tuple Use {replacement} instead of multiple equality comparisons 🛠
SIM110 reimplemented-builtin Use {repl} instead of for loop 🛠
SIM112 use-capital-environment-variables Use capitalized environment variable {expected} instead of {original} 🛠
SIM114 if-with-same-arms Combine if branches using logical or operator
SIM115 open-file-with-context-handler Use context handler for opening files
SIM116 manual-dict-lookup Use a dictionary instead of consecutive if statements
SIM117 multiple-with-statements Use a single with statement with multiple contexts instead of nested with statements 🛠
SIM118 key-in-dict Use {key} in {dict} instead of {key} in {dict}.keys() 🛠
SIM201 negate-equal-op Use {left} != {right} instead of not {left} == {right} 🛠
SIM202 negate-not-equal-op Use {left} == {right} instead of not {left} != {right} 🛠
SIM208 double-negation Use {expr} instead of not (not {expr}) 🛠
SIM210 if-expr-with-true-false Use bool({expr}) instead of True if {expr} else False 🛠
SIM211 if-expr-with-false-true Use not {expr} instead of False if {expr} else True 🛠
SIM212 if-expr-with-twisted-arms Use {expr_else} if {expr_else} else {expr_body} instead of {expr_body} if not {expr_else} else {expr_else} 🛠
SIM220 expr-and-not-expr Use False instead of {name} and not {name} 🛠
SIM221 expr-or-not-expr Use True instead of {name} or not {name} 🛠
SIM222 expr-or-true Use True instead of ... or True 🛠
SIM223 expr-and-false Use False instead of ... and False 🛠
SIM300 yoda-conditions Yoda conditions are discouraged, use {suggestion} instead 🛠
SIM401 dict-get-with-default Use {contents} instead of an if block 🛠

flake8-tidy-imports (TID)#

For more, see flake8-tidy-imports on PyPI.

Code Name Message Fix
TID251 banned-api {name} is banned:
TID252 relative-imports Relative imports from parent modules are banned 🛠

flake8-type-checking (TCH)#

For more, see flake8-type-checking on PyPI.

Code Name Message Fix
TCH001 typing-only-first-party-import Move application import {} into a type-checking block
TCH002 typing-only-third-party-import Move third-party import {} into a type-checking block
TCH003 typing-only-standard-library-import Move standard library import {} into a type-checking block
TCH004 runtime-import-in-type-checking-block Move import {} out of type-checking block. Import is used for more than type hinting.
TCH005 empty-type-checking-block Found empty type-checking block 🛠

flake8-unused-arguments (ARG)#

For more, see flake8-unused-arguments on PyPI.

Code Name Message Fix
ARG001 unused-function-argument Unused function argument: {name}
ARG002 unused-method-argument Unused method argument: {name}
ARG003 unused-class-method-argument Unused class method argument: {name}
ARG004 unused-static-method-argument Unused static method argument: {name}
ARG005 unused-lambda-argument Unused lambda argument: {name}

flake8-use-pathlib (PTH)#

For more, see flake8-use-pathlib on PyPI.

Code Name Message Fix
PTH100 pathlib-abspath os.path.abspath() should be replaced by Path.resolve()
PTH101 pathlib-chmod os.chmod() should be replaced by Path.chmod()
PTH102 pathlib-mkdir os.mkdir() should be replaced by Path.mkdir()
PTH103 pathlib-makedirs os.makedirs() should be replaced by Path.mkdir(parents=True)
PTH104 pathlib-rename os.rename() should be replaced by Path.rename()
PTH105 pathlib-replace os.replace() should be replaced by Path.replace()
PTH106 pathlib-rmdir os.rmdir() should be replaced by Path.rmdir()
PTH107 pathlib-remove os.remove() should be replaced by Path.unlink()
PTH108 pathlib-unlink os.unlink() should be replaced by Path.unlink()
PTH109 pathlib-getcwd os.getcwd() should be replaced by Path.cwd()
PTH110 pathlib-exists os.path.exists() should be replaced by Path.exists()
PTH111 pathlib-expanduser os.path.expanduser() should be replaced by Path.expanduser()
PTH112 pathlib-is-dir os.path.isdir() should be replaced by Path.is_dir()
PTH113 pathlib-is-file os.path.isfile() should be replaced by Path.is_file()
PTH114 pathlib-is-link os.path.islink() should be replaced by Path.is_symlink()
PTH115 pathlib-readlink os.readlink() should be replaced by Path.readlink()
PTH116 pathlib-stat os.stat() should be replaced by Path.stat(), Path.owner(), or
PTH117 pathlib-is-abs os.path.isabs() should be replaced by Path.is_absolute()
PTH118 pathlib-join os.path.join() should be replaced by Path with / operator
PTH119 pathlib-basename os.path.basename() should be replaced by
PTH120 pathlib-dirname os.path.dirname() should be replaced by Path.parent
PTH121 pathlib-samefile os.path.samefile() should be replaced by Path.samefile()
PTH122 pathlib-splitext os.path.splitext() should be replaced by Path.suffix
PTH123 pathlib-open open() should be replaced by
PTH124 pathlib-py-path py.path is in maintenance mode, use pathlib instead

eradicate (ERA)#

For more, see eradicate on PyPI.

Code Name Message Fix
ERA001 commented-out-code Found commented-out code 🛠

pandas-vet (PD)#

For more, see pandas-vet on PyPI.

Code Name Message Fix
PD002 use-of-inplace-argument inplace=True should be avoided; it has inconsistent behavior 🛠
PD003 use-of-dot-is-null .isna is preferred to .isnull; functionality is equivalent
PD004 use-of-dot-not-null .notna is preferred to .notnull; functionality is equivalent
PD007 use-of-dot-ix .ix is deprecated; use more explicit .loc or .iloc
PD008 use-of-dot-at Use .loc instead of .at. If speed is important, use numpy.
PD009 use-of-dot-iat Use .iloc instead of .iat. If speed is important, use numpy.
PD010 use-of-dot-pivot-or-unstack .pivot_table is preferred to .pivot or .unstack; provides same functionality
PD011 use-of-dot-values Use .to_numpy() instead of .values
PD012 use-of-dot-read-table .read_csv is preferred to .read_table; provides same functionality
PD013 use-of-dot-stack .melt is preferred to .stack; provides same functionality
PD015 use-of-pd-merge Use .merge method instead of pd.merge function. They have equivalent functionality.
PD901 df-is-a-bad-variable-name df is a bad variable name. Be kinder to your future self.

pygrep-hooks (PGH)#

For more, see pygrep-hooks on GitHub.

Code Name Message Fix
PGH001 no-eval No builtin eval() allowed
PGH002 deprecated-log-warn warn is deprecated in favor of warning
PGH003 blanket-type-ignore Use specific rule codes when ignoring type issues
PGH004 blanket-noqa Use specific rule codes when using noqa

Pylint (PL)#

For more, see Pylint on PyPI.

Convention (PLC)#

Code Name Message Fix
PLC0414 useless-import-alias Import alias does not rename original package 🛠
PLC1901 compare-to-empty-string {} can be simplified to {} as an empty string is falsey
PLC3002 unnecessary-direct-lambda-call Lambda expression called directly. Execute the expression inline instead.

Error (PLE)#

Code Name Message Fix
PLE0100 yield-in-init __init__ method is a generator
PLE0101 return-in-init Explicit return in __init__
PLE0116 continue-in-finally continue not supported inside finally clause
PLE0117 nonlocal-without-binding Nonlocal name {name} found without binding
PLE0118 used-prior-global-declaration Name {name} is used prior to global declaration on line
PLE0604 invalid-all-object Invalid object in __all__, must contain only strings
PLE0605 invalid-all-format Invalid format for __all__, must be tuple or list
PLE1142 await-outside-async await should be used within an async function
PLE1205 logging-too-many-args Too many arguments for logging format string
PLE1206 logging-too-few-args Not enough arguments for logging format string
PLE1307 bad-string-format-type Format type does not match argument type
PLE1310 bad-str-strip-call String {strip} call contains duplicate characters (did you mean {removal}?)
PLE1507 invalid-envvar-value Invalid type for initial os.getenv argument; expected str
PLE2502 bidirectional-unicode Contains control characters that can permit obfuscated code
PLE2510 invalid-character-backspace Invalid unescaped character backspace, use "\b" instead 🛠
PLE2512 invalid-character-sub Invalid unescaped character SUB, use "\x1A" instead 🛠
PLE2513 invalid-character-esc Invalid unescaped character ESC, use "\x1B" instead 🛠
PLE2514 invalid-character-nul Invalid unescaped character NUL, use "\0" instead 🛠
PLE2515 invalid-character-zero-width-space Invalid unescaped character zero-width-space, use "\u200B" instead 🛠

Refactor (PLR)#

Code Name Message Fix
PLR0133 comparison-of-constant Two constants compared in a comparison, consider replacing {left_constant} {op} {right_constant}
PLR0206 property-with-parameters Cannot have defined parameters for properties
PLR0402 consider-using-from-import Use from {module} import {name} in lieu of alias 🛠
PLR0911 too-many-return-statements Too many return statements ({returns} > {max_returns})
PLR0912 too-many-branches Too many branches ({branches} > {max_branches})
PLR0913 too-many-arguments Too many arguments to function call ({c_args} > {max_args})
PLR0915 too-many-statements Too many statements ({statements} > {max_statements})
PLR1701 consider-merging-isinstance Merge these isinstance calls: isinstance({obj}, ({types}))
PLR1711 useless-return Useless return statement at end of function 🛠
PLR1722 consider-using-sys-exit Use sys.exit() instead of {name} 🛠
PLR2004 magic-value-comparison Magic value used in comparison, consider replacing {value} with a constant variable
PLR5501 collapsible-else-if Consider using elif instead of else then if to remove one indentation level

Warning (PLW)#

Code Name Message Fix
PLW0120 useless-else-on-loop else clause on loop without a break statement; remove the else and de-indent all the code inside it
PLW0602 global-variable-not-assigned Using global for {name} but no assignment is done
PLW0603 global-statement Using the global statement to update {name} is discouraged
PLW1508 invalid-envvar-default Invalid type for environment variable default; expected str or None
PLW2901 redefined-loop-name Outer {outer_kind} variable {name} overwritten by inner {inner_kind} target

tryceratops (TRY)#

For more, see tryceratops on PyPI.

Code Name Message Fix
TRY002 raise-vanilla-class Create your own exception
TRY003 raise-vanilla-args Avoid specifying long messages outside the exception class
TRY004 prefer-type-error Prefer TypeError exception for invalid type
TRY200 reraise-no-cause Use raise from to specify exception cause
TRY201 verbose-raise Use raise without specifying exception name
TRY300 try-consider-else Consider moving this statement to an else block
TRY301 raise-within-try Abstract raise to an inner function
TRY400 error-instead-of-exception Use logging.exception instead of logging.error
TRY401 verbose-log-message Redundant exception object included in logging.exception call

NumPy-specific rules (NPY)#

Code Name Message Fix
NPY001 numpy-deprecated-type-alias Type alias np.{type_name} is deprecated, replace with builtin type 🛠
NPY002 numpy-legacy-random Replace legacy np.random.{method_name} call with np.random.Generator

Ruff-specific rules (RUF)#

Code Name Message Fix
RUF001 ambiguous-unicode-character-string String contains ambiguous unicode character {confusable} (did you mean {representant}?) 🛠
RUF002 ambiguous-unicode-character-docstring Docstring contains ambiguous unicode character {confusable} (did you mean {representant}?) 🛠
RUF003 ambiguous-unicode-character-comment Comment contains ambiguous unicode character {confusable} (did you mean {representant}?) 🛠
RUF005 unpack-instead-of-concatenating-to-collection-literal Consider {expr} instead of concatenation 🛠
RUF006 asyncio-dangling-task Store a reference to the return value of asyncio.{method}
RUF007 pairwise-over-zipped Prefer itertools.pairwise() over zip() when iterating over successive pairs
RUF100 unused-noqa Unused noqa directive 🛠