[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 - recommended to disable when using ruff format # https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules "COM812", # Trailing comma missing - formatter handles this automatically "ISC001", # Implicit string concatenation - formatter may create these when wrapping # Security audit - prone to false positives with validated input # https://github.com/astral-sh/ruff/issues/4045 "S603", # subprocess call without shell - prone to false positives as it is # difficult to determine whether the passed arguments have been validated ] # Allow ALL rules to be auto-fixed fixable = ["ALL"] unfixable = [] # Per-file ignores — only rules that FUNDAMENTALLY conflict with test code remain. # Every other rule was fixed in source. See justifications below. [tool.ruff.lint.per-file-ignores] "**/tests/**/*.py" = [ "ARG", # @patch decorators inject mock params that aren't always referenced; # the patch side-effect is needed, not the mock object itself. "D", # Test names like test_sub_cards_no_answer_text are self-documenting; # docstrings would be redundant noise on every test method. "PLC0415", # Test isolation requires importing AFTER mocking sys.modules; # top-level imports would bypass the mocks entirely. "PLR2004", # assert count == 5 is clearer than assert count == EXPECTED_COUNT; # named constants for test expectations add indirection without value. "S101", # assert IS what tests do — every Python test suite suppresses this. "SLF001", # Unit tests must exercise private internals (_method, _attr) to reach # 100% branch coverage; only integration tests can avoid this. ] "**/test_*.py" = [ "ARG", "D", "PLC0415", "PLR2004", "S101", "SLF001", ] # Heavy ML libraries (torch, transformers, scipy, bark) must be lazily imported # inside functions — they take seconds to load and aren't needed at module level. "python_pkg/music_gen/_music_generation.py" = ["PLC0415"] "python_pkg/music_gen/_music_speech.py" = ["PLC0415"] # Circular dependency: submodules import constants (W, H, CLIP_DUR, etc.) # from this module, so they must be imported lazily inside _build(). "python_pkg/moviepy_showcase/moviepy_showcase.py" = ["PLC0415"] # Matplotlib drawing helpers inherently require many parameters (x, y, w, h, # fill, lw, fontsize, etc.) — refactoring to config dataclasses would break # 57+ callers spread across the diagram generation pipeline. "python_pkg/praca_magisterska_video/generate_images/*.py" = ["PLR0913"] # generate_arch_diagrams.py: matplotlib imports must follow mpl.use("Agg"). "python_pkg/praca_magisterska_video/generate_images/generate_arch_diagrams.py" = [ "E402", "PLR0913", ] # Long deeply-nested import paths and matplotlib text strings can't be shortened. "python_pkg/praca_magisterska_video/**/*.py" = ["E501"] # Circular dependency: _q02_algorithm_steps imports constants from this module. "python_pkg/praca_magisterska_video/visualize_q02.py" = ["E501", "PLC0415"] [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.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/", "python_pkg/music_gen/", # Uses dynamic imports from transformers "python_pkg/praca_magisterska_video/", # Thesis plotting scripts "pomodoro_app/tools/", # Avoid duplicate module named 'tools' "linux_configuration/scripts/misc/testsAndMisc-bash/tools/", # Avoid duplicate module named 'tools' ] # ============================================================================ # 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__"] # Ignore patterns ignore-patterns = [".*\\.pyi$"] # Allow C extension modules to be introspected extension-pkg-allow-list = ["cv2", "pygame", "lxml"] [tool.pylint.messages_control] # Enable all checks by disabling disable enable = "all" # No disabled checks - maximum strictness disable = [] [tool.pylint.design] # A class with just run() as public API is valid for games/apps min-public-methods = 1 # Enforce maximum file length of 500 lines max-module-lines = 500 [tool.pylint.spelling] # No spelling dictionary to avoid false positives spelling-dict = "" [tool.pylint.typecheck] # cv2 (OpenCV) dynamically loads members from C extension at runtime generated-members = ["cv2.*"] # ============================================================================ # BANDIT - Security linter # ============================================================================ [tool.bandit] # Exclude test directories and vendored code exclude_dirs = ["tests", ".venv", "Bash/ffmpeg-build", "python_pkg/lichess_bot/.venv"] # ============================================================================ # BLACK & ISORT - Removed (ruff handles formatting and import sorting) # ============================================================================ # ============================================================================ # PYTEST - Testing framework configuration # ============================================================================ [tool.pytest.ini_options] testpaths = ["python_pkg"] python_files = ["test_*.py", "*_test.py"] python_classes = ["Test*"] python_functions = ["test_*"] addopts = [ "-v", "--strict-markers", "--strict-config", "-ra", "--cov=python_pkg", "--cov-branch", "--cov-report=term-missing", "--cov-report=lcov", ] filterwarnings = [ "error", "ignore::DeprecationWarning", "default::pytest.PytestUnraisableExceptionWarning", ] # ============================================================================ # COVERAGE - Code coverage configuration # ============================================================================ [tool.coverage.run] source = ["python_pkg"] branch = true omit = [ "*/__pycache__/*", "*/tests/*", "*/.venv/*", ] [tool.coverage.report] # Fail under this percentage fail_under = 100 show_missing = true skip_covered = false exclude_lines = [ # Standard exclusions "pragma: no cover", # Unreachable defensive code "raise NotImplementedError", "raise AssertionError", # Type checking imports "if TYPE_CHECKING:", # Main script entry point 'if __name__ == "__main__":', ] # Partial branch exclusions for unreachable branches partial_branches = [ "pragma: no branch", ] # ============================================================================ # VULTURE - Dead code detection # ============================================================================ # Note: Vulture uses command-line args, but we can document settings here # vulture --min-confidence 80 --exclude ".venv,Bash" . # ============================================================================ # FLAKE8 - Python linter (via Flake8-pyproject for pyproject.toml support) # ============================================================================ [tool.flake8] # Maximum line length (matches ruff/black) max-line-length = 88 # Maximum McCabe complexity (matches ruff C901 threshold) max-complexity = 10 # Maximum cognitive complexity (flake8-cognitive-complexity) max-cognitive-complexity = 12 # Maximum function length (flake8-functions) max-function-length = 20 # Maximum returns/arguments per function max-returns-amount = 6 max-arguments = 5 # Docstring convention (matches ruff) docstring-convention = "google" # Select all error codes select = ["E", "F", "W", "C", "B", "B950"] # Extend with plugin codes extend-select = ["B", "B9", "C4", "SIM", "PT", "TC", "ANN"] # Ignore rules that conflict with ruff-format or are duplicated extend-ignore = [ "E501", # Line too long - B950 from bugbear is smarter (allows 10% overflow) "W503", # Line break before binary operator - contradicts PEP 8 update "ANN101", # Missing type annotation for self "ANN102", # Missing type annotation for cls ] # Exclude directories exclude = [ ".git", ".venv", "__pycache__", "build", "dist", ".eggs", "Bash/ffmpeg-build", ] # Per-file ignores per-file-ignores = [ "**/tests/**/*.py:S101,ANN", "**/test_*.py:S101,ANN", ] # ============================================================================ # PYDOCSTYLE - Docstring style checker (ruff handles this, but for standalone) # ============================================================================ # Configured in ruff.lint.pydocstyle above