[project] name = "testsandmisc" version = "0.1.0" description = "Collection of miscellaneous tests and scripts" requires-python = ">=3.10" # ============================================================================ # RUFF - Extremely fast Python linter and formatter (written in Rust) # ============================================================================ [tool.ruff] target-version = "py310" # Include all Python files include = ["*.py", "**/*.py"] # Exclude vendored/build directories exclude = [ ".git", ".venv", "__pycache__", "build", "dist", ".eggs", "Bash/ffmpeg-build", # Vendored FFmpeg tools ] [tool.ruff.lint] # AGGRESSIVE: Select ALL rules from all categories select = ["ALL"] # Ignores for rules that are too strict for this mixed script repository ignore = [ # D203 vs D211 conflict - we use D211 (no blank line before class docstring) "D203", # 1 blank line required before class docstring (conflicts with D211) # D212 vs D213 conflict - we use D212 (summary on first line after """) "D213", # Multi-line docstring summary should start at second line (conflicts with D212) # Formatter conflicts - these rules conflict with ruff format "COM812", # Trailing comma missing (conflicts with formatter) "ISC001", # Implicit string concatenation (conflicts with formatter) ] # Allow ALL rules to be auto-fixed fixable = ["ALL"] unfixable = [] # Per-file ignores for test files [tool.ruff.lint.per-file-ignores] # Test files - allow test-specific patterns "**/tests/**/*.py" = [ "S101", # Allow assert in tests "S603", # Allow subprocess calls in tests "PLR2004", # Allow magic values in tests "PTH", # Allow os.path in tests for simplicity ] "**/test_*.py" = [ "S101", # Allow assert in tests "S603", # Allow subprocess calls in tests "S310", # Allow URL open in tests "S607", # Allow partial executable path in tests "PLC0415", # Allow late imports for test isolation "PTH", # Allow os.path in tests for simplicity ] "**/conftest.py" = [ "D100", # Allow missing module docstring "D103", # Allow missing function docstring "PTH", # Allow os.path in conftest ] "python_pkg/random_jpg/generate_jpeg.py" = [ "PTH", # os.path patterns in existing code "LOG015", # Root logger in script "G004", # f-strings in logging ] "python_pkg/tag_divider/tag_divider.py" = [ "PTH", # os.path patterns in existing code "LOG015", # Root logger in script ] "poker_modifier_app/*.py" = [ "LOG015", # Root logger in script "G004", # f-strings in logging ] "poker_modifier_app/poker_modifier_app.py" = [ "FBT003", # Boolean positional values in tkinter API calls "LOG015", # Root logger in app "G004", # f-strings in logging ] "python_pkg/download_cats/generate_cats.py" = [ "PTH", # os.path patterns in existing code "LOG015", # Root logger in script "G004", # f-strings in logging ] "python_pkg/lichess_bot/main.py" = [ "C901", # Complex functions handling game lifecycle (run_bot, handle_game) "PLR0912", # Complex nested game event handling with many branches "PLR0915", # Long function handling complete game lifecycle "S603", # Subprocess call for analysis script "PTH", # os.path patterns in existing code "LOG015", # Root logger in bot "G004", # f-strings in logging ] "python_pkg/lichess_bot/engine.py" = [ "S603", # Subprocess for engine communication "PTH", # os.path patterns "LOG015", # Root logger for debug messages ] "python_pkg/lichess_bot/lichess_api.py" = [ "LOG015", # Root logger in API client "G004", # f-strings in logging ] "python_pkg/lichess_bot/utils.py" = [ "PTH", # os.path patterns "LOG015", # Root logger "G004", # f-strings in logging ] "python_pkg/lichess_bot/tools/generate_blunder_tests.py" = [ "PTH", # os.path patterns in tool "LOG015", # Root logger in tool "G004", # f-strings in logging ] "python_pkg/stockfish_analysis/analyze_chess_game.py" = [ "C901", # Complex main() with many argument combinations and analysis modes "PLR0912", # Complex main() with many argument combinations and analysis modes "PLR0915", # Long main() handling complete analysis workflow "PTH", # os.path patterns "LOG015", # Root logger in analysis tool "G004", # f-strings in logging ] "python_pkg/randomize_numbers/random_digits.py" = [ "LOG015", # Root logger in script "G004", # f-strings in logging ] "python_pkg/keyboard_coop/main.py" = [ "FBT003", # Boolean positional values in pygame API calls (e.g., font.render) "PTH", # os.path patterns "LOG015", # Root logger in script ] "python_pkg/screen_locker/screen_lock.py" = [ "FBT003", # Boolean positional values in tkinter API calls "PTH", # os.path patterns "LOG015", # Root logger in app "G004", # f-strings in logging ] "python_pkg/scrape_website/scrape_comics.py" = [ "PTH", # os.path patterns "LOG015", # Root logger in script "G004", # f-strings in logging ] "python_pkg/extract_links/main.py" = [ "PTH", # os.path patterns "LOG015", # Root logger in script "G004", # f-strings in logging ] [tool.ruff.lint.pydocstyle] convention = "google" # Use Google docstring convention [tool.ruff.lint.isort] force-single-line = false force-sort-within-sections = true known-first-party = ["python_pkg"] [tool.ruff.lint.flake8-quotes] docstring-quotes = "double" inline-quotes = "double" [tool.ruff.lint.flake8-tidy-imports] ban-relative-imports = "all" [tool.ruff.lint.pylint] max-args = 5 max-branches = 12 max-returns = 6 max-statements = 50 [tool.ruff.lint.mccabe] max-complexity = 10 [tool.ruff.format] quote-style = "double" indent-style = "space" skip-magic-trailing-comma = false line-ending = "auto" docstring-code-format = true # ============================================================================ # MYPY - Static type checker (most aggressive settings) # ============================================================================ [tool.mypy] python_version = "3.10" # Strict mode enables most checks strict = true # Additional aggressive settings warn_return_any = true warn_unused_configs = true disallow_untyped_defs = true disallow_incomplete_defs = true check_untyped_defs = true disallow_untyped_decorators = true no_implicit_optional = true warn_redundant_casts = true warn_unused_ignores = true warn_no_return = true warn_unreachable = true # Extra strict settings disallow_any_unimported = true disallow_any_explicit = false # Too aggressive for practical use disallow_any_generics = true disallow_subclassing_any = true strict_equality = true extra_checks = true # Allow missing imports for third-party packages ignore_missing_imports = true # Show error codes show_error_codes = true # Enable colored output color_output = true # Exclude vendored directories exclude = [ "Bash/ffmpeg-build/", ".venv/", ] # ============================================================================ # PYLINT - Comprehensive Python linter # ============================================================================ [tool.pylint.main] # Analyse import fallback blocks analyse-fallback-blocks = true # Pickle collected data for later comparisons persistent = true # Jobs to use for parallel execution (0 = auto) jobs = 0 # Minimum Python version py-version = "3.10" # Ignore vendored directories ignore = ["Bash", ".venv", "__pycache__", "downloadCats", "keyboardCoop", "randomJPG", "scapeWebsite", "tagDivider"] # Ignore patterns ignore-patterns = [".*\\.pyi$"] [tool.pylint.messages_control] # Enable all checks by disabling disable enable = "all" # Minimal disabled checks - only truly problematic ones disable = [ "raw-checker-failed", "bad-inline-option", "locally-disabled", "file-ignored", "suppressed-message", "useless-suppression", "deprecated-pragma", "use-symbolic-message-instead", "too-few-public-methods", # Often false positive for data classes "invalid-name", # Existing camelCase folder names (downloadCats, etc.) ] [tool.pylint.format] # Maximum line length (same as ruff/black) max-line-length = 88 # Maximum module lines max-module-lines = 1000 [tool.pylint.design] # Maximum arguments for function/method max-args = 5 # Maximum local variables max-locals = 15 # Maximum return statements max-returns = 6 # Maximum branches in function body max-branches = 12 # Maximum statements in function body max-statements = 50 # Maximum parents for a class max-parents = 7 # Maximum attributes for a class max-attributes = 10 # Maximum public methods for a class max-public-methods = 20 # Minimum public methods for a class min-public-methods = 1 [tool.pylint.similarities] # Minimum lines for similarity check min-similarity-lines = 4 # Ignore comments when computing similarities ignore-comments = true # Ignore docstrings when computing similarities ignore-docstrings = true # Ignore imports when computing similarities ignore-imports = true [tool.pylint.spelling] # No spelling dictionary to avoid false positives spelling-dict = "" [tool.pylint.typecheck] # Ignore missing members for dynamic modules ignored-modules = ["chess", "pygame", "cv2", "PIL"] # ============================================================================ # BANDIT - Security linter # ============================================================================ [tool.bandit] # Exclude test directories and vendored code exclude_dirs = ["tests", ".venv", "Bash/ffmpeg-build"] # Use all tests tests = [] # No skipped tests (most aggressive) skips = [] # Severity level: all (1=low, 2=medium, 3=high) severity = 1 # Confidence level: all confidence = 1 # ============================================================================ # BLACK - Code formatter (for comparison/fallback) # ============================================================================ [tool.black] line-length = 88 target-version = ["py310"] include = '\.pyi?$' extend-exclude = ''' /( \.git | \.venv | __pycache__ | Bash/ffmpeg-build )/ ''' # ============================================================================ # ISORT - Import sorting (for comparison/fallback, ruff handles this) # ============================================================================ [tool.isort] profile = "black" line_length = 88 force_single_line = false force_sort_within_sections = true known_first_party = ["PYTHON"] skip = [".venv", "__pycache__", "Bash/ffmpeg-build"] # ============================================================================ # PYTEST - Testing framework configuration # ============================================================================ [tool.pytest.ini_options] testpaths = ["tests", "PYTHON", "articles"] python_files = ["test_*.py", "*_test.py"] python_classes = ["Test*"] python_functions = ["test_*"] addopts = [ "-v", "--strict-markers", "--strict-config", "-ra", ] filterwarnings = [ "error", "ignore::DeprecationWarning", ] # ============================================================================ # COVERAGE - Code coverage configuration # ============================================================================ [tool.coverage.run] source = ["PYTHON", "articles", "poker-modifier-app"] branch = true omit = [ "*/__pycache__/*", "*/tests/*", "*/.venv/*", "Bash/*", ] [tool.coverage.report] # Fail under this percentage fail_under = 0 show_missing = true skip_covered = false exclude_lines = [ "pragma: no cover", "def __repr__", "raise AssertionError", "raise NotImplementedError", "if __name__ == .__main__.:", "if TYPE_CHECKING:", ] # ============================================================================ # VULTURE - Dead code detection # ============================================================================ # Note: Vulture uses command-line args, but we can document settings here # vulture --min-confidence 80 --exclude ".venv,Bash" . # ============================================================================ # PYDOCSTYLE - Docstring style checker (ruff handles this, but for standalone) # ============================================================================ # Configured in ruff.lint.pydocstyle above