chore: add noqa blocker, per-app timeouts, clean up per-file-ignores

- Add no-noqa and no-ruff-noqa pre-commit hooks
- Add per-app timeout overrides for beeper/signal (20m)
- Remove excessive per-file-ignores for cinema_planner, linux_configuration,
  word_frequency, praca_magisterska_video
- Add PT019 allowance for test files
- Add S310 per-file exceptions for geo_data.py and library_hider.py
This commit is contained in:
Krzysztof kuhy Rudnicki 2026-04-10 18:46:17 +02:00
parent 21781d547e
commit e05335bbb7
3 changed files with 35 additions and 127 deletions

View File

@ -54,6 +54,22 @@ repos:
args: [--fix=lf]
- id: requirements-txt-fixer
# ===========================================================================
# NOQA BLOCKER - Zero tolerance for noqa/type:ignore suppression comments
# ===========================================================================
- repo: local
hooks:
- id: no-noqa
name: Block noqa comments
entry: '(?i)#\s*(noqa|type:\s*ignore)'
language: pygrep
types: [python]
- id: no-ruff-noqa
name: Block ruff noqa file-level comments
entry: '(?i)#\s*ruff:\s*noqa'
language: pygrep
types: [python]
# ===========================================================================
# RUFF - Fast Python linter and formatter (replaces black, isort, flake8, etc.)
# ===========================================================================

View File

@ -31,6 +31,12 @@ AUTO_CLOSE_TIMEOUT_MINUTES=10
# Warning before auto-close (in minutes before timeout)
AUTO_CLOSE_WARNING_MINUTES=2
# Per-app timeout overrides (apps not listed use AUTO_CLOSE_TIMEOUT_MINUTES)
declare -A APP_TIMEOUT_MINUTES=(
["beeper"]=20
["signal-desktop"]=20
)
# Apps to limit (name -> binary path)
# These are the primary wrapper locations (what the user calls)
declare -A APPS=(
@ -175,7 +181,9 @@ launch_with_timer() {
local real_binary="$2"
shift 2
local warning_seconds=$(((AUTO_CLOSE_TIMEOUT_MINUTES - AUTO_CLOSE_WARNING_MINUTES) * 60))
# Use per-app timeout if set, otherwise fall back to global default
local timeout_minutes="${APP_TIMEOUT_MINUTES[$app]:-$AUTO_CLOSE_TIMEOUT_MINUTES}"
local warning_seconds=$(((timeout_minutes - AUTO_CLOSE_WARNING_MINUTES) * 60))
local running_file
running_file=$(get_running_file "$app")
@ -188,7 +196,7 @@ launch_with_timer() {
# Record state
echo "$app_pid $(date +%s)" >"$running_file"
log_message "LAUNCHED: $app with PID $app_pid (auto-close in ${AUTO_CLOSE_TIMEOUT_MINUTES}m)"
log_message "LAUNCHED: $app with PID $app_pid (auto-close in ${timeout_minutes}m)"
# Spawn the auto-close daemon in a completely detached subshell
# Uses process-name matching so it works for Electron apps that fork on launch
@ -222,7 +230,7 @@ launch_with_timer() {
# Kill all matching processes (handles forked Electron children)
kill_app "$real_binary"
echo "$(date '+%Y-%m-%d %H:%M:%S') - AUTO-CLOSED: $app after ${AUTO_CLOSE_TIMEOUT_MINUTES}m" >>"$LOG_FILE" 2>/dev/null || true
echo "$(date '+%Y-%m-%d %H:%M:%S') - AUTO-CLOSED: $app after ${timeout_minutes}m" >>"$LOG_FILE" 2>/dev/null || true
fi
rm -f "$running_file" 2>/dev/null || true

View File

@ -51,6 +51,7 @@ unfixable = []
"**/tests/**/*.py" = [
"S101", # Allow assert in tests
"PLR2004", # Allow magic values in tests
"PT019", # Allow underscore-prefixed fixture params
"SLF001", # Allow private member access in tests
]
"**/test_*.py" = [
@ -59,8 +60,12 @@ unfixable = []
"S607", # Allow partial executable path in tests
"PLC0415", # Allow late imports for test isolation
"PLR2004", # Allow magic values in tests
"PT019", # Allow underscore-prefixed fixture params
"SLF001", # Allow private member access in tests
]
# Files using urlopen with validated URL schemes
"python_pkg/geo_data.py" = ["S310"]
"python_pkg/steam_backlog_enforcer/library_hider.py" = ["S310"]
"poker_modifier_app/poker_modifier_app.py" = [
"FBT003", # Boolean positional values in tkinter API calls
]
@ -77,133 +82,12 @@ unfixable = []
"C901", # Complex interactive mode is acceptable
"PLR0912", # Too many branches in interactive mode
]
# Cinema planner - CLI tool with print output
"python_pkg/cinema_planner/*.py" = [
"ARG001", # Unused function argument (callbacks)
"T201", # print() is intentional for CLI output
"D101", # Missing docstring in public class
"D102", # Missing docstring in public method
"D103", # Missing docstring in public function
"D104", # Missing docstring in public package
"ANN201", # Missing return type annotation
"ANN202", # Missing return type annotation (private)
"C901", # Complex functions acceptable for CLI
"E501", # Line too long
"EM102", # Exception f-string literal
"PERF203", # try-except in loop
"PERF401", # List comprehension
"PLR0912", # Too many branches
"PLR0915", # Too many statements
"PLR2004", # Magic values
"PLR1714", # Multiple comparisons
"PTH123", # open() instead of Path.open()
"S607", # Partial executable path
"SIM105", # Use contextlib.suppress
"TRY003", # Long exception messages
]
# Linux configuration scripts - standalone scripts
"linux_configuration/**/*.py" = [
"ARG001", # Unused function argument (signal handlers)
"BLE001", # Blind exception catching in scripts
"T201", # print() is intentional for scripts
"ANN001", # Missing function argument type annotation
"ANN201", # Missing return type annotation
"ANN202", # Missing return type annotation (private)
"ANN204", # Missing return type for __init__
"C901", # Complex functions in scripts
"D100", # Missing module docstring
"D103", # Missing docstring in public function
"D107", # Missing docstring in __init__
"D205", # 1 blank line required between summary and description
"D415", # First line should end with period
"DTZ005", # datetime without timezone
"E501", # Line too long
"EXE001", # Shebang without executable permission
"N806", # Non-lowercase variable name
"PERF203", # try-except in loop
"PGH003", # Use specific rule codes
"PLR0912", # Too many branches
"PLR0915", # Too many statements
"PLR2004", # Magic values
"PTH100", # Path manipulation
"PTH103", # Path manipulation
"PTH108", # Path manipulation
"PTH110", # Path manipulation
"PTH111", # Path manipulation
"PTH112", # Path manipulation
"PTH118", # Path manipulation
"PTH119", # Path manipulation
"PTH120", # Path manipulation
"PTH122", # Path manipulation
"PTH123", # open() instead of Path.open()
"PTH202", # Path manipulation
"S110", # try-except-pass
"S607", # Partial executable path
"SIM102", # Collapsible if
"SIM105", # Use contextlib.suppress
"SIM115", # Use context manager
"TRY300", # Consider else block
]
# Word frequency package - legacy code with pre-existing complexity
"python_pkg/word_frequency/*.py" = [
"C901", # Function complexity - legacy code
"PLR0911", # Too many return statements - legacy code
"PLR0912", # Too many branches - legacy code
"PLR0913", # Too many arguments - legacy code
"PLR0915", # Too many statements - legacy code
"PLR2004", # Magic values - legacy code
"FBT001", # Boolean typed argument - legacy code
"FBT002", # Boolean default argument - legacy code
"FBT003", # Boolean positional value - legacy code
"T201", # print() used for CLI feedback
"TRY003", # Long exception messages - legacy code
"EM101", # Exception string literal - legacy code
"EM102", # Exception f-string literal - legacy code
"SIM105", # Use contextlib.suppress - legacy code
"SIM108", # Use ternary operator - legacy code
"SIM117", # Use single with statement - legacy code
"PLW2901", # Loop variable overwritten - legacy code
"PLW0603", # Global statement - legacy code
"TRY300", # Consider else block - legacy code
"TRY301", # Abstract raise - legacy code
"PTH123", # open() instead of Path.open() - legacy code
"EXE001", # Shebang without executable - legacy code
"ARG001", # Unused function argument - legacy code
"ARG002", # Unused method argument - legacy code
"ARG005", # Unused lambda argument - legacy code
"F401", # Unused import - legacy code
"F841", # Unused variable - legacy code
"TC003", # Move stdlib import to type-checking block - legacy code
"SLF001", # Private member access - legacy code
"SIM101", # Multiple isinstance calls - legacy code
"PERF401", # List comprehension - legacy code
"N806", # Non-lowercase variable - legacy code
"C416", # Unnecessary list comprehension - legacy code
"E501", # Line too long - legacy code
]
# Thesis diagram generators - one-off matplotlib plotting scripts
# Thesis diagram generation scripts - matplotlib plotting helpers need many params
"python_pkg/praca_magisterska_video/**/*.py" = [
"ANN001", # Missing type annotation - plotting scripts, not library code
"ANN202", # Missing return type (private)
"BLE001", # Blind exception (file I/O error handling)
"C901", # Function complexity - long plotting functions
"E501", # Line too long - matplotlib call chains
"E741", # Ambiguous variable name - math convention (l, I)
"ERA001", # Commented-out code - contains notes and alternatives
"FBT002", # Boolean default argument - matplotlib patterns
"FBT003", # Boolean positional value - matplotlib API calls
"N806", # Uppercase variable - math convention (X, Y, F_A)
"PERF203", # try-except in loop - file processing
"PERF401", # List append in loop
"PLR0912", # Too many branches - plotting functions
"PLR0913", # Too many arguments - plotting functions
"PLR0915", # Too many statements - plotting functions
"PLR2004", # Magic values - plot coordinates and sizes
"PLW2901", # Loop variable overwritten - data processing
"S110", # try-except-pass - optional dependency handling
"T201", # print() for script output
"PLR0913", # Matplotlib drawing functions inherently require many parameters
]
[tool.ruff.lint.pydocstyle]
convention = "google" # Use Google docstring convention