core/.github/copilot-instructions.md

101 lines
4.1 KiB
Markdown

# Instructions for GitHub Copilot
This repository holds the core of Home Assistant, a Python 3 based home
automation application.
- Python code must be compatible with Python 3.13
- Use the newest Python language features if possible:
- Pattern matching
- Type hints
- f-strings for string formatting over `%` or `.format()`
- Dataclasses
- Walrus operator
- Code quality tools:
- Formatting: Ruff
- Linting: PyLint and Ruff
- Type checking: MyPy
- Testing: pytest with plain functions and fixtures
- Inline code documentation:
- File headers should be short and concise:
```python
"""Integration for Peblar EV chargers."""
```
- Every method and function needs a docstring:
```python
async def async_setup_entry(hass: HomeAssistant, entry: PeblarConfigEntry) -> bool:
"""Set up Peblar from a config entry."""
...
```
- All code and comments and other text are written in American English
- Follow existing code style patterns as much as possible
- Core locations:
- Shared constants: `homeassistant/const.py`, use them instead of hardcoding
strings or creating duplicate integration constants.
- Integration files:
- Constants: `homeassistant/components/{domain}/const.py`
- Models: `homeassistant/components/{domain}/models.py`
- Coordinator: `homeassistant/components/{domain}/coordinator.py`
- Config flow: `homeassistant/components/{domain}/config_flow.py`
- Platform code: `homeassistant/components/{domain}/{platform}.py`
- All external I/O operations must be async
- Async patterns:
- Avoid sleeping in loops
- Avoid awaiting in loops, gather instead
- No blocking calls
- Polling:
- Follow update coordinator pattern, when possible
- Polling interval may not be configurable by the user
- For local network polling, the minimum interval is 5 seconds
- For cloud polling, the minimum interval is 60 seconds
- Error handling:
- Use specific exceptions from `homeassistant.exceptions`
- Setup failures:
- Temporary: Raise `ConfigEntryNotReady`
- Permanent: Use `ConfigEntryError`
- Logging:
- Message format:
- No periods at end
- No integration names or domains (added automatically)
- No sensitive data (keys, tokens, passwords), even when those are incorrect.
- Be very restrictive on the use of logging info messages, use debug for
anything which is not targeting the user.
- Use lazy logging (no f-strings):
```python
_LOGGER.debug("This is a log message with %s", variable)
```
- Entities:
- Ensure unique IDs for state persistence:
- Unique IDs should not contain values that are subject to user or network change.
- An ID needs to be unique per platform, not per integration.
- The ID does not have to contain the integration domain or platform.
- Acceptable examples:
- Serial number of a device
- MAC address of a device formatted using `homeassistant.helpers.device_registry.format_mac`
Do not obtain the MAC address through arp cache of local network access,
only use the MAC address provided by discovery or the device itself.
- Unique identifier that is physically printed on the device or burned into an EEPROM
- Not acceptable examples:
- IP Address
- Device name
- Hostname
- URL
- Email address
- Username
- For entities that are setup by a config entry, the config entry ID
can be used as a last resort if no other Unique ID is available.
For example: `f"{entry.entry_id}-battery"`
- If the state value is unknown, use `None`
- Do not use the `unavailable` string as a state value,
implement the `available()` property method instead
- Do not use the `unknown` string as a state value, use `None` instead
- Extra entity state attributes:
- The keys of all state attributes should always be present
- If the value is unknown, use `None`
- Provide descriptive state attributes
- Testing:
- Test location: `tests/components/{domain}/`
- Use pytest fixtures from `tests.common`
- Mock external dependencies
- Use snapshots for complex data
- Follow existing test patterns