diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 00000000..00e61031 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,251 @@ +# ============================================================================= +# ThrillWiki Django Project - Pylint Configuration +# ============================================================================= +# +# Purpose: Django-aware Pylint configuration that suppresses false positives +# while maintaining code quality standards. +# +# Alignment: +# - Line length: 120 characters (matches Black and Ruff in pyproject.toml) +# - Django version: 5.2.8 +# +# Key Features: +# - Suppresses false positives for Django ORM patterns (.objects, _meta, .DoesNotExist) +# - Whitelists Django management command styling (self.style.SUCCESS, ERROR, etc.) +# - Accommodates Django REST Framework patterns +# - Allows django-fsm state machine patterns +# +# Maintenance: +# - Review when upgrading Django or adding new dynamic attribute patterns +# - Keep line-length aligned with Black/Ruff settings in pyproject.toml +# +# ============================================================================= + +[MASTER] +# Use all available CPU cores for faster linting +jobs=0 + +# Directories and files to exclude from linting +ignore=.git,__pycache__,.venv,venv,migrations,node_modules,.tox,.pytest_cache,build,dist + +# File patterns to ignore (e.g., Emacs backup files) +ignore-patterns=^\.# + +# Pickle collected data for faster subsequent runs +persistent=yes + +# ============================================================================= +# [MESSAGES CONTROL] +# Disable checks that conflict with Django patterns and conventions +# ============================================================================= +[MESSAGES CONTROL] +disable= + # C0114: missing-module-docstring + # Django apps often don't need module docstrings; the app's purpose is + # typically documented in apps.py or README + C0114, + + # C0115: missing-class-docstring + # Django models, forms, and serializers are often self-documenting through + # their field definitions and Meta classes + C0115, + + # C0116: missing-function-docstring + # Allow simple functions and methods without docstrings; Django views and + # model methods are often self-explanatory + C0116, + + # C0103: invalid-name + # Django uses non-PEP8 names by convention (e.g., 'pk', 'id', 'qs') + # and single-letter variables in comprehensions are acceptable + C0103, + + # C0411: wrong-import-order + # Let isort/ruff handle import ordering; they have Django-specific rules + C0411, + + # C0415: import-outside-toplevel + # Django often requires lazy imports to avoid circular dependencies, + # especially in models.py and signals + C0415, + + # W0212: protected-access + # Django extensively uses _meta for model introspection; this is documented + # and supported API: https://docs.djangoproject.com/en/5.2/ref/models/meta/ + W0212, + + # W0613: unused-argument + # Django views, signals, and receivers often have unused parameters that + # are required by the framework's signature (e.g., request, sender, **kwargs) + W0613, + + # R0903: too-few-public-methods + # Django models, forms, and serializers can be simple data containers + # with few or no methods beyond __str__ + R0903, + + # R0801: duplicate-code + # Django patterns naturally duplicate across apps (e.g., CRUD views, + # model patterns); this is intentional for consistency + R0801, + + # E1101: no-member + # Main source of false positives for Django's dynamic attributes: + # - Model.objects (Manager) + # - Model.DoesNotExist / MultipleObjectsReturned (exceptions) + # - self.style.SUCCESS/ERROR (management commands) + # - model._meta (Options) + E1101 + +# ============================================================================= +# [TYPECHECK] +# Whitelist Django's dynamically generated attributes +# ============================================================================= +[TYPECHECK] +# Django generates many attributes dynamically that Pylint cannot detect +# statically. This list covers common patterns: +# +# - objects.* : Django ORM Manager methods (all, filter, get, create, etc.) +# - DoesNotExist : Exception raised when Model.objects.get() finds nothing +# - MultipleObjectsReturned : Exception when get() finds multiple objects +# - _meta.* : Django model metadata API (fields, app_label, model_name) +# - style.* : Django management command styling (SUCCESS, ERROR, WARNING, NOTICE) +# - id, pk : Django auto-generated primary key fields +# - REQUEST : Django request object attributes +# - aq_* : Acquisition attributes (Zope/Plone compatibility) +# - acl_users : Zope/Plone user folder +# +generated-members= + REQUEST, + acl_users, + aq_parent, + aq_inner, + aq_explicit, + aq_acquire, + aq_base, + objects, + objects.*, + DoesNotExist, + MultipleObjectsReturned, + _meta, + _meta.*, + style, + style.*, + id, + pk + +# ============================================================================= +# [FORMAT] +# Code formatting settings - aligned with Black and Ruff (120 chars) +# ============================================================================= +[FORMAT] +# Maximum line length - matches Black and Ruff configuration in pyproject.toml +max-line-length=120 + +# Use 4 spaces for indentation (Python standard) +indent-string=' ' + +# Use Unix line endings (LF) +expected-line-ending-format=LF + +# ============================================================================= +# [BASIC] +# Naming conventions and allowed short names +# ============================================================================= +[BASIC] +# Short variable names commonly used in Django and Python +# - i, j, k : Loop counters +# - ex : Exception variable +# - Run : Django command method +# - _ : Throwaway variable +# - id, pk : Primary key (Django convention) +# - qs : QuerySet abbreviation +good-names=i,j,k,ex,Run,_,id,pk,qs + +# Enforce snake_case for most identifiers (Python/Django convention) +argument-naming-style=snake_case +attr-naming-style=snake_case +function-naming-style=snake_case +method-naming-style=snake_case +module-naming-style=snake_case +variable-naming-style=snake_case + +# PascalCase for classes +class-naming-style=PascalCase + +# UPPER_CASE for constants +const-naming-style=UPPER_CASE + +# ============================================================================= +# [DESIGN] +# Complexity thresholds - relaxed for Django patterns +# ============================================================================= +[DESIGN] +# Django views and forms often need many arguments +max-args=7 + +# Django models can have many fields +max-attributes=12 + +# Allow complex boolean expressions +max-bool-expr=5 + +# Django views can have complex branching logic +max-branches=15 + +# Django views often have many local variables +max-locals=20 + +# Django uses multiple inheritance (Model, Mixin classes) +max-parents=7 + +# Django models and viewsets have many built-in methods +max-public-methods=25 + +# Allow multiple return statements +max-returns=6 + +# Django views can be lengthy +max-statements=60 + +# Allow simple classes with no methods (e.g., Django Meta classes) +min-public-methods=0 + +# ============================================================================= +# [SIMILARITIES] +# Duplicate code detection settings +# ============================================================================= +[SIMILARITIES] +# Increase threshold to reduce false positives from Django boilerplate +min-similarity-lines=6 + +# Don't flag similar comments +ignore-comments=yes + +# Don't flag similar docstrings +ignore-docstrings=yes + +# Don't flag similar import blocks +ignore-imports=yes + +# ============================================================================= +# [VARIABLES] +# Variable naming patterns +# ============================================================================= +[VARIABLES] +# Patterns for dummy/unused variables +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Arguments that are commonly unused but required by framework signatures +ignored-argument-names=_.*|^ignored_|^unused_|args|kwargs|request|pk + +# ============================================================================= +# [IMPORTS] +# Import checking settings +# ============================================================================= +[IMPORTS] +# Don't allow wildcard imports even with __all__ defined +allow-wildcard-with-all=no + +# Don't analyze fallback import blocks +analyse-fallback-blocks=no