# ============================================================================
# NHL Scrabble - Project Configuration
# ============================================================================
# Central configuration file for the NHL Scrabble Score Analyzer project.
# Follows PEP 621 (Project Metadata), PEP 517 (Build System), PEP 518 (pyproject.toml).
#
# Documentation:
# - PEP 621: https://peps.python.org/pep-0621/
# - PEP 517: https://peps.python.org/pep-0517/
# - PEP 518: https://peps.python.org/pep-0518/
#
# Auto-formatting: This file is automatically formatted by pyproject-fmt pre-commit hook.
# Manual formatting is not necessary - commit changes and the hook applies formatting.
#
# Key Sections:
# - [build-system]: Build backend configuration (hatchling + hatch-vcs)
# - [project]: Core metadata (name, version, dependencies, etc.)
# - [project.optional-dependencies]: Extra dependency groups (test, lint, docs, etc.)
# - [tool.*]: Tool-specific configurations (ruff, mypy, pytest, etc.)
#
# Versioning Strategy:
# - Version is dynamically determined from git tags via hatch-vcs
# - Tagged release: v0.1.0 → Package version 0.1.0
# - Development: 5 commits after v0.1.0 → 0.1.1.dev5+g<hash>
# - No tags: 0.0.0+unknown
# - To release: git tag -a v0.1.0 -m "Release 0.1.0" && git push --tags
#
# Dependency Philosophy:
# - Use >= for minimum versions (maximum compatibility)
# - Only specify minimums when specific features required
# - Avoid upper bounds unless breaking changes known
# - Document WHY minimum versions are specified
#
# Tool Configuration Philosophy:
# - Enable ALL rules by default (comprehensive quality)
# - Selectively ignore with documented justification
# - Matches ruff's "ALL rules" approach
# - Per-file exceptions documented with rationale
# ============================================================================
[build-system]
build-backend = "hatchling.build"
requires = [
    "babel>=2.14.0", # For compiling .po to .mo during build
    "hatch-vcs",
    "hatchling",
]

[project]
name = "nhl-scrabble"
description = "NHL Roster Scrabble Score Analyzer - Calculate Scrabble scores for NHL player names"
readme = "README.md"
keywords = [
    "analytics",
    "hockey",
    "nhl",
    "scrabble",
    "sports",
]
requires-python = ">=3.12"
classifiers = [
    "Development Status :: 4 - Beta",
    "Intended Audience :: Developers",
    "Intended Audience :: End Users/Desktop",
    "License :: OSI Approved :: MIT License",
    "Programming Language :: Python :: 3 :: Only",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Programming Language :: Python :: 3.14",
    "Topic :: Games/Entertainment",
    "Topic :: Software Development :: Libraries :: Python Modules",
]
dynamic = [ "version" ]
dependencies = [
    "certifi",
    "click",
    "colorlog>=6.10.1",
    "dicttoxml>=1.7.16",
    "fastapi",
    "httpx>=0.28.1",
    "jinja2>=3.1.6",
    "platformdirs>=4.0.0",
    "prompt-toolkit>=3.0.52",
    "pydantic",
    "pydantic-settings>=2.7.3",
    "pyyaml>=6.0.3",
    "requests>=2.33.1",
    "requests-cache>=1.3.1",
    "rich>=15.0.0",
    "starlette>=1.0.0",
    "unidecode>=1.3.0",
    "uvicorn[standard]>=0.27.0",
]
[[project.authors]]
name = "Brandon Perkins"
email = "bdperkin@gmail.com"
[project.license]
text = "MIT"
[project.optional-dependencies]
test = [
    "beautifulsoup4",
    "diff-cover>=10.2.0",
    "pytest>=9.0.3",
    "pytest-benchmark>=5.2.3",
    "pytest-clarity>=1.0.1",
    "pytest-cov>=7.1.0",
    "pytest-doctestplus>=1.3.2",
    "pytest-mock>=3.15.1",
    "pytest-randomly>=4.1.0",
    "pytest-rerunfailures>=16.1",
    "pytest-sugar>=1.1.1",
    "pytest-timeout>=2.4.0",
    "pytest-xdist>=3.8.0",
]
lint = [
    "djlint>=1.34.0",
    "refurb>=2.3.1",
    "ruff",
]
type = [
    "mypy",
    "ty",
    "types-pyyaml>=6.0.12.20260408",
    "types-requests>=2.33.0.20260408",
]
security = [
    "bandit[toml]>=1.7.5",
    "pip-audit>=2.10.0",
    "pip-licenses>=5.5.5",
    "safety>=3.7.0",
]
branding = [
    "cairosvg>=2.9.0",
    "pillow>=12.2.0",
]
export = [
    "openpyxl>=3.1.5",
]
i18n = [
    "babel>=2.14.0",
    "flask-babel>=4.0.0",
]
docs = [
    "blacken-docs>=1.20.0",
    "linkchecker>=10.0.0",
    "myst-parser>=5.0.0",
    "pytest-sphinx>=0.7.1",
    "sphinx>=9.1.0",
    "sphinx-autobuild>=2025.8.25",
    "sphinx-autodoc-typehints>=3.10.2",
    "sphinx-copybutton>=0.5.2",
    "sphinx-design>=0.7.0",
    "sphinx-rtd-theme>=3.1.0",
    "sphinx-sitemap>=2.9.0",
    "sphinxcontrib-programoutput>=0.19",
    "sphinxcontrib-spelling>=8.0.2",
    "sphinxext-opengraph>=0.13.0",
]
docs-gen = [
    "pdoc>=16.0.0",
]
qa = [
    "locust>=2.32.7",
    "pytest-playwright>=0.7.0",
]
watch = [
    "pytest-watch",
]
build = [
    "build",
]
publish = [
    "twine>=6.2.0",
]
tox = [
    "tox",
    "tox-uv>=1.35.1",
]
shell = [
    "bashate>=2.1.1",
    "beautysh>=6.2.1",
]
dev = [
    "check-jsonschema>=0.37.1",
    "nhl-scrabble[build,docs,export,lint,publish,security,shell,test,tox,type,watch]",
    "pre-commit",
    "tomli>=2.4.1",
    "tomli-w>=1.2.0",
]
[project.scripts]
nhl-scrabble = "nhl_scrabble.cli:cli"
[project.urls]
Homepage = "https://bdperkin.github.io/nhl-scrabble/"
Documentation = "https://bdperkin.github.io/nhl-scrabble/"
Repository = "https://github.com/bdperkin/nhl-scrabble"
Issues = "https://github.com/bdperkin/nhl-scrabble/issues"
Changelog = "https://github.com/bdperkin/nhl-scrabble/blob/main/CHANGELOG.md"

[tool.hatch.build.hooks.custom]
# Compile .po translation files to .mo during package build
# This ensures .mo files are included in the wheel/sdist without committing them to git
path = "scripts/hatch_build.py"
[tool.hatch.build.hooks.vcs]
version-file = "src/nhl_scrabble/_version.py"
[tool.hatch.build.targets.wheel]
packages = [
    "src/nhl_scrabble",
]
[tool.hatch.version]
source = "vcs"

[tool.uv]
python-preference = "managed"
constraint-dependencies = []
override-dependencies = []
index-strategy = "first-index"
keyring-provider = "disabled"
resolution = "highest"
compile-bytecode = true
link-mode = "copy"
managed = true
package = true
cache-keys = []
preview = false
[tool.uv.sources]

[tool.black]
line-length = 100
target-version = [
    "py312",
]
skip-string-normalization = false
skip-magic-trailing-comma = false
extend-exclude = """\
    /(\n  # directories\n  \\.eggs\n  | \\.git\n  | \\.tox\n  | \\.venv\n  | venv\n  | build\n  | \
    dist\n  | \\.egg-info\n  | __pycache__\n  | \\.pytest_cache\n  | \\.mypy_cache\n  | \
    \\.ruff_cache\n  # auto-generated files\n  | src/nhl_scrabble/_version\\.py\n)/\n\
    """

[tool.ruff]
target-version = "py312"
line-length = 100
src = [
    "src",
    "tests",
]
exclude = [
    "src/nhl_scrabble/_version.py",
]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
docstring-code-format = false
[tool.ruff.lint]
select = [
    "ALL",
]
ignore = [
    "E501",
    "COM812",
    "ISC001",
    "D100",
    "D101",
    "D102",
    "D103",
    "D104",
    "D105",
    "D106",
    "D107",
    "D413",
    "FBT001",
    "FBT002",
    "TD002",
    "TD003",
    "FIX002",
    "EM101",
    "EM102",
    "TRY003",
    "TRY300",
    "TRY400",
    "G004",
    "PLR2004",
    "PERF203",
    "PLC0206",
    "TC001",
    "PTH123",
    "PERF102",
    "RET504",
    "D203",
    "D213",
    "PYI034",
    "PYI036",
]
[tool.ruff.lint.isort]
known-first-party = [
    "nhl_scrabble",
]
[tool.ruff.lint.mccabe]
max-complexity = 10
[tool.ruff.lint.per-file-ignores]
"__init__.py" = [
    "F401",
    "D104",
]
"scripts/**/*.py" = [
    "T201",
    "S603",
    "S607",
    "INP001",
]
"tests/**/*.py" = [
    "ARG",
    "S101",
    "PLR2004",
    "ANN",
    "PLC0415",
    "SLF001",
]
"src/nhl_scrabble/cli.py" = [
    "T201",
    "PLC0415",
    "TC003",
    "C901",
]
"src/nhl_scrabble/logging_config.py" = [
    "PLC0415",
    "PERF403",
]
"src/nhl_scrabble/__main__.py" = [
    "T201",
]
"scripts/generate_branding.py" = [
    "T201",
    "PLR0915",
]
"scripts/update_dependencies.py" = [
    "T201",
    "C901",
    "PLR0911",
    "PLR0912",
    "PLR0915",
    "S607",
]
"src/nhl_scrabble/api/nhl_client.py" = [
    "C901",
    "PLR0912",
    "ANN401",  # API responses return dict[str, Any] for unstructured JSON
]
"src/nhl_scrabble/api_server/routes/*.py" = [
    "FAST002",
    "TRY301",
    "ERA001",
    "C901",
]
"tests/unit/test_nhl_client.py" = [
    "SLF001",
]
"src/nhl_scrabble/reports/base.py" = [
    "ANN401", # Abstract method intentionally uses Any for flexibility
]
"src/nhl_scrabble/formatters/factory.py" = [
    "ANN401", # Factory pattern requires flexible kwargs
]
"src/nhl_scrabble/formatters/__init__.py" = [
    "ANN401", # Factory pattern requires flexible kwargs
]
"src/nhl_scrabble/models/*.py" = [
    "ANN401", # to_dict() methods return dict[str, Any] for JSON serialization
]
"src/nhl_scrabble/reports/comparison.py" = [
    "ANN401", # JSON generation methods return dict[str, Any]
]
"src/nhl_scrabble/validators.py" = [
    "ANN401", # API response validation uses dict[str, Any]
]
"src/nhl_scrabble/web/app.py" = [
    "ANN401",  # FastAPI/Pydantic response models use dict[str, Any]
    "C901",
    "PLR0912",
]
"src/nhl_scrabble/exporters/excel_exporter.py" = [
    "ANN401", # Excel export methods accept dict[str, Any] for flexibility
]
"src/nhl_scrabble/formatters/*.py" = [
    "ANN401", # Formatters accept dict[str, Any] for unstructured data
]
"src/nhl_scrabble/utils/retry.py" = [
    "ANN401", # Decorator wrappers use *args: Any, **kwargs: Any pattern
]
"src/nhl_scrabble/security/circuit_breaker.py" = [
    "ANN401", # Generic wrapper uses *args: Any, **kwargs: Any pattern
]
[tool.ruff.lint.pylint]
max-args = 7
max-branches = 12
max-returns = 6
max-statements = 50

[tool.isort]
profile = "black"
line_length = 100
known_first_party = [
    "nhl_scrabble",
]
src_paths = [
    "src",
    "tests",
]
skip_gitignore = true
sections = [
    "FUTURE",
    "STDLIB",
    "THIRDPARTY",  # codespell:ignore THIRDPARTY
    "FIRSTPARTY",
    "LOCALFOLDER",
]
multi_line_output = 3
include_trailing_comma = true
force_grid_wrap = 0
use_parentheses = true
ensure_newline_before_comments = true
skip_glob = [
    ".eggs/*",
    ".git/*",
    ".tox/*",
    ".venv/*",
    "venv/*",
    "build/*",
    "dist/*",
    "*.egg-info/*",
    "__pycache__/*",
    "src/nhl_scrabble/_version.py",
]

[tool.flake8]
max-line-length = 100
extend-ignore = [
    "E501",
    "W503",
    "E203",
]
per-file-ignores = [
    "__init__.py:F401,F403",
    "tests/*:S101",
    "src/nhl_scrabble/api/nhl_client.py:C901",
    "src/nhl_scrabble/api_server/routes/players.py:C901",
    "src/nhl_scrabble/validators.py:C901",
    "src/nhl_scrabble/cli.py:TC003,C901",
    "src/nhl_scrabble/config_validators.py:C901",
    "src/nhl_scrabble/web/app.py:C901",
    "scripts/update_dependencies.py:C901",
]
max-complexity = 10
exclude = [
    ".git",
    ".tox",
    ".venv",
    "venv",
    "build",
    "dist",
    "*.egg-info",
    "__pycache__",
    ".pytest_cache",
    ".mypy_cache",
    ".ruff_cache",
    "src/nhl_scrabble/_version.py",
]

[tool.codespell]
check-filenames = true
check-hidden = true
skip = """\
    *.lock,*.json,*.min.js,*.svg,*.po,htmlcov/*,.git/*,.tox/*,.venv/*,*.egg-info/*,build/*,dist/*,.\
    pytest_cache/*,.mypy_cache/*,.ruff_cache/*,docs/reference/api,docs/_build/*\
    """
ignore-words = ".codespell-ignore-words.txt"
count = true
quiet-level = 0

[tool.docformatter]
wrap_length = 100
wrap_summaries = 100
wrap_descriptions = 100
black = false
style = "pep257"
make_summary_multi_line = false
close_quotes_on_newline = false
pre_summary_newline = false
exclude = [
    ".git",
    ".tox",
    ".venv",
    "venv",
    "build",
    "dist",
    "*.egg-info",
    "src/nhl_scrabble/_version.py",
]

[tool.check-wheel-contents]
toplevel = [
    "nhl_scrabble",
]
ignore = [
    "W002",
]

[tool.deptry]
exclude = [
    "\\.git",
    "\\.tox",
    "\\.venv",
    "venv",
    "build",
    "dist",
    ".*\\.egg-info",
    "__pycache__",
    "tests",
    "qa",
    "scripts",
]
ignore = []
pep621_dev_dependency_groups = [
    "dev",
    "test",
    "lint",
    "type",
    "security",
    "docs",
    "watch",
    "build",
    "publish",
    "tox",
    "docs-gen",
    "branding",
    "shell",
]
known_first_party = [ "nhl_scrabble" ]
[tool.deptry.package_module_name_map]
bandit = "bandit"
beautifulsoup4 = "beautifulsoup4"
blacken-docs = "blacken_docs"
build = "build"
cairosvg = "cairosvg"
certifi = "certifi"
check-jsonschema = "check_jsonschema"
colorlog = "colorlog"
dicttoxml = "dicttoxml"
diff-cover = "diff_cover"
fastapi = "fastapi"
httpx = "httpx"
jinja2 = "jinja2"
linkchecker = "linkchecker"
mypy = "mypy"
myst-parser = "myst_parser"
nhl-scrabble = "nhl_scrabble"
openpyxl = "openpyxl"
pdoc = "pdoc"
Pillow = "pillow"
pip-audit = "pip_audit"
pip-licenses = "pip_licenses"
pre-commit = "pre_commit"
prompt-toolkit = "prompt_toolkit"
pydantic = "pydantic"
pytest-benchmark = "pytest_benchmark"
pytest-clarity = "pytest_clarity"
pytest-cov = "pytest_cov"
pytest-mock = "pytest_mock"
pytest = "pytest"
pytest-randomly = "pytest_randomly"
pytest-rerunfailures = "pytest_rerunfailures"
pytest-sphinx = "pytest_sphinx"
pytest-sugar = "pytest_sugar"
pytest-timeout = "pytest_timeout"
pytest-watch = "pytest_watch"
pytest-xdist = "pytest_xdist"
python-dotenv = "dotenv"
pyyaml = "yaml"
refurb = "refurb"
requests-cache = "requests_cache"
requests = "requests"
rich = "rich"
ruff = "ruff"
safety = "safety"
sphinx-autobuild = "sphinx_autobuild"
sphinx-autodoc-typehints = "sphinx_autodoc_typehints"
sphinxcontrib-programoutput = "sphinxcontrib_programoutput"
sphinxcontrib-spelling = "sphinxcontrib_spelling"
sphinx-copybutton = "sphinx_copybutton"
sphinx-design = "sphinx_design"
sphinxext-opengraph = "sphinxext_opengraph"
sphinx-rtd-theme = "sphinx_rtd_theme"
sphinx-sitemap = "sphinx_sitemap"
sphinx = "sphinx"
starlette = "starlette"
tomli = "tomli"
tomli-w = "tomli_w"
tox = "tox"
tox-uv = "tox_uv"
twine = "twine"
types-PyYAML = "types_pyyaml"
types-requests = "types_requests"
ty = "ty"
uvicorn = "uvicorn"
[tool.deptry.per_rule_ignores]
DEP002 = [
    "babel",
    "bashate",
    "beautysh",
    "flask-babel",
    "locust",
    "pytest-playwright",
]

[tool.pyproject-fmt]
column_width = 100
indent = 4
keep_full_version = true
table_format = "long"

[tool.bandit]
targets = [
    "src",
]
exclude_dirs = [
    "tests",
    ".tox",
    ".venv",
    "venv",
    "build",
    "dist",
    "*.egg-info",
    "src/nhl_scrabble/_version.py",
]
severity = "LOW"
confidence = "LOW"
skips = [
    "B101",
    "B311",
]
exclude_tests = []

[tool.mypy]
python_version = "3.12"
plugins = [ "pydantic.mypy" ]
exclude = [
    "src/nhl_scrabble/_version.py",
    "scripts/",
]
strict = true
warn_unreachable = true
warn_no_return = true
disallow_any_unimported = false
disallow_any_expr = false
disallow_any_decorated = false
disallow_any_explicit = true  # Warn about explicit Any usage
disallow_any_generics = true
disallow_subclassing_any = true
warn_unused_ignores = true
warn_return_any = true
warn_redundant_casts = true
warn_unused_configs = true
strict_optional = true
strict_equality = true
strict_concatenate = true
show_error_context = true
show_column_numbers = true
show_error_code_links = true
pretty = true
color_output = true
error_summary = true
show_absolute_path = false
namespace_packages = true
explicit_package_bases = false
ignore_missing_imports = true
mypy_path = "src"
check_untyped_defs = true
disallow_incomplete_defs = true
disallow_untyped_defs = true
no_implicit_optional = true
no_implicit_reexport = true
[[tool.mypy.overrides]]
module = [
    "tests.*",
    "qa.*",
]
# Relax type checking for test files
disallow_untyped_defs = false
disallow_untyped_decorators = false
disallow_any_expr = false
disallow_any_explicit = false
check_untyped_defs = false
[[tool.mypy.overrides]]
module = [
    "nhl_scrabble.cli",
    "nhl_scrabble.web.*",
    "nhl_scrabble.api_server.*",
]
# Disable strict checks for modules using third-party decorators (Click, FastAPI)
# that don't provide complete type information
disallow_untyped_decorators = false
disallow_subclassing_any = false
disallow_any_explicit = false
[[tool.mypy.overrides]]
module = [
    "update_dependencies",
]
# Script uses conditional imports for compatibility
warn_unused_ignores = false
[[tool.mypy.overrides]]
module = [
    "nhl_scrabble.reports.base",
    "nhl_scrabble.reports.comparison",
    "nhl_scrabble.reports.stats_report",
    "nhl_scrabble.reports.generator",
    "nhl_scrabble.formatters.*",
    "nhl_scrabble.models.*",
    "nhl_scrabble.web.app",
    "nhl_scrabble.validators",
    "nhl_scrabble.api.nhl_client",
    "nhl_scrabble.filters",
    "nhl_scrabble.utils.retry",
    "nhl_scrabble.security.circuit_breaker",
    "nhl_scrabble.exporters.*",
    "nhl_scrabble.rate_limiter",
    "nhl_scrabble.storage.*",
    "nhl_scrabble.scoring.scrabble",
    "nhl_scrabble.config",
    "nhl_scrabble.dashboard",
    "nhl_scrabble.logging_config",
    "nhl_scrabble.processors.team_processor",
    "nhl_scrabble.interactive.shell",
]
# Allow explicit Any for legitimate use cases:
# - Abstract base classes with generic methods
# - JSON serialization/deserialization
# - API response handling
# - Factory patterns
# - Generic wrappers and decorators
# - Pre-existing type inconsistencies
disallow_any_explicit = false
# Don't warn about unused type: ignore comments (Jinja2 i18n extension adds methods dynamically)
warn_unused_ignores = false

[tool.ty.environment]
python-version = "3.12"
[tool.ty.rules]
[tool.ty.src]
include = [
    "src/",
    "tests/",
]
[tool.ty.terminal]
error-on-warning = false

[tool.pytest.ini_options]
testpaths = [
    "tests",
]
python_files = [
    "test_*.py",
]
python_classes = [
    "Test*",
]
python_functions = [
    "test_*",
]
timeout = 60
timeout_method = "thread"
junit_family = "xunit2"
junit_logging = "all"
addopts = [
    "--strict-markers",
    "--strict-config",
    "-n",
    "auto",
    "--cov=nhl_scrabble",
    "--cov-report=term-missing:skip-covered",
    "--cov-report=html",
    "--cov-report=xml",
    "--timeout=60",
]
markers = [
    "unit: Unit tests",
    "integration: Integration tests",
    "slow: Slow running tests",
    "timeout: Custom timeout for specific tests (e.g., @pytest.mark.timeout(300))",
    "no_parallel: Tests that must run sequentially (e.g., @pytest.mark.no_parallel)",
    "flaky: Flaky test that may fail intermittently (will be retried on failure)",
    "performance: Performance tests measuring page load and response times",
    "benchmark: Benchmark tests using pytest-benchmark",
]
doctest_optionflags = [
    "NORMALIZE_WHITESPACE",
    "ELLIPSIS",
    "IGNORE_EXCEPTION_DETAIL",
]

[tool.coverage.html]
directory = "htmlcov"
[tool.coverage.report]
exclude_lines = [
    "pragma: no cover",
    "def __repr__",
    "raise AssertionError",
    "raise NotImplementedError",
    "if __name__ == .__main__.:",
    "if TYPE_CHECKING:",
    "@abstractmethod",
]
precision = 2
show_missing = true
skip_covered = false
[tool.coverage.run]
source = [
    "src",
]
branch = true
omit = [
    "*/tests/*",
    "*/__main__.py",
]

[tool.djlint]
# Template profile (jinja, django, nunjucks, handlebars, twig, angular, golang)
profile = "jinja"
# Indentation
indent = 4
max_line_length = 120
max_attribute_length = 80
# Formatting options
format_css = true
format_js = true
preserve_blank_lines = true
preserve_leading_space = false
# Linting rules
# H006: Img tag without alt attribute (may have decorative images or dynamic alt)
# H021: Inline styles (acceptable for single-file template with <style> block)
# H023: Entity references (using &copy; is standard and readable)
# H030: Consider meta keywords (outdated for SEO, not relevant for reports)
# H031: Consider meta description (not needed for generated reports)
# J004: Static URLs - not using Flask's url_for (project doesn't use Flask static helper)
# J018: Internal links - not using Flask's url_for (direct URLs are intentional)
# T003: Endblock names - optional style preference, blocks are small and clear
# T028: Spaceless tags - minor style preference, doesn't affect functionality
ignore = "H006,H021,H023,H030,H031,J004,J018,T003,T028"
# Exclude patterns (comma-separated glob patterns)
exclude = ".git,.tox,.venv,venv,node_modules,htmlcov,_build,dist"
# Extension matching
extension = "html"

[tool.autoflake]
check = true
in-place = false
remove-all-unused-imports = true
remove-unused-variables = true
remove-duplicate-keys = true
ignore-init-module-imports = true
exclude = [
    ".git",
    ".tox",
    ".venv",
    "venv",
    "build",
    "dist",
    "*.egg-info",
    "__pycache__",
    "src/nhl_scrabble/_version.py",
]

[tool.refurb]
enable_all = true
python_version = "3.12"
ignore = [
    "FURB113", # Multiple append() calls are sometimes more readable than extend()
    "FURB120", # Explicit default arguments can improve code clarity
]

[tool.ssort]
skip = [
    "tests/fixtures/",
    "migrations/",
    "src/nhl_scrabble/_version.py",
]
src_paths = [
    "src/",
    "tests/",
]

[tool.diff_cover]
compare_branch = "origin/main"
fail_under = 80.0
include_paths = [
    "src/",
]
exclude_paths = [
    "tests/",
    "*/__main__.py",
]

[tool.pytest_benchmark]
save = true
save_data = true
compare = "0001"
fail_on_regression = true
regression_threshold = 0.2
storage = ".benchmarks"
columns = [
    "min",
    "max",
    "mean",
    "stddev",
    "median",
    "iqr",
    "outliers",
    "rounds",
    "iterations",
]
histogram = "normal"
warmup = true
warmup_iterations = 5
min_time = 5e-06

[tool.rstcheck]
report_level = "INFO"
ignore_directives = []
ignore_roles = []
ignore_substitutions = []
ignore_languages = []
ignore_messages = ""

[tool.doc8]
max-line-length = 100
extensions = [
    ".rst",
    ".txt",
]
ignore-path = [
    ".git",
    ".tox",
    ".venv",
    "venv",
    "build",
    "dist",
    "*.egg-info",
    "__pycache__",
    ".pytest_cache",
    ".mypy_cache",
    ".ruff_cache",
    "htmlcov",
]
ignore = []
verbose = false
file-encoding = "utf-8"

[tool.mdformat]
wrap = 100
number = true
end_of_line = "lf"

[tool.pymarkdown.mode]
strict-config = true
[tool.pymarkdown.plugins]
enabled = [
    "md001",
    "md002",
    "md003",
    "md004",
    "md005",
    "md006",
    "md007",
    "md009",
    "md010",
    "md011",
    "md012",
    "md013",
    "md014",
    "md018",
    "md019",
    "md020",
    "md021",
    "md022",
    "md023",
    "md024",
    "md025",
    "md026",
    "md027",
    "md028",
    "md029",
    "md030",
    "md031",
    "md032",
    "md033",
    "md034",
    "md035",
    "md036",
    "md037",
    "md038",
    "md039",
    "md040",
    "md041",
    "md042",
    "md043",
    "md044",
    "md045",
    "md046",
    "md047",
    "md048",
    "md049",
    "md050",
    "md051",
    "md052",
    "md053",
]
disabled = []
[tool.pymarkdown.plugins.md010]
enabled = false
[tool.pymarkdown.plugins.md012]
enabled = true
[tool.pymarkdown.plugins.md013]
enabled = false
[tool.pymarkdown.plugins.md022]
enabled = false
[tool.pymarkdown.plugins.md024]
enabled = false
[tool.pymarkdown.plugins.md029]
enabled = false
[tool.pymarkdown.plugins.md031]
enabled = false
[tool.pymarkdown.plugins.md032]
enabled = false
[tool.pymarkdown.plugins.md033]
enabled = false
[tool.pymarkdown.plugins.md034]
enabled = false
[tool.pymarkdown.plugins.md036]
enabled = false
[tool.pymarkdown.plugins.md040]
enabled = false
[tool.pymarkdown.plugins.md041]
enabled = false
[tool.pymarkdown.plugins.md043]
enabled = false

[tool.interrogate]
fail-under = 100.0
verbose = 2
quiet = false
color = true
ignore-init-method = false
ignore-init-module = false
ignore-magic = false
ignore-module = false
ignore-nested-functions = false
ignore-nested-classes = false
ignore-overloaded-functions = false
ignore-private = false
ignore-semiprivate = false
ignore-property-decorators = false
ignore-setters = false
exclude = [
    ".git",
    ".tox",
    ".venv",
    "venv",
    "build",
    "dist",
    "*.egg-info",
    "__pycache__",
    "tests",
    "scripts",
    ".scratch",
    "src/nhl_scrabble/_version.py",
    "qa",
]
ext = []
style = "sphinx"
omit-covered-files = false

[tool.unimport]
exclude = "\\.git|\\.tox|\\.venv|venv|build|dist|.*\\.egg-info|__pycache__|src/nhl_scrabble/_version\\.py"
ignore_init = true
include_star_import = false
gitignore = true

[tool.pydocstyle]
convention = "pep257"
match = ".*\\.py"
match_dir = "[^\\.].*"
match-dir = "(?!_version\\.py$).*"
add-ignore = [
    "D100",
    "D101",
    "D102",
    "D103",
    "D104",
    "D105",
    "D106",
    "D107",
    "D202",
    "D203",
    "D213",
    "D413",
]

[tool.vulture]
exclude = [
    ".git",
    ".tox",
    ".venv",
    "venv",
    "build",
    "dist",
    "*.egg-info",
    "__pycache__",
    "src/nhl_scrabble/_version.py",
]
ignore_decorators = [
    "@*.command",
    "@*.group",
    "@*.option",
    "@*.argument",
    "@pytest.fixture",
    "@pytest.mark.*",
    "@app.route",
    "@app.get",
    "@app.post",
    "@app.put",
    "@app.patch",
    "@app.delete",
    "@*.register",
    "@property",
    "@*.setter",
    "@*.getter",
    "@staticmethod",
    "@classmethod",
    "@abstractmethod",
]
ignore_names = [
    "exc_*",
    "format",
    "NHLApiNotFoundError",
    "track_score_calculation",
    "track_report_generation",
    "track_api_fetching",
    "ReportGenerator",
    "get_report",
    "validate_safe_path",
    "validate_url",
    "validate_float_range",
    "validate_output_format",
    "reset",
    "health",
    "root",
    "favicon",
    "dispatch",
    "templates",
    "get_players",
    "get_standings",
    "get_team",
    "get_teams",
    "get_translator",
    "format_number",
    "test_*",
    "fixture_*",
    "*_fixture",
    "args",
    "kwargs",
    "_*",
]
min_confidence = 60
