RulesΒΆ

Each rule below reports a pattern that makes code harder to read or review, and most can fix it.

  • Filter the table by code, name or description, or narrow it to a group or to rules with a fix.

  • The address bar keeps the filter, so you can share a filtered view as a link.

  • To choose which rules run, see Choose which rules run and fix.

108 rules
CodeNameChecksFixCross-file
Comments
SMP001section-commentComments used as dividers or section headersπŸ› οΈβœ—
SMP002long-paragraphComment paragraphs over the word limitβœ—
SMP003suppression-without-reasonnoqa, type: ignore and pragma comments with no reasonβœ—
SMP004blanket-ignoreSuppression comments that name no error codeβœ—
SMP005restating-commentComments that only repeat the code belowπŸ› οΈβœ—
SMP006string-statement-commentBare strings used as comments instead of # commentsπŸ”§βœ—
SMP007long-comment-lineComment and docstring lines over the line lengthπŸ› οΈβœ—
Naming
SMP101single-letter-nameSingle-letter names outside comprehensionsβœ—
SMP102module-variable-caseModule variables not UPPER_CASEπŸ”§βœ“
SMP103meaningless-nameVariables, parameters and attributes named with a word that says nothingβœ—
SMP104catch-all-moduleModules and packages named for a grab bag of codeβœ—
Module layout
SMP201definition-before-useHelpers defined above their first caller, or away from itπŸ”§βœ—
SMP202single-user-constantModule constants only one function usesπŸ”§βœ“
SMP203class-member-orderClass members defined out of section order, such as a constructor below a methodπŸ”§βœ—
Imports and dependencies
SMP301future-annotationsfrom __future__ import annotations on Python 3.14+πŸ”§βœ—
SMP302absolute-sibling-importAbsolute imports from the same packageπŸ› οΈβœ—
SMP303dependency-import-guardtry/except ImportError around a required dependencyπŸ”§βœ—
SMP304module-attribute-importModule attributes reached as module.Name instead of importedπŸ”§βœ“
SMP305up-backport-importImports of backports that the standard library replacesπŸ”§βœ—
SMP306up-type-checking-lazy-importif TYPE_CHECKING: imports that can be lazy importsπŸ”§βœ—
SMP307up-lazy-modules-list__lazy_modules__ lists that lazy imports replaceπŸ”§βœ—
SMP308import-cycleRuntime imports that close a cycle between modulesβœ“
SMP309star-importimport * of a module the project defines, which names can be imported one by oneπŸ”§βœ“
Public API
SMP401missing-from-allNames other modules import that __all__ omitsπŸ”§βœ“
SMP402unused-export__all__ entries no other module importsπŸ”§βœ“
SMP403unexported-public-namePublic functions and classes missing from __all__πŸ”§βœ“
SMP404module-variable-prefixModule variables whose leading _ does not match their visibilityπŸ”§βœ“
SMP405all-format__all__ not a list with a trailing commaπŸ› οΈβœ—
SMP406all-not-last__all__ not at the end of the moduleπŸ”§βœ—
SMP407init-module-content__init__.py holding more than a docstringβœ“
SMP408test-only-codeModule-level functions and classes only test modules useβœ“
SMP409unused-definitionFunctions, classes, methods and class attributes nothing in the run usesβœ“
SMP410test-only-parameterParameters only test calls pass, which production calls leave at their defaultβœ“
SMP411unused-return-valueReturn values no production call readsβœ“
Logic
SMP501forwarding-functionPrivate functions that only forward to another callβœ“
SMP502walrus-candidateAn assignment the next if test could absorb with :=πŸ› οΈβœ“
SMP503string-concatenation+ between stringsπŸ”§βœ“
SMP504single-use-variableVariables read once, right below their assignmentπŸ› οΈβœ—
SMP505single-caller-helperPrivate helpers with one short call site, which inlining would keep shortβœ“
SMP506unused-defaultParameter defaults that every call passes explicitlyπŸ”§βœ“
SMP507error-message-matchingExceptions told apart by their message textβœ“
SMP508up-comprehension-unpackingNested for clauses that only unpack their iterable into the elementπŸ› οΈβœ—
SMP509up-traceback-exception-argumentstraceback calls that pass an exception's type and traceback next to itπŸ› οΈβœ—
SMP510up-exc-info-exceptionsys.exc_info() reads of the exception being handledπŸ› οΈβœ—
SMP511up-object-sentinelobject() placeholders sentinel would nameπŸ› οΈβœ—
SMP512up-context-var-token-resetContextVar.set() tokens reset in a finally blockπŸ”§βœ—
SMP513up-chdir-restoreWorking directories restored in a finally blockπŸ”§βœ—
SMP514up-strptime-datedatetime.strptime() results narrowed to a date or timeπŸ”§βœ—
SMP515up-event-loop-in-coroutineasyncio.get_event_loop() calls in coroutinesπŸ”§βœ—
SMP516up-asyncio-iscoroutinefunctionasyncio.iscoroutinefunction() callsπŸ”§βœ—
SMP517up-codecs-opencodecs.open() callsπŸ”§βœ—
SMP518up-re-error-aliasre.error referencesπŸ› οΈβœ—
SMP519up-argparse-suggest-on-errorsuggest_on_error=True in ArgumentParser() callsπŸ”§βœ—
SMP520up-removed-ast-nodeast node aliases and visitor methods Python 3.14 removedπŸ”§βœ—
SMP521up-utf8-encoding-defaultUTF-8 encoding arguments that Python 3.15 makes the defaultπŸ”§βœ—
SMP522up-re-prefixmatchre.match() calls that re.prefixmatch() namesπŸ› οΈβœ—
SMP523up-compression-modulesgzip, bz2, lzma and zlib imports that compression namesπŸ”§βœ—
SMP524up-warnings-deprecatedFunctions and classes that warn with DeprecationWarning where @warnings.deprecated marks themπŸ”§βœ—
SMP525up-deprecated-stdlib-aliasDeprecated standard library names that have a replacementπŸ”§βœ—
SMP526early-assignmentConstants assigned well above their first useπŸ”§βœ—
SMP527super-forwarding-methodMethods that only return the parent's method called with their own argumentsπŸ”§βœ—
SMP528long-tuple-returnFunctions returning tuples too long to unpack by positionβœ—
SMP529cognitive-complexityFunctions whose cognitive complexity is over the limitβœ—
SMP530duplicate-codeStatements that another module repeatsβœ“
SMP531collection-built-by-statementsEmpty collections filled by the statements right after themπŸ”§βœ—
SMP532unnamed-regex-groupRegular expressions with unnamed capture groupsπŸ”§βœ—
SMP533unexplained-regexRegular expressions with four or more parts and no commentsβœ—
Typing
SMP601missing-finalModule constants not annotated FinalπŸ”§βœ“
SMP602imprecise-annotationobject and Any in annotationsβœ—
SMP603callable-ellipsisCallable[..., T]βœ—
SMP604vars-callvars() callsβœ—
Classes
SMP701dataclass-frozenDataclasses without frozenπŸ› οΈβœ“
SMP702dataclass-slotsDataclasses without slotsπŸ› οΈβœ“
SMP703dataclass-kw-onlyDataclasses without kw_onlyπŸ› οΈβœ“
SMP704indistinct-error-classException classes no handler catches by nameβœ“
Tests
SMP801test-classTest classesπŸ”§βœ“
SMP802parametrize-without-idparametrize rows without pytest.param(..., id=...)βœ—
SMP803conditional-in-testif, match and conditional expressions in testsβœ—
SMP804constant-assertAssertions on a truthy constantπŸ”§βœ—
SMP805mock-attribute-assignmentMock attributes assigned after constructionπŸ”§βœ—
SMP806mock-without-specMocks and patches without a specβœ—
SMP807split-composite-assertConsecutive asserts comparing fields of one objectπŸ”§βœ—
SMP808sleep-in-testtime.sleep and asyncio.sleep calls in testsβœ—
SMP809stdlib-mockunittest.mock imports in projects that depend on pytest-mockβœ—
SMP811up-unittest-assert-helperassertTrue and assertFalse on checks that TestCase has a helper forπŸ”§βœ—
SMP812up-unittest-enter-contextPatches started and stopped by hand in TestCase methodsπŸ”§βœ—
SMP813loop-in-testLoops in tests that assert over a table of casesβœ—
SMP814mock-assertion-typoMock assertion methods misspelled or missing their assert_ prefixπŸ› οΈβœ“
SMP815unused-fixturePytest fixtures no test or fixture requestsβœ“
Docstrings
SMP901function-docstringDocstrings on internal functions and classesπŸ”§βœ“
SMP902test-module-docstringDocstrings on test modulesπŸ”§βœ—
SMP903undocumented-public-apiPublic functions, classes, methods and variables without documentationβœ“
SMP904long-docstring-paragraphDocstring paragraphs over the word limitβœ—
SMP910rst-field-syntaxMalformed or misplaced reStructuredText docstring fieldsπŸ”§βœ—
SMP911rst-inline-markupRoles without backticks and unclosed inline literalsπŸ”§βœ—
SMP912rst-type-fieldTypes in docstrings, which belong in annotationsπŸ”§βœ—
SMP913rst-restating-fieldField descriptions that only repeat the nameβœ—
SMP914rst-empty-fieldFields with no descriptionβœ—
SMP915rst-private-fieldPublic docstrings documenting internal namesπŸ”§βœ“
SMP916rst-missing-paramPublic API docstrings that leave a parameter undocumentedβœ“
SMP917rst-unknown-param:param: and :type: fields for parameters the signature lacksπŸ”§βœ—
SMP918rst-duplicate-paramConstructor parameters documented in both the class and __init__ docstringsπŸ”§βœ—
SMP919rst-param-order:param: fields out of the signature's orderβœ—
SMP920rst-missing-attributePublic classes whose docstring leaves an attribute undocumentedβœ“
SMP921rst-unknown-attribute:ivar:, :cvar: and :var: fields for attributes the class lacksπŸ”§βœ—
SMP922rst-attribute-kind:ivar: on class variables and :cvar: on instance attributesπŸ”§βœ—
SMP923rst-returnsMissing, extraneous or misused :returns: and :yields: fieldsπŸ”§βœ“
SMP924rst-missing-raisesPublic API docstrings that leave a raised exception undocumentedβœ“

Rules marked βœ“ under Cross-file read other files of the run; How simplint works explains how. Which fixes count as safe is under Fix safety.