content: [project]
  requires-python = ">=3.13"
  
  [tool.coverage.run]
  source = [
    "custom_components",
    ]
  
  [tool.coverage.report]
  exclude_also = [
    "raise NotImplemented\\(\\)",
    "if __name__ == ['\"]__main__[\"']:",
    ]
  show_missing = true
  
  [tool.pytest.ini_options]
  testpaths = "tests"
  norecursedirs = [".git", ".mypy_cache", ".ruff_cache"]
  addopts = [
    "-p syrupy",
    "--strict",
    "--cov=custom_components",
    "--cov-branch",
    "--cov-report=term",
    "--cov-report=html",
    ]
  
  asyncio_mode = "auto"
  asyncio_default_fixture_loop_scope = "function"
  
  [tool.ruff]
  required-version = ">=0.11.0"
  
  [tool.ruff.lint]
  preview = true
  select = [
    "ERA",    # eradicate
    "ANN",    # flake8-annotations
    "ASYNC",  # flake8-async
    "S",      # flake8-bandit
    "BLE",    # flake8-blind-except
    "FBT",    # flake8-boolean-trap
    "B",      # flake8-bugbear
    "A",      # flake8-builtins
    "COM",    # flake8-commas
    "C4",     # flake8-comprehensions
    "DTZ",    # flake8-datetimez
    "T10",    # flake8-debugger
    "EXE",    # flake8-executable
    "FIX",    # flake8-fixme
    "FA",     # flake8-future-annotations
    "INT",    # flake8-gettext
    "ISC",    # flake8-implicit-str-concat
    "ICN",    # flake8-import-conventions
    "LOG",    # flake8-logging
    "G",      # flake8-logging-format
    "INP",    # flake8-no-pep420
    "PIE",    # flake8-pie
    "T20",    # flake8-print
    "PYI",    # flake8-pyi
    "PT",     # flake8-pytest-style
    "Q",      # flake8-quotes
    "RSE",    # flake8-raise
    "RET",    # flake8-return
    "SLF",    # flake8-self
    "SIM",    # flake8-simplify
    "SLOT",   # flake8-slots
    "TID",    # flake8-tidy-imports
    "TD",     # flake8-todos
    "TC",     # flake8-type-checking
    "ARG",    # flake8-unused-arguments
    "PTH",    # flake8-use-pathlib
    "FLY",    # flynt
    "I",      # isort
    "N",      # pep-naming
    "PERF",   # Perflint
    "E",      # pycodestyle
    "W",      # pycodestyle
    "DOC",    # pydoclint
    "D",      # pydocstyle
    "F",      # Pyflakes
    "PGH",    # pygrep-hooks
    "PL",     # pylint
    "UP",     # pyupgrade
    "FURB",   # refurb
    "RUF",    # ruff-specific rules
    "TRY",    # tryceratops
    ]
  ignore = [
    "E501",     # line too long
    "D100",     # missing docstring in public module
    "D102",     # missing docstring in public method
    "D103",     # missing docstring in public function
    "D104",     # missing docstring in public package
    "D105",     # missing docstring in magic method
    "D202",     # no blank lines allowed after function docstring
    "D203",     # 1 blank line required before class docstring
    "D213",     # multi-line docstring summary should start at the second line
    "N818",     # exception name {name} should be named with an Error suffix
    "PLR0911",  # too many return statements ({returns} > {max_returns})
    "PLR0912",  # too many branches ({branches} > {max_branches})
    "PLR0913",  # too many arguments to function call ({c_args} > {max_args})
    "PLR0915",  # too many statements ({statements} > {max_statements})
    "PLR2004",  # magic value used in comparison, consider replacing {value} with a constant variable
    "PLW2901",  # outer {outer_kind} variable {name} overwritten by inner {inner_kind} target
    "S101",     # use of `assert` detected
  
    # moving imports into type-checking blocks can mess with pytest.patch()
    "TC001",    # move application import {} into a type-checking block
    "TC002",    # move third-party import {} into a type-checking block
    "TC003",    # move standard library import {} into a type-checking block
  
    # May conflict with the formatter, https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
    "COM812",
    ]
  
  [tool.ruff.lint.pydocstyle]
  convention = "google"
  
  [tool.ruff.lint.flake8-import-conventions.extend-aliases]
  voluptuous = "vol"
  "homeassistant.helpers.config_validation" = "cv"
  "homeassistant.helpers.device_registry" = "dr"
  "homeassistant.helpers.entity_registry" = "er"
  "homeassistant.helpers.issue_registry" = "ir"
  "homeassistant.util.dt" = "dt_util"
  
  [tool.ruff.lint.isort]
  force-sort-within-sections = true
  combine-as-imports = true
  split-on-trailing-comma = false
  
  [tool.ruff.lint.per-file-ignores]
  ".github/*.py" = [
    "ANN",      # flake8-annotations
    "INP001",   # file {filename} is part of an implicit namespace package. Add an __init__.py
    ]
  "tests/**" = [
    "ANN001",   # missing type annotation for function argument {name}
    "ANN201",   # missing return type annotation for public function
    "ANN202",   # missing type annotation for *{name}
    "ANN204",   # missing return type annotation for special method {name}
    "ANN401",   # dynamically typed expressions (typing.Any) are disallowed in {name}
    "ARG001",   # unused function argument
    "D101",     # missing docstring in public class
    "D107",     # missing docstring in `__init__`
    "DOC",      # pydoclint
    "FBT001",   # boolean-typed positional argument in function definition
    "PLR0914",  # too many local variables
    "PLR0917",  # too many positional arguments
    "S108",     # hardcoded_tmp_directory
    "S306",     # mktemp_q
    "S307",     # eval
    "S313",     # xml_bad_cElementTree
    "S314",     # xml_bad_ElementTree
    "S315",     # xml_bad_expatreader
    "S316",     # xml_bad_expatbuilder
    "S317",     # xml_bad_sax
    "S318",     # xml_bad_minidom
    "S319",     # xml_bad_pulldom
    "S320",     # xml_bad_etree
    "S602",     # subprocess_popen_with_shell_equals_true
    "S604",     # any_other_function_with_shell_equals_true
    "SLF001",   # private member accessed: `_schedule_updates_stalled_event_post_update`
    "TRY003",   # avoid specifying long messages outside the exception class
    ]
  
  [tool.mypy]
  python_version = "3.13"
  follow_imports = "normal"
  local_partial_types = true
  strict_equality = true
  no_implicit_optional = true
  warn_incomplete_stub = true
  warn_redundant_casts = true
  warn_unused_configs = true
  warn_unused_ignores = true
  enable_error_code = ["ignore-without-code", "redundant-self", "truthy-iterable"]
  disable_error_code = ["annotation-unchecked", "import-not-found", "import-untyped"]
  extra_checks = false
  check_untyped_defs = true
  warn_return_any = true
  warn_unreachable = true
  explicit_package_bases = true
  