# =============================================================================
# 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
