Comprehensive static code analysis tool for Python that performs deep code inspection without executing the program
—
Optional extensions providing 25+ additional specialized checkers for advanced code analysis. Extensions enhance pylint's capabilities with domain-specific checks, advanced pattern detection, and integration with external tools and standards.
System for loading and managing optional checker extensions.
def initialize(linter):
"""
Standard extension initialization function.
Each extension module must provide this function to register
its checkers with the linter.
Args:
linter: PyLinter instance to register checkers with
"""
# Extension loading patterns
def register(linter):
"""Alternative registration function name."""
pass
def load_configuration(linter):
"""Load extension-specific configuration."""
passAdvanced code style and formatting checkers beyond the standard format checker.
# Code style enhancements
import pylint.extensions.code_style
# - Additional naming convention checks
# - Enhanced formatting validation
# - Style consistency enforcement
# Empty comment detection
import pylint.extensions.empty_comment
# - Detect and flag empty comment lines
# - Configurable comment content validation
# Bad builtin usage
import pylint.extensions.bad_builtin
# - Flag usage of problematic builtin functions
# - Suggest better alternatives
# - Configurable builtin blacklistAdvanced complexity metrics and analysis tools.
# McCabe complexity analysis
import pylint.extensions.mccabe
# - Cyclomatic complexity calculation
# - Configurable complexity thresholds
# - Function and method complexity limits
# Broad try clause detection
import pylint.extensions.broad_try_clause
# - Detect overly broad try blocks
# - Encourage specific exception handling
# - Configurable try block size limitsComprehensive docstring and documentation checking.
# Docstring parameter validation
import pylint.extensions.docparams
# - Validate docstring parameters match function signature
# - Check parameter descriptions
# - Validate return value documentation
# - Support for multiple docstring formats (Google, NumPy, Sphinx)
# Docstring style checking
import pylint.extensions.docstyle
# - Docstring format validation
# - Style consistency checking
# - Missing docstring detection enhancementAdvanced type checking and analysis capabilities.
# Enhanced type checking
import pylint.extensions.typing
# - Additional type annotation validation
# - Generic type usage checking
# - Type compatibility analysis
# - Protocol and TypedDict validation
# Equality without hash detection
import pylint.extensions.eq_without_hash
# - Detect classes with __eq__ but no __hash__
# - Flag potential dictionary/set usage issues
# - Suggest proper hash implementationCheckers focused on performance patterns and optimization opportunities.
# Set membership optimization
import pylint.extensions.set_membership
# - Detect inefficient membership testing
# - Suggest set/frozenset for O(1) lookups
# - Flag repeated list/tuple membership checks
# For/any/all pattern detection
import pylint.extensions.for_any_all
# - Suggest using any() or all() instead of loops
# - Detect common iteration patterns
# - Performance optimization suggestionsAdvanced control flow and conditional logic analysis.
# Elif condition analysis
import pylint.extensions.check_elif
# - Validate elif condition logic
# - Detect unreachable elif branches
# - Suggest condition simplification
# Confusing elif detection
import pylint.extensions.confusing_elif
# - Flag potentially confusing elif structures
# - Suggest clearer conditional logic
# - Detect overlapping conditions
# Ternary expression suggestions
import pylint.extensions.consider_ternary_expression
# - Suggest ternary operators for simple if/else
# - Improve code conciseness
# - Configurable complexity thresholdsAdvanced import analysis and dependency management.
# Private import detection
import pylint.extensions.private_import
# - Detect imports from private modules
# - Flag underscore-prefixed imports
# - Validate API boundary respect
# Overlapping exception detection
import pylint.extensions.overlapping_exceptions
# - Detect overlapping exception handlers
# - Flag unreachable except clauses
# - Suggest exception hierarchy improvementsEnhanced variable usage and assignment pattern analysis.
# Redefined variable type detection
import pylint.extensions.redefined_variable_type
# - Detect variables assigned different types
# - Flag potential type confusion
# - Suggest consistent typing patterns
# Unused self parameter detection
import pylint.extensions.no_self_use
# - Detect methods that don't use self
# - Suggest staticmethod or function conversion
# - Configurable whitelist patternsDetection and management of magic numbers and strings.
# Magic value detection
import pylint.extensions.magic_value
# - Detect magic numbers and strings
# - Suggest named constants
# - Configurable value whitelists
# - Context-aware detectionAdvanced comparison and logical expression analysis.
# Zero comparison optimization
import pylint.extensions.comparetozero
# - Detect inefficient zero comparisons
# - Suggest truthiness testing
# - Flag explicit None comparisons
# No else return pattern
import pylint.extensions.no_else_return
# - Detect unnecessary else after return
# - Suggest early return patterns
# - Improve code flow readabilityfrom pylint.lint import PyLinter
# Load extension programmatically
linter = PyLinter()
from pylint.extensions import mccabe
mccabe.initialize(linter)
# Load multiple extensions
extensions = [
'pylint.extensions.mccabe',
'pylint.extensions.docparams',
'pylint.extensions.code_style'
]
for ext_name in extensions:
linter.load_plugin(ext_name)# Load single extension
pylint --load-plugins=pylint.extensions.mccabe mymodule.py
# Load multiple extensions
pylint --load-plugins=mccabe,docparams,code_style mymodule.py
# Load all available extensions
pylint --load-plugins=pylint.extensions mymodule.py# McCabe complexity configuration
linter.config.max_complexity = 10
# Docparams configuration
linter.config.accept_no_param_doc = False
linter.config.accept_no_raise_doc = False
linter.config.accept_no_return_doc = False
linter.config.accept_no_yields_doc = False
# Magic value configuration
linter.config.valid_magic_values = [-1, 0, 1, 2]
linter.config.valid_magic_strings = ['', 'utf-8', 'ascii']# Creating a custom extension
from pylint.checkers import BaseChecker
from pylint.interfaces import IAstroidChecker
class CustomExtensionChecker(BaseChecker):
"""Custom extension checker example."""
__implements__ = IAstroidChecker
name = 'custom-extension'
msgs = {
'C9900': (
'Custom extension message: %s',
'custom-extension-message',
'Description of custom extension check'
)
}
options = (
('custom-option', {
'default': True,
'type': 'yn',
'help': 'Enable custom extension behavior'
}),
)
def visit_functiondef(self, node):
"""Custom analysis logic."""
if self.config.custom_option:
# Perform custom analysis
self.add_message('custom-extension-message',
node=node, args=(node.name,))
def initialize(linter):
"""Register the custom extension."""
linter.register_checker(CustomExtensionChecker(linter))# pylint.extensions.docparams
# - missing-param-doc: Missing parameter documentation
# - missing-type-doc: Missing parameter type documentation
# - missing-return-doc: Missing return documentation
# - missing-return-type-doc: Missing return type documentation
# - missing-raises-doc: Missing exception documentation
# pylint.extensions.docstyle
# - docstring-first-line-empty: Empty first docstring line
# - docstring-min-length: Docstring too short# pylint.extensions.mccabe
# - too-complex: Function/method too complex
# pylint.extensions.code_style
# - consider-using-assignment-expr: Consider using assignment expression
# - consider-using-namedtuple-or-dataclass: Consider namedtuple/dataclass
# pylint.extensions.magic_value
# - magic-value-comparison: Magic value used in comparison# pylint.extensions.set_membership
# - use-set-for-membership: Use set for membership testing
# pylint.extensions.for_any_all
# - consider-using-any-or-all: Consider using any() or all()# pylint.extensions.consider_ternary_expression
# - consider-ternary-expression: Consider using ternary expression
# pylint.extensions.confusing_elif
# - confusing-elif: Confusing elif condition# .pylintrc configuration
[DESIGN]
max-complexity = 10
[MESSAGES CONTROL]
enable = too-complex[PARAMETER_DOCUMENTATION]
accept-no-param-doc = no
accept-no-raise-doc = no
accept-no-return-doc = no
accept-no-yields-doc = no
default-docstring-type = sphinx[MAGIC_VALUE]
valid-magic-values = -1,0,1,2,100,1000
valid-magic-strings = '',utf-8,ascii,latin-1Install with Tessl CLI
npx tessl i tessl/pypi-pylint