This repository contains the core of Home Assistant, a Python 3 based home automation application.
- Do NOT amend, squash, or rebase commits that have already been pushed to the PR branch after the PR is opened - Reviewers need to follow the commit history, as well as see what changed since their last review
- When opening a pull request, use the repository's PR template (
.github/PULL_REQUEST_TEMPLATE.md). NEVER REMOVE ANYTHING from the template. - Do not remove checkboxes that are not checked — leave all unchecked checkboxes in place so reviewers can see which options were not selected.
- When entering a new environment or worktree, run
script/setupto set up the virtual environment with all development dependencies (pylint, pre-commit hooks, etc.). This is required before committing. - .vscode/tasks.json contains useful commands used for development.
- Home Assistant officially supports Python 3.14 as its minimum version. Do not flag syntax or features that require Python 3.14 as issues, and do not suggest workarounds for older Python versions.
- Python 3.14 explicitly allows
except TypeA, TypeB:without parentheses. Never flag this as an issue. - Python 3.14 evaluates annotations lazily (PEP 649). Forward references in annotations do not need to be quoted — annotations can reference names defined later in the module without quoting them or using
from __future__ import annotations. Do not flag unquoted forward references in annotations as issues.
- Use
uv run pytestto run tests - After modifying
strings.jsonfor an integration, regenerate the English translation file before running tests:.venv/bin/python3 -m script.translations develop --integration <integration_name>. Tests load translations from the generatedtranslations/en.json, not directly fromstrings.json. - When writing or modifying tests, ensure all test function parameters have type annotations.
- Prefer concrete types (for example,
HomeAssistant,MockConfigEntry, etc.) overAny. - Prefer
@pytest.mark.usefixturesover arguments, if the argument is not going to be used. - Avoid using conditions/branching in tests. Instead, either split tests or adjust the test parametrization to cover all cases without branching.
- If multiple tests share most of their code, use
pytest.mark.parametrizeto merge them into a single parameterized test instead of duplicating the body. Usepytest.paramwith anidparameter to name the test cases clearly. - We use Syrupy for snapshot testing. Leverage
.ambrsnapshots instead of repetitive and exhaustive generation of test data within Python code itself.
- Integrations with Platinum or Gold level in the Integration Quality Scale reflect a high standard of code quality and maintainability. When looking for examples of something, these are good places to start. The level is indicated in the manifest.json of the integration.
- When reviewing entity actions, do not suggest extra defensive checks for input fields that are already validated by Home Assistant's service/action schemas and entity selection filters. Suggest additional guards only when data bypasses those validators or is transformed into a less-safe form.
- When validation guarantees a dict key exists, prefer direct key access (
data["key"]) instead of.get("key")so contract violations are surfaced instead of silently masked. - Do not add comments that just restate the code on the following line(s) (e.g.
# Check if initializedaboveif self.initialized:). Comments should only explain why — non-obvious constraints, surprising behavior, or workarounds — never what.