Add pylint checker to check for using registries as fixture (#172455)

Co-authored-by: Markus Tuominen <3738613+Markus98@users.noreply.github.com>
This commit is contained in:
Joost Lekkerkerker
2026-07-22 09:56:23 +03:00
committed by GitHub
co-authored by Markus Tuominen
parent 149fca4900
commit 8e7deee967
86 changed files with 692 additions and 136 deletions
+29
View File
@@ -104,6 +104,7 @@ Every check has a code following the
| `R7401` | [`home-assistant-consider-usefixtures-decorator`](#r7401-home-assistant-consider-usefixtures-decorator) | Use `@pytest.mark.usefixtures` for unused fixtures |
| `R7402` | [`home-assistant-unused-test-fixture-argument`](#r7402-home-assistant-unused-test-fixture-argument) | Unused test function argument should use `@pytest.mark.usefixtures` |
| `R7403` | [`home-assistant-tests-redundant-usefixtures`](#r7403-home-assistant-tests-redundant-usefixtures) | `@pytest.mark.usefixtures` redundant when `pytestmark` already applies it |
| `R7404` | [`home-assistant-tests-registry-fixtures`](#r7404-home-assistant-tests-registry-fixtures) | Use the registry fixture instead of calling `<registry>.async_get(hass)` directly in tests |
| `W7401` | [`home-assistant-deprecated-import`](#w7401-home-assistant-deprecated-import) | Import uses a deprecated path |
| `W7402` | [`home-assistant-async-callback-decorator`](#w7402-home-assistant-async-callback-decorator) | Coroutine should not be decorated with `@callback` |
| `W7403` | [`home-assistant-pytest-fixture-decorator`](#w7403-home-assistant-pytest-fixture-decorator) | Pytest fixture has invalid scope or autouse config |
@@ -744,6 +745,34 @@ Drop the redundant `@pytest.mark.usefixtures` decorator; the fixture is
already applied to every test in the module.
## `home_assistant_tests_registry_fixtures` checker
Detects test functions and pytest fixtures that call a registry helper's
`async_get(hass)` directly instead of using the registry fixtures defined
in `tests/conftest.py` (`area_registry`, `category_registry`,
`device_registry`, `entity_registry`, `floor_registry`, `issue_registry`,
`label_registry`).
### `R7404`: `home-assistant-tests-registry-fixtures`
A `test_*` function or `@pytest.fixture`-decorated function calls
`<registry>.async_get(hass)` directly (e.g. `er.async_get(hass)`) where
`<registry>` resolves via a module-level
`from homeassistant.helpers import ...` statement to one of the seven
registry helper modules. Request the corresponding registry fixture as a
test/fixture argument instead:
```python
async def test_entities(hass: HomeAssistant, entity_registry: er.EntityRegistry) -> None:
entry = entity_registry.async_get(entity_id)
```
Only aliases imported from `homeassistant.helpers` are tracked. The
checker is scoped to test modules; `conftest.py` files (where the
fixtures themselves are defined) and `tests.helpers` (which exercises the
registry helpers directly) are exempt.
## `home_assistant_test_determinism` checker
`if` and `match` statements inside test functions create non-deterministic
@@ -0,0 +1,186 @@
"""Checker for direct registry ``async_get`` calls in tests.
Test functions and pytest fixtures should use the standard registry
fixtures defined in ``tests/conftest.py``
(``area_registry``, ``category_registry``, ``device_registry``,
``entity_registry``, ``floor_registry``, ``issue_registry``,
``label_registry``) instead of calling ``<registry>.async_get(hass)``
directly.
This checker flags calls of the form ``<alias>.async_get(...)`` where
``<alias>`` resolves (via a module-level ``from homeassistant.helpers
import ...`` statement) to one of the seven registry helper modules,
when the call is located inside a ``test_*`` function or a
``@pytest.fixture``-decorated function.
Files literally named ``conftest.py`` are exempt — these are where the
registry fixtures themselves are typically defined.
"""
from pathlib import Path
from astroid import nodes
from pylint.checkers import BaseChecker
from pylint.lint import PyLinter
from pylint_home_assistant.helpers.module_info import is_test_module
_REGISTRY_HELPERS: frozenset[str] = frozenset(
{
"area_registry",
"category_registry",
"device_registry",
"entity_registry",
"floor_registry",
"issue_registry",
"label_registry",
}
)
def _build_alias_map(module: nodes.Module) -> dict[str, str]:
"""Map module-level alias -> registry helper module name.
Walks top-level ``from homeassistant.helpers import ...`` statements
and records each imported registry helper, keyed by its alias (or
its own name when no alias is provided).
"""
alias_map: dict[str, str] = {}
for node in module.body:
if not isinstance(node, nodes.ImportFrom):
continue
if node.modname != "homeassistant.helpers":
continue
for name, asname in node.names:
if name not in _REGISTRY_HELPERS:
continue
alias_map[asname or name] = name
return alias_map
def _binds_to_import(name_node: nodes.Name) -> bool:
"""Return True when *name_node* resolves to a module-level import.
Uses Astroid scope lookup to find the binding for the name at the call
site. Returns True only when every binding is an ``ImportFrom`` (i.e.
the name was not shadowed by a parameter, assignment, or other local
definition such as a fixture instance).
"""
try:
_, assignments = name_node.lookup(name_node.name)
except Exception: # noqa: BLE001 - defensive: lookup can raise on odd ASTs
return False
if not assignments:
return False
return all(isinstance(assignment, nodes.ImportFrom) for assignment in assignments)
def _in_test_or_fixture(node: nodes.NodeNG) -> bool:
"""Return True when *node* executes inside a test or pytest fixture.
Walks the full ancestor chain so calls in nested helpers/callbacks
defined inside a ``test_*`` function or a ``@pytest.fixture`` function
are recognized, not just those in the nearest enclosing function.
"""
parent = node.parent
while parent is not None and not isinstance(parent, nodes.Module):
if isinstance(parent, (nodes.FunctionDef, nodes.AsyncFunctionDef)) and (
parent.name.startswith("test_") or _is_pytest_fixture(parent)
):
return True
parent = parent.parent
return False
def _is_pytest_fixture(
func: nodes.FunctionDef | nodes.AsyncFunctionDef,
) -> bool:
"""Return True when *func* is decorated with ``@pytest.fixture``."""
if not func.decorators:
return False
for decorator in func.decorators.nodes:
# ``@pytest.fixture(...)`` — a Call whose func is an Attribute
target = decorator.func if isinstance(decorator, nodes.Call) else decorator
if not isinstance(target, nodes.Attribute):
continue
if target.attrname != "fixture":
continue
expr = target.expr
if isinstance(expr, nodes.Name) and expr.name == "pytest":
return True
return False
class RegistryFixturesChecker(BaseChecker):
"""Checker that enforces use of registry fixtures in tests."""
name = "home_assistant_tests_registry_fixtures"
priority = -1
msgs = {
"R7404": (
"Use the '%s' fixture instead of calling '%s.async_get(...)' "
"directly in tests",
"home-assistant-tests-registry-fixtures",
"Used when a test function or pytest fixture calls "
"``<registry>.async_get(hass)`` directly instead of relying "
"on the corresponding registry fixture defined in "
"``tests/conftest.py``.",
),
}
options = ()
_active: bool
_alias_map: dict[str, str]
def visit_module(self, node: nodes.Module) -> None:
"""Record module state and build the alias map."""
self._active = False
self._alias_map = {}
if not is_test_module(node.name):
return
# ``tests.helpers`` tests cover the registry helpers themselves and
# are expected to call ``async_get`` directly.
if node.name == "tests.helpers" or node.name.startswith("tests.helpers."):
return
# Exempt ``conftest.py`` files entirely — registry fixtures live there.
if node.file and Path(node.file).name == "conftest.py":
return
self._active = True
self._alias_map = _build_alias_map(node)
def visit_call(self, node: nodes.Call) -> None:
"""Flag direct registry ``async_get`` calls inside tests/fixtures."""
if not self._active or not self._alias_map:
return
func = node.func
if not isinstance(func, nodes.Attribute):
return
if func.attrname != "async_get":
return
if not isinstance(func.expr, nodes.Name):
return
helper = self._alias_map.get(func.expr.name)
if helper is None:
return
# The alias map only records the module-level spelling. A parameter
# or local (e.g. the ``entity_registry`` fixture instance) can shadow
# a non-aliased import, so confirm the name still binds to the
# recorded ``from homeassistant.helpers import ...`` statement before
# flagging.
if not _binds_to_import(func.expr):
return
if _in_test_or_fixture(node):
self.add_message(
"home-assistant-tests-registry-fixtures",
node=node,
args=(helper, helper),
)
def register(linter: PyLinter) -> None:
"""Register the checker."""
linter.register_checker(RegistryFixturesChecker(linter))
+1 -1
View File
@@ -188,7 +188,7 @@ async def test_uid_migrate_entry(
mock_async_get_firmware_data: AsyncMock,
) -> None:
"""Test migrate entry unique id."""
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
MOCK_MAC = dr.format_mac("01:23:45:67:89:AB")
MOCK_ID = "device_id_12345"
+1 -1
View File
@@ -266,7 +266,7 @@ async def test_brand_migration_issue(hass: HomeAssistant) -> None:
assert config_entry.state is ConfigEntryState.LOADED
issue_reg = ir.async_get(hass)
issue_reg = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
await hass.config_entries.async_remove(config_entry.entry_id)
assert not issue_reg.async_get_issue(DOMAIN, "yale_brand_migration")
@@ -197,7 +197,7 @@ async def test_vehicle_name_update(
"""Test device name updates in device registry when vehicle is renamed."""
await setup_integration(hass, mock_config_entry)
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
device_entry = device_registry.async_get_device(identifiers={(DOMAIN, "12345")})
assert device_entry is not None
assert device_entry.name == "Test Vehicle"
@@ -42,7 +42,7 @@ async def test_unauthorized_triggers_reauth(
await async_check_for_repair_issues(hass, mock_entry)
mock_reauth.assert_called_once_with(hass)
assert len(ir.async_get(hass).issues) == 0
assert len(ir.async_get(hass).issues) == 0 # pylint: disable=home-assistant-tests-registry-fixtures
@pytest.mark.parametrize(
@@ -65,7 +65,7 @@ async def test_repair_issue_creation(
await async_check_for_repair_issues(hass, mock_entry)
mock_reauth.assert_not_called()
assert len(ir.async_get(hass).issues) == expected_issues
assert len(ir.async_get(hass).issues) == expected_issues # pylint: disable=home-assistant-tests-registry-fixtures
async def test_async_create_fix_flow(hass: HomeAssistant) -> None:
+2 -2
View File
@@ -982,7 +982,7 @@ async def test_create_backup_success_clears_issue(
await hass.async_block_till_done()
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert set(issue_registry.issues) == issues_after_create_backup
@@ -1344,7 +1344,7 @@ async def test_create_backup_failure_raises_issue(
assert result["success"] == create_backup_result
await hass.async_block_till_done()
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert set(issue_registry.issues) == set(issues_after_create_backup)
for issue_id, issue_data in issues_after_create_backup.items():
issue = issue_registry.issues[issue_id]
+7 -7
View File
@@ -1807,7 +1807,7 @@ async def test_repair_issue_created_for_degraded_scanner_in_docker(
manager.on_scanner_start(scanner)
issue_id = f"bluetooth_adapter_missing_permissions_{scanner.source}"
registry = ir.async_get(hass)
registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = registry.async_get_issue(bluetooth.DOMAIN, issue_id)
assert issue is not None
assert issue.severity == ir.IssueSeverity.WARNING
@@ -1824,7 +1824,7 @@ async def test_repair_issue_deleted_when_scanner_not_degraded(
await hass.async_block_till_done()
manager = _get_manager()
registry = ir.async_get(hass)
registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
scanner = HaScanner(
mode=BluetoothScanningMode.ACTIVE,
@@ -1900,7 +1900,7 @@ async def test_no_repair_issue_when_not_docker(
manager.on_scanner_start(scanner)
issue_id = f"bluetooth_adapter_missing_permissions_{scanner.source}"
registry = ir.async_get(hass)
registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert registry.async_get_issue(bluetooth.DOMAIN, issue_id) is None
@@ -1926,7 +1926,7 @@ async def test_no_repair_issue_for_remote_scanner(
):
manager.on_scanner_start(scanner)
registry = ir.async_get(hass)
registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issues = [
issue
for issue in registry.issues.values()
@@ -1963,7 +1963,7 @@ async def test_repair_issue_created_for_passive_mode_fallback(
# Check repair issue is created
issue_id = f"bluetooth_adapter_passive_mode_{scanner.source}"
registry = ir.async_get(hass)
registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = registry.async_get_issue(bluetooth.DOMAIN, issue_id)
assert issue is not None
assert issue.severity == ir.IssueSeverity.WARNING
@@ -2014,7 +2014,7 @@ async def test_repair_issue_created_for_passive_mode_fallback_uart(
# Check repair issue is created with UART-specific translation key
issue_id = f"bluetooth_adapter_passive_mode_{scanner.source}"
registry = ir.async_get(hass)
registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = registry.async_get_issue(bluetooth.DOMAIN, issue_id)
assert issue is not None
assert issue.severity == ir.IssueSeverity.WARNING
@@ -2051,7 +2051,7 @@ async def test_repair_issue_deleted_when_passive_mode_resolved(
# Check repair issue is created
issue_id = f"bluetooth_adapter_passive_mode_{scanner.source}"
registry = ir.async_get(hass)
registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = registry.async_get_issue(bluetooth.DOMAIN, issue_id)
assert issue is not None
@@ -92,7 +92,7 @@ async def test_setup_multiple_systems_zones(
assert state.attributes["current_temperature"] == zone
# Check that the created devices are wired to each other as expected.
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
def find_device(name):
return next(filter(lambda x: x.name == name, device_registry.devices.values()))
+1 -1
View File
@@ -24,7 +24,7 @@ async def test_async_setup_and_unload_entry(
assert mock_config_entry.state is ConfigEntryState.LOADED
assert mock_config_entry.runtime_data is not None
entity_reg = er.async_get(hass)
entity_reg = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entities = [
e
for e in entity_reg.entities.values()
+1 -1
View File
@@ -178,7 +178,7 @@ async def test_set_temperature(
# Put areas on different floors:
# first floor => living room and office
# upstairs => bedroom
floor_registry = fr.async_get(hass)
floor_registry = fr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
first_floor = floor_registry.async_create("First floor")
living_room_area = area_registry.async_update(
living_room_area.id, floor_id=first_floor.floor_id
+1 -1
View File
@@ -36,7 +36,7 @@ async def test_registry_cleanup(
) -> None:
"""Test being able to remove a disconnected device."""
entry_id = load_int.entry_id
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
live_id = "L1.100"
dead_id = "L2.200"
@@ -1814,8 +1814,8 @@ async def test_device_automation_resolves_legacy_id(
await dr.async_load(hass)
await er.async_load(hass)
await ar.async_load(hass)
device_registry = dr.async_get(hass)
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
by_entry = {
d.config_entry_id: d.id
for d in device_registry.async_get_devices_for_composite_device_id(COMPOSITE_ID)
+1 -1
View File
@@ -24,7 +24,7 @@ async def test_change_schedule_fails(
favorites_side_effect=mock_not_found_exception()
)
assert doorbird_entry.entry.state is ConfigEntryState.SETUP_RETRY
issue_reg = ir.async_get(hass)
issue_reg = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert len(issue_reg.issues) == 1
issue = list(issue_reg.issues.values())[0]
issue_id = issue.issue_id
+3 -3
View File
@@ -463,7 +463,7 @@ async def test_remote_sensor_devices(
freezer.tick(100)
async_fire_time_changed(hass)
state = hass.states.get(ENTITY_ID)
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
for device in device_registry.devices.values():
if device.name == "Remote Sensor 1":
remote_sensor_1_id = device.id
@@ -551,7 +551,7 @@ async def test_remote_sensors_ignore_non_ecobee_devices(hass: HomeAssistant) ->
an ecobee sensor's name was wrongly reported as a participating sensor.
"""
await setup_platform(hass, [const.Platform.CLIMATE, const.Platform.SENSOR])
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
# A device from another integration that shares the ecobee sensor's name.
other_entry = MockConfigEntry(domain="other")
@@ -581,7 +581,7 @@ async def test_set_sensors_used_in_climate(hass: HomeAssistant) -> None:
"""Test set sensors used in climate."""
# Get device_id of remote sensor from the device registry.
await setup_platform(hass, [const.Platform.CLIMATE, const.Platform.SENSOR])
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
for device in device_registry.devices.values():
if device.name == "Remote Sensor 1":
remote_sensor_1_id = device.id
+1 -1
View File
@@ -390,7 +390,7 @@ async def test_raise_segment_changed_issue(
entity_entry = entity_registry.async_get(entity_id)
issue_id = f"{vacuum.ISSUE_SEGMENTS_CHANGED}_{entity_entry.id}"
issue = ir.async_get(hass).async_get_issue(vacuum.DOMAIN, issue_id)
issue = ir.async_get(hass).async_get_issue(vacuum.DOMAIN, issue_id) # pylint: disable=home-assistant-tests-registry-fixtures
assert issue is not None
+1 -1
View File
@@ -707,7 +707,7 @@ async def test_entity_assignment_to_sub_device(
mock_esphome_device: MockESPHomeDeviceType,
) -> None:
"""Test entities are assigned to correct sub devices."""
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
# Define sub devices
sub_devices = [
+5 -5
View File
@@ -1920,7 +1920,7 @@ async def test_device_adds_friendly_name(
device_info={"name": "nofriendlyname", "friendly_name": ""},
)
await hass.async_block_till_done()
dev_reg = dr.async_get(hass)
dev_reg = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
dev = dev_reg.async_get_device(
connections={(dr.CONNECTION_NETWORK_MAC, device.entry.unique_id)}
)
@@ -2006,7 +2006,7 @@ async def test_sub_device_creation(
mock_esphome_device: MockESPHomeDeviceType,
) -> None:
"""Test sub devices are created in device registry."""
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
# Define areas
areas = [
@@ -2076,7 +2076,7 @@ async def test_sub_device_cleanup(
mock_esphome_device: MockESPHomeDeviceType,
) -> None:
"""Test sub devices are removed when they no longer exist."""
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
# Initial sub devices
sub_devices_initial = [
@@ -2167,7 +2167,7 @@ async def test_sub_device_with_empty_name(
mock_esphome_device: MockESPHomeDeviceType,
) -> None:
"""Test sub devices with empty names are handled correctly."""
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
# Define sub devices with empty names
sub_devices = [
@@ -2211,7 +2211,7 @@ async def test_sub_device_references_main_device_area(
mock_esphome_device: MockESPHomeDeviceType,
) -> None:
"""Test sub devices can reference the main device's area."""
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
# Define areas - note we don't include area_id=0 in the areas list
areas = [
+1 -1
View File
@@ -115,7 +115,7 @@ async def test_last_alarm_pic_sensor_not_created(
assert last_alarm_pic_state is None
# But other sensors should be created
registry = er.async_get(hass)
registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
battery_entity = registry.async_get("sensor.camera_1_battery")
assert battery_entity is not None
+2 -2
View File
@@ -283,7 +283,7 @@ async def test_cleanup_button_deprecation_issue(
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.LOADED
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert issue_registry.async_get_issue(DOMAIN, "deprecated_cleanup_button")
@@ -303,5 +303,5 @@ async def test_firmware_update_button_deprecation_issue(
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.LOADED
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert issue_registry.async_get_issue(DOMAIN, "deprecated_firmware_update_button")
@@ -29,7 +29,7 @@ async def test_get_forecast_service(
snapshot: SnapshotAssertion,
) -> None:
"""Test fetching a forecast for a subentry."""
device = dr.async_get(hass).async_get_device(
device = dr.async_get(hass).async_get_device( # pylint: disable=home-assistant-tests-registry-fixtures
identifiers={(DOMAIN, f"{mock_config_entry.entry_id}_home-subentry-id")}
)
assert device is not None
+1 -1
View File
@@ -869,7 +869,7 @@ async def test_dynamic_device_added(
# Verify multiple entity types to confirm end-to-end dynamic device support
assert hass.states.get("switch.new456789_charge_from_grid") is not None
# Additional check: verify entities exist in the entity registry
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
new_device_entry = device_registry.async_get_device(
identifiers={(DOMAIN, "NEW456789")}
)
+1 -1
View File
@@ -72,7 +72,7 @@ async def test_unique_id_migration(
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
ent_reg = er.async_get(hass)
ent_reg = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
switch_tv = ent_reg.async_get(ENTITY_WATCH_TV)
assert switch_tv.unique_id == f"activity_{WATCH_TV_ACTIVITY_ID}"
+1 -1
View File
@@ -1146,7 +1146,7 @@ async def test_reader_writer_create_addon_folder_error(
),
]
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert not issue_registry.issues
await client.send_json_auto_id({"type": "backup/subscribe_events"})
+1 -1
View File
@@ -875,7 +875,7 @@ async def test_partial_backup_legacy_homeassistant_folder(
folders={Folder.SSL},
)
)
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert (
issue_registry.async_get_issue("hassio", "legacy_homeassistant_folder")
is not None
+1 -1
View File
@@ -71,7 +71,7 @@ async def test_device_diagnostics(
"""Test generating diagnostics for a config entry."""
config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
device = device_registry.async_get_device({(DOMAIN, "1")})
assert device is not None
diagnostics = await get_diagnostics_for_device(
@@ -204,7 +204,7 @@ async def test_switch_restore_state(
]
# Verify entity registry attributes
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entity_entry = entity_registry.async_get(TEST_SWITCH_ENTITY_ID)
assert entity_entry is not None
assert entity_entry.entity_category == EntityCategory.CONFIG
@@ -261,7 +261,7 @@ async def test_ble_device_populates_connections(
await hass.async_block_till_done()
assert config_entry.state is ConfigEntryState.LOADED
dev_reg = dr.async_get(hass)
dev_reg = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert (
dev_reg.async_get_device(
identifiers={}, connections={("bluetooth", "AA:BB:CC:DD:EE:FF")}
@@ -930,7 +930,7 @@ async def test_hmip_smoke_detector_dirt_level(
device_model = "HmIP-SWSD"
# Pre-register the entity as enabled before platform loads
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entity_registry.async_get_or_create(
"sensor",
DOMAIN,
+5 -5
View File
@@ -142,7 +142,7 @@ async def test_load_creates_repair_issue(
await hass.async_block_till_done()
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = issue_registry.async_get_issue(
domain=DOMAIN, issue_id=f"migrate_to_v2_api_{mock_config_entry.entry_id}"
@@ -168,7 +168,7 @@ async def test_load_creates_repair_issue_when_name_is_updated(
await hass.async_block_till_done()
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue_id = f"migrate_to_v2_api_{mock_config_entry.entry_id}"
issue = issue_registry.async_get_issue(domain=DOMAIN, issue_id=issue_id)
@@ -178,7 +178,7 @@ async def test_load_creates_repair_issue_when_name_is_updated(
assert issue.translation_placeholders["title"] == "Device"
# Update the device name
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
device = get_main_device(hass, mock_config_entry)
# Update device name
@@ -318,9 +318,9 @@ async def test_battery_cloud_issue_stale_issue_cleared_on_reload(
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert ir.async_get(hass).async_get_issue(DOMAIN, issue_id) is not None
assert ir.async_get(hass).async_get_issue(DOMAIN, issue_id) is not None # pylint: disable=home-assistant-tests-registry-fixtures
combined_data.system.cloud_enabled = True
await hass.config_entries.async_reload(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert ir.async_get(hass).async_get_issue(DOMAIN, issue_id) is None
assert ir.async_get(hass).async_get_issue(DOMAIN, issue_id) is None # pylint: disable=home-assistant-tests-registry-fixtures
+1 -1
View File
@@ -46,7 +46,7 @@ async def test_device_manufacturer_uses_oem(
with patch("homeassistant.components.hypontech._PLATFORMS", [Platform.SENSOR]):
await setup_integration(hass, mock_config_entry)
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
overview_device = device_registry.async_get_device(
identifiers={(DOMAIN, mock_config_entry.unique_id)}
)
+1 -1
View File
@@ -58,7 +58,7 @@ async def test_setup_ignores_unknown_button_types(
mock_config_entry: MockConfigEntry,
) -> None:
"""Unknown button keys from the API are not turned into entities."""
registry = er.async_get(hass)
registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entries = er.async_entries_for_config_entry(registry, mock_config_entry.entry_id)
assert len(entries) == 1
assert entries[0].translation_key == PARAM_MUTE
+1 -1
View File
@@ -96,7 +96,7 @@ async def test_no_camera_without_channel(
mock_config_entry: MockConfigEntry,
) -> None:
"""Devices without a channel do not get a camera entity."""
registry = er.async_get(hass)
registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entries = er.async_entries_for_config_entry(registry, mock_config_entry.entry_id)
assert not any(entry.domain == "camera" for entry in entries)
+1 -1
View File
@@ -66,7 +66,7 @@ async def test_device_registry_identifiers(
mock_config_entry: MockConfigEntry,
) -> None:
"""Device registry uses channel-aware identifiers from the default mock devices."""
registry = dr.async_get(hass)
registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
devices = dr.async_entries_for_config_entry(registry, mock_config_entry.entry_id)
assert len(devices) == 1
assert (DOMAIN, "d1") in devices[0].identifiers
+1 -1
View File
@@ -85,7 +85,7 @@ async def test_setup_ignores_unknown_switch_types(
mock_config_entry: MockConfigEntry,
) -> None:
"""Unknown switch keys from the API are not turned into entities."""
registry = er.async_get(hass)
registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entries = er.async_entries_for_config_entry(registry, mock_config_entry.entry_id)
switch_entries = [entry for entry in entries if entry.domain == SWITCH_DOMAIN]
assert len(switch_entries) == 1
+2 -2
View File
@@ -151,8 +151,8 @@ async def test_setup_and_remove_config_entry(
async def test_entry_changed(hass: HomeAssistant, platform) -> None:
"""Test reconfiguring."""
device_registry = dr.async_get(hass)
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
def _create_mock_entity(domain: str, name: str) -> er.RegistryEntry:
config_entry = MockConfigEntry(
+1 -1
View File
@@ -183,7 +183,7 @@ async def test_get_temperature(
# first floor => living room and office
# 2nd floor => bedroom
# 3rd floor => attic
floor_registry = fr.async_get(hass)
floor_registry = fr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
first_floor = floor_registry.async_create("First floor")
living_room_area = area_registry.async_update(
living_room_area.id, floor_id=first_floor.floor_id
+2 -2
View File
@@ -59,13 +59,13 @@ async def test_sensor_device_info(
hass: HomeAssistant, init_integration: MockConfigEntry
) -> None:
"""Test sensor has correct device info."""
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entity = entity_registry.async_get("sensor.iss")
assert entity is not None
assert entity.unique_id == f"{init_integration.entry_id}_people"
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
device = device_registry.async_get(entity.device_id)
assert device is not None
+2 -2
View File
@@ -50,7 +50,7 @@ async def test_data_secure_group_key_issue_only_for_configured_group_address(
}
)
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert bool(issue_registry.issues) is False
# An issue should only be created if this address is configured.
knx.receive_data_secure_issue("1/2/5")
@@ -76,7 +76,7 @@ async def test_data_secure_group_key_issue_repair_flow(
knx.receive_data_secure_issue("11/0/0", source="1.0.1")
knx.receive_data_secure_issue("1/2/5", source="1.0.10")
knx.receive_data_secure_issue("1/2/5", source="1.0.1")
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = issue_registry.async_get_issue(DOMAIN, REPAIR_ISSUE_DATA_SECURE_GROUP_KEY)
assert issue is not None
assert issue.translation_placeholders == {
+3 -3
View File
@@ -155,7 +155,7 @@ async def test_store_telegram_history_error_handling(
assert telegrams_module.store is None
# Check that the repair issue was created
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = issue_registry.async_get_issue(DOMAIN, REPAIR_ISSUE_TELEGRAM_BACKEND_ERROR)
assert issue is not None
@@ -183,7 +183,7 @@ async def test_store_telegram_history_needs_migration_timeout(
assert telegrams_module.store is None
# Check that the repair issue was created
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = issue_registry.async_get_issue(DOMAIN, REPAIR_ISSUE_TELEGRAM_BACKEND_ERROR)
assert issue is not None
@@ -546,7 +546,7 @@ async def test_postgres_backend_init_error(
telegrams_module = hass.data[KNX_MODULE_KEY].telegrams
assert telegrams_module.store is None
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert (
issue_registry.async_get_issue(DOMAIN, REPAIR_ISSUE_TELEGRAM_BACKEND_ERROR)
is not None
+1 -1
View File
@@ -22,7 +22,7 @@ async def test_migrate_entry(
mock_config_entry_v1.add_to_hass(hass)
dev_reg = dr.async_get(hass)
dev_reg = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
# Create device registry entries for old integration
dev_reg.async_get_or_create(
config_entry_id=mock_config_entry_v1.entry_id,
+1 -1
View File
@@ -232,7 +232,7 @@ async def test_gateway_version_issue(
await async_init_integration(hass, mock_config_entry)
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = issue_registry.async_get_issue(DOMAIN, "unsupported_gateway_firmware")
assert (issue is not None) == issue_exists
+3 -3
View File
@@ -187,7 +187,7 @@ async def test_filter_sensor(
) -> None:
"""Test numeric sensors are filtered."""
registry = er.async_get(hass_)
registry = er.async_get(hass_) # pylint: disable=home-assistant-tests-registry-fixtures
# Unregistered sensor without a unit of measurement - should be in logbook
entity_id1 = "sensor.bla"
@@ -3225,7 +3225,7 @@ async def test_context_user_ids_lru_eviction(
for_live_stream=True,
)
context_augmenter = logbook.processor.ContextAugmenter(logbook_run)
ent_reg = er.async_get(hass)
ent_reg = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
processor = logbook.processor.EventProcessor.__new__(
logbook.processor.EventProcessor
@@ -3353,7 +3353,7 @@ async def test_parent_user_attribution_does_not_use_origin_event_fallback(
memoize_new_contexts=False,
)
context_augmenter = logbook.processor.ContextAugmenter(logbook_run)
ent_reg = er.async_get(hass)
ent_reg = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
processor = logbook.processor.EventProcessor.__new__(
logbook.processor.EventProcessor
+1 -1
View File
@@ -372,7 +372,7 @@ async def test_lovelace_from_yaml_creates_repair_issue(
assert hass.data[frontend.DATA_PANELS]["lovelace"].config == {"mode": "yaml"}
# Repair issue should be created
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = issue_registry.async_get_issue("lovelace", "yaml_mode_deprecated")
assert issue is not None
assert issue.severity == ir.IssueSeverity.WARNING
+3 -3
View File
@@ -29,7 +29,7 @@ async def test_setup_entry(
# Verify that the unique ID is generated correctly.
# This prevents regression in unique ID generation which would be a breaking change.
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
# The light from mock_lutron has uuid="light_uuid" and guid="12345678901"
expected_unique_id = "12345678901_light_uuid"
entry = entity_registry.async_get("light.test_area_test_light")
@@ -81,8 +81,8 @@ async def test_unique_id_migration(
# Setup registries with an entry using the "legacy" unique ID format.
# This simulates a user who had configured the integration in an older version.
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
legacy_unique_id = "12345678901_light_legacy_uuid"
new_unique_id = "12345678901_light_uuid"
+2 -2
View File
@@ -506,7 +506,7 @@ async def test_vacuum_no_issue_on_transient_empty_segments(
set_node_attribute(matter_node, 1, 336, 0, [])
await trigger_subscription_callback(hass, matter_client)
issue_reg = ir.async_get(hass)
issue_reg = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = issue_reg.async_get_issue(
VACUUM_DOMAIN, f"segments_changed_{entity_entry.id}"
)
@@ -542,7 +542,7 @@ async def test_vacuum_raise_segments_changed_issue(
set_node_attribute(matter_node, 1, 97, 4, 0x02)
await trigger_subscription_callback(hass, matter_client)
issue_reg = ir.async_get(hass)
issue_reg = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = issue_reg.async_get_issue(
VACUUM_DOMAIN, f"segments_changed_{entity_entry.id}"
)
+1 -1
View File
@@ -2593,7 +2593,7 @@ async def test_mqtt_protocol_failed_migration_to_v5(
assert len(events) == 1
assert events[0].data["issue_id"] == "protocol_5_migration"
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert len(issue_registry.issues) == 1
issue = issue_registry.async_get_issue(DOMAIN, "protocol_5_migration")
assert issue is not None
+1 -1
View File
@@ -140,7 +140,7 @@ async def test_subentry_reconfigure_export_settings(
# The subentry ID is used as device identifier
assert len(events) == 1
issue_id = events[0].data["issue_id"]
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
repair_issue = issue_registry.async_get_issue(DOMAIN, issue_id)
assert repair_issue.translation_key == translation_key
+2 -2
View File
@@ -355,7 +355,7 @@ async def test_clean_segments_initial_setup_without_repair_issue(
state.attributes.get(ATTR_SUPPORTED_FEATURES)
& vacuum.VacuumEntityFeature.CLEAN_AREA
)
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert len(issue_registry.issues) == 0
@@ -405,7 +405,7 @@ async def test_clean_segments_command(
& vacuum.VacuumEntityFeature.CLEAN_AREA
)
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
# We do not expect a repair flow as the segments did not change
assert len(issue_registry.issues) == 0
@@ -179,7 +179,7 @@ async def test_authentication_required_triggers_reauth(
assert config_entry.state is ConfigEntryState.SETUP_ERROR
issue_reg = ir.async_get(hass)
issue_reg = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue_id = f"config_entry_reauth_{DOMAIN}_{config_entry.entry_id}"
assert issue_reg.async_get_issue("homeassistant", issue_id)
@@ -208,6 +208,6 @@ async def test_authentication_required_addon_no_reauth(
assert config_entry.state is ConfigEntryState.SETUP_ERROR
issue_reg = ir.async_get(hass)
issue_reg = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue_id = f"config_entry_reauth_{DOMAIN}_{config_entry.entry_id}"
assert issue_reg.async_get_issue("homeassistant", issue_id) is None
@@ -63,7 +63,8 @@ async def test_updating(
# Resolve the created scene entity dynamically
entity_entries = er.async_entries_for_config_entry(
er.async_get(hass), mock_config_entry.entry_id
er.async_get(hass), # pylint: disable=home-assistant-tests-registry-fixtures
mock_config_entry.entry_id,
)
scene_entities = [e for e in entity_entries if e.domain == SCENE_DOMAIN]
assert scene_entities, "No scene entities registered"
+2 -2
View File
@@ -104,7 +104,7 @@ async def test_remove_device_valid(
list_commands_return_value=[],
)
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert device_registry is not None
device_entry = device_registry.async_get_device(
@@ -137,7 +137,7 @@ async def test_remove_device_stale(
list_commands_return_value=[],
)
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert device_registry is not None
device_entry = device_registry.async_get_or_create(
+1 -1
View File
@@ -221,7 +221,7 @@ async def test_data_cap_issues(
await setup_integration(hass, mock_config_entry)
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = issue_registry.async_get_issue(DOMAIN, issue_key)
assert (issue is not None) == issue_exists
+1 -1
View File
@@ -33,7 +33,7 @@ async def test_migrate_camera_entities_unique_ids(hass: HomeAssistant) -> None:
config_entry = MockConfigEntry(domain=DOMAIN, unique_id=MAC)
config_entry.add_to_hass(hass)
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entity_with_only_mac = entity_registry.async_get_or_create(
domain="camera",
+2 -2
View File
@@ -48,7 +48,7 @@ async def test_remove_config_entry_device_server(
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
server_device = device_registry.async_get_device(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
)
@@ -74,7 +74,7 @@ async def test_remove_config_entry_device_still_connected(
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
# Get a device that's in coordinator.data (still connected)
devices = dr.async_entries_for_config_entry(
+2 -2
View File
@@ -238,7 +238,7 @@ async def test_coordinator_migration(
assert stats == snapshot
# Check that an issue was created
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = issue_registry.async_get_issue(DOMAIN, "return_to_grid_migration_111111")
assert issue is not None
assert issue.severity == ir.IssueSeverity.WARNING
@@ -412,7 +412,7 @@ async def test_coordinator_migration_empty_source_stats(
# no individual stats were found
assert migrated is False
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = issue_registry.async_get_issue(DOMAIN, "return_to_grid_migration_111111")
assert issue is None
+1 -1
View File
@@ -39,7 +39,7 @@ async def test_sensors(
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
# Check electric sensors
entry = entity_registry.async_get(
+1 -1
View File
@@ -92,7 +92,7 @@ async def test_unique_id_migration(hass: HomeAssistant) -> None:
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
ent_reg = er.async_get(hass)
ent_reg = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
unique_id_map = {
ENTITY_SENSOR_DISCRETE_RSSI_LEVEL: "io://1234-5678-1234/3541212-core:DiscreteRSSILevelState",
+1 -1
View File
@@ -585,7 +585,7 @@ class TestPicnicSensor(unittest.IsolatedAsyncioTestCase):
# Setup platform and default mock responses
await self._setup_platform(use_default_responses=True)
device_registry = dr.async_get(self.hass)
device_registry = dr.async_get(self.hass) # pylint: disable=home-assistant-tests-registry-fixtures
picnic_service = device_registry.async_get_device(
identifiers={(const.DOMAIN, DEFAULT_USER_RESPONSE["user_id"])}
)
+2 -2
View File
@@ -143,8 +143,8 @@ async def test_migration_v1_to_v3(
entry.add_to_hass(hass)
assert entry.version == 1
device_registry = dr.async_get(hass)
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
vm_device = device_registry.async_get_or_create(
config_entry_id=entry.entry_id,
+4 -4
View File
@@ -452,7 +452,7 @@ async def test_cloud_api_repair(
await hass.config_entries.async_setup(mock_roborock_entry.entry_id)
await hass.async_block_till_done()
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert len(issue_registry.issues) == 1
# Check that both expected device names are present, regardless of order
assert all(
@@ -495,7 +495,7 @@ async def test_cloud_api_repair_cleared_on_update(
await hass.async_block_till_done()
assert mock_roborock_entry.state is ConfigEntryState.LOADED
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert len(issue_registry.issues) == 1
# Fake that the device is reachable locally again.
@@ -513,7 +513,7 @@ async def test_cloud_api_repair_cleared_on_update(
await hass.async_block_till_done()
# Verify that the repair issue is cleared
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert len(issue_registry.issues) == 0
# Fake the device is cloud only again. Refreshing the coordinator
@@ -529,7 +529,7 @@ async def test_cloud_api_repair_cleared_on_update(
await hass.async_block_till_done()
# Verify that the repair issue still does not exist
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert len(issue_registry.issues) == 0
+2 -2
View File
@@ -588,7 +588,7 @@ async def test_segments_changed_issue(
await hass.async_block_till_done()
issue_id = f"segments_changed_{entity_entry.id}"
issue = ir.async_get(hass).async_get_issue(VACUUM_DOMAIN, issue_id)
issue = ir.async_get(hass).async_get_issue(VACUUM_DOMAIN, issue_id) # pylint: disable=home-assistant-tests-registry-fixtures
assert issue is not None
assert issue.severity == ir.IssueSeverity.WARNING
assert issue.translation_key == "segments_changed"
@@ -621,7 +621,7 @@ async def test_segments_changed_issue_no_map_info(
await hass.async_block_till_done()
issue_id = f"segments_changed_{entity_entry.id}"
issue = ir.async_get(hass).async_get_issue(VACUUM_DOMAIN, issue_id)
issue = ir.async_get(hass).async_get_issue(VACUUM_DOMAIN, issue_id) # pylint: disable=home-assistant-tests-registry-fixtures
assert issue is None
+1 -1
View File
@@ -6744,7 +6744,7 @@ async def test_clean_up_repairs(
) -> None:
"""Test cleaning up repairs."""
await async_setup_component(hass, DOMAIN, {})
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
client = await hass_ws_client()
# Create some issues
+1 -1
View File
@@ -126,7 +126,7 @@ async def test_unique_id_migration(hass: HomeAssistant, mock_asyncsleepiq) -> No
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
ent_reg = er.async_get(hass)
ent_reg = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
sensor_is_in_bed = ent_reg.async_get(ENTITY_IS_IN_BED)
assert sensor_is_in_bed.unique_id == f"{SLEEPER_L_ID}_{IS_IN_BED}"
+2 -2
View File
@@ -115,7 +115,7 @@ async def test_upnp_disabled_discovery(
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done(wait_background_tasks=True)
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert (
issue_registry.async_get_issue(
sonos.DOMAIN, f"{UPNP_ISSUE_ID}_{soco.ip_address}"
@@ -144,7 +144,7 @@ async def test_upnp_disabled_manual_hosts(
):
await _setup_hass(hass)
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issue = issue_registry.async_get_issue(
sonos.DOMAIN, f"{UPNP_ISSUE_ID}_{soco.ip_address}"
)
+4 -4
View File
@@ -334,7 +334,7 @@ async def test_yaml_filter_only_no_deprecation_issue(
assert len(entries) == 0
# Verify no deprecation issue was created
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
issues = issue_registry.issues
assert not any(
issue_id[0] == DOMAIN and "deprecated" in issue_id[1] for issue_id in issues
@@ -370,7 +370,7 @@ async def test_yaml_with_connection_creates_deprecation_issue(
assert entries[0].source == SOURCE_IMPORT
# Verify deprecation issue was created in homeassistant domain
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert (HOMEASSISTANT_DOMAIN, f"deprecated_yaml_{DOMAIN}") in issue_registry.issues
@@ -400,7 +400,7 @@ async def test_yaml_import_error_creates_specific_issue(
assert len(entries) == 0
# Verify error-specific issue was created
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert (
DOMAIN,
"deprecated_yaml_import_issue_cannot_connect",
@@ -432,5 +432,5 @@ async def test_yaml_import_already_configured_creates_deprecation_issue(
await hass.async_block_till_done()
# Verify deprecation issue was still created (single_instance_allowed is ok)
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert (HOMEASSISTANT_DOMAIN, f"deprecated_yaml_{DOMAIN}") in issue_registry.issues
@@ -501,7 +501,7 @@ async def test_dhcp_known_player(
"""Test DHCP discovery aborts if player is already registered."""
mock_config_entry.add_to_hass(hass)
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entity_registry.async_get_or_create(
MP_DOMAIN, DOMAIN, "aa:bb:cc:dd:ee:ff", config_entry=mock_config_entry
)
+1 -1
View File
@@ -74,7 +74,7 @@ async def test_setup_g4(hass: HomeAssistant, subaru_config_entry) -> None:
assert check_entry.state is ConfigEntryState.LOADED
# Gen4 must receive both Gen2+ and Gen3+ sensor sets; without this, only
# the odometer was created on 2026 model year vehicles.
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert entity_registry.async_get_entity_id(
"sensor", DOMAIN, f"{TEST_VIN_4_G4}_AVG_FUEL_CONSUMPTION"
)
+1 -1
View File
@@ -399,7 +399,7 @@ async def test_hub_device_info_mac_connections(
setup_dsm_with_usb: MagicMock,
) -> None:
"""Test that the hub DeviceInfo includes MAC address connections."""
dev_reg = dr.async_get(hass)
dev_reg = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
device = dev_reg.async_get_device(identifiers={(DOMAIN, SERIAL)})
assert device is not None
assert device.connections == {
+1 -1
View File
@@ -41,7 +41,7 @@ def storage_setup_named_tag(
}
else:
hass_storage[DOMAIN] = items
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entry = entity_registry.async_get_or_create(DOMAIN, DOMAIN, TEST_TAG_ID)
entity_registry.async_update_entity(entry.entity_id, name=TEST_TAG_NAME)
config = {DOMAIN: {}}
+1 -1
View File
@@ -44,7 +44,7 @@ def storage_setup(hass: HomeAssistant, hass_storage: dict[str, Any]):
}
else:
hass_storage[DOMAIN] = items
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
_create_entry(entity_registry, TEST_TAG_ID, TEST_TAG_NAME)
_create_entry(entity_registry, TEST_TAG_ID_2, TEST_TAG_NAME_2)
config = {DOMAIN: {}}
+1 -1
View File
@@ -1149,7 +1149,7 @@ async def test_raise_segments_changed_issue(
hass.states.async_set(TEST_ATTRIBUTE_ENTITY_ID, "Bathroom")
await hass.async_block_till_done()
issue_registry = ir.async_get(hass)
issue_registry = ir.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert len(issue_registry.issues) != 0
+2 -2
View File
@@ -149,8 +149,8 @@ async def test_setup_and_remove_config_entry(
async def test_entry_changed(hass: HomeAssistant, platform) -> None:
"""Test reconfiguring."""
device_registry = dr.async_get(hass)
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
def _create_mock_entity(domain: str, name: str) -> er.RegistryEntry:
config_entry = MockConfigEntry(
+2 -2
View File
@@ -639,7 +639,7 @@ async def test_time_remaining_trigger_entity_removed_from_target(
now = dt_util.utcnow()
calls: list[dict[str, Any]] = []
label_reg = lr.async_get(hass)
label_reg = lr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
label = label_reg.async_create("Test Time Remaining")
entry = entity_registry.async_get_or_create(
@@ -688,7 +688,7 @@ async def test_time_remaining_trigger_entity_added_to_target(
now = dt_util.utcnow()
calls: list[dict[str, Any]] = []
label_reg = lr.async_get(hass)
label_reg = lr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
label = label_reg.async_create("Test Time Remaining Add")
entry = entity_registry.async_get_or_create(
@@ -35,7 +35,7 @@ async def test_restore_state(hass: HomeAssistant) -> None:
entry = MockConfigEntry(domain=DOMAIN, data={CONF_WEBHOOK_ID: "webhook_id"})
entry.add_to_hass(hass)
dr.async_get(hass).async_get_or_create(
dr.async_get(hass).async_get_or_create( # pylint: disable=home-assistant-tests-registry-fixtures
config_entry_id=entry.entry_id,
identifiers={(DOMAIN, DEVICE_ID)},
)
+2 -2
View File
@@ -202,7 +202,7 @@ async def test_get_tuya_device_error_non_tuya_device(
"""Test service error when target device is not a Tuya device."""
await initialize_entry(hass, mock_manager, mock_config_entry, mock_device)
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
non_tuya_device = device_registry.async_get_or_create(
config_entry_id=mock_config_entry.entry_id,
identifiers={("other_domain", "some_id")},
@@ -231,7 +231,7 @@ async def test_get_tuya_device_error_unknown_tuya_device(
"""Test service error when Tuya identifier is not present in manager map."""
await initialize_entry(hass, mock_manager, mock_config_entry, mock_device)
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
tuya_device = device_registry.async_get_or_create(
config_entry_id=mock_config_entry.entry_id,
identifiers={(DOMAIN, "unknown_tuya_id")},
@@ -988,7 +988,7 @@ async def test_aiport_no_binary_sensor_entities(
# AI Port should not create any camera-specific binary sensors
# (motion, smart detection, etc.)
# NVR HDD sensors will still be created, but no AI Port-specific entities
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
entities = er.async_entries_for_config_entry(entity_registry, ufp.entry.entry_id)
for entity in entities:
+2 -2
View File
@@ -150,7 +150,7 @@ async def test_first_active_quality_is_default(
== camera_all.channels[1].rtsps_no_srtp_url
)
entity_registry = er.async_get(hass)
entity_registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert entity_registry.async_get(_channel_entity_id(camera_all, 0)) is None
assert entity_registry.async_get(_channel_entity_id(camera_all, 2)) is None
assert (
@@ -424,7 +424,7 @@ async def test_public_only_camera(
# device identity degrades to name-only; the NVR link is omitted (resolving
# the NVR identity publicly is wired with the config-mode setup)
device_registry = dr.async_get(hass)
device_registry = dr.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
device = device_registry.async_get_device(
connections={(dr.CONNECTION_NETWORK_MAC, public.mac)}
)
@@ -140,7 +140,7 @@ async def test_multiple_entities_in_one_call(hass: HomeAssistant) -> None:
"""Test handling of service calls with multiple entity IDs."""
user_id = str(uuid.uuid4())
ent_reg = er.async_get(hass)
ent_reg = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
ent_reg.async_get_or_create(
"light",
"test",
+2 -2
View File
@@ -533,7 +533,7 @@ async def test_segments_changed_issue(
mock_vacuum.async_create_segments_issue()
issue_id = f"segments_changed_{entity_entry.id}"
issue = ir.async_get(hass).async_get_issue(DOMAIN, issue_id)
issue = ir.async_get(hass).async_get_issue(DOMAIN, issue_id) # pylint: disable=home-assistant-tests-registry-fixtures
assert issue is not None
assert issue.severity == ir.IssueSeverity.WARNING
assert issue.translation_key == "segments_changed"
@@ -551,7 +551,7 @@ async def test_segments_changed_issue(
)
await hass.async_block_till_done()
assert ir.async_get(hass).async_get_issue(DOMAIN, issue_id) is None
assert ir.async_get(hass).async_get_issue(DOMAIN, issue_id) is None # pylint: disable=home-assistant-tests-registry-fixtures
@pytest.mark.parametrize(("is_built_in", "log_warnings"), [(True, 0), (False, 3)])
+3 -3
View File
@@ -125,7 +125,7 @@ async def test_clean_area(hass: HomeAssistant) -> None:
"""Test HassVacuumCleanArea intent."""
await vacuum_intent.async_setup_intents(hass)
area_reg = ar.async_get(hass)
area_reg = ar.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
kitchen = area_reg.async_create("Kitchen")
vacuum_1 = f"{DOMAIN}.vacuum_1"
@@ -183,7 +183,7 @@ async def test_clean_area_no_matching_vacuum(hass: HomeAssistant) -> None:
"""Test HassVacuumCleanArea intent with no matching vacuum."""
await vacuum_intent.async_setup_intents(hass)
area_reg = ar.async_get(hass)
area_reg = ar.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
area_reg.async_create("Kitchen")
# No vacuums at all
@@ -238,7 +238,7 @@ async def test_clean_area_service_failure(hass: HomeAssistant) -> None:
"""Test HassVacuumCleanArea intent when the service call fails."""
await vacuum_intent.async_setup_intents(hass)
area_reg = ar.async_get(hass)
area_reg = ar.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
area_reg.async_create("Kitchen")
entity_id = f"{DOMAIN}.test_vacuum"
+1 -1
View File
@@ -167,7 +167,7 @@ async def test_migrate_entry_creates_repair_issue(hass: HomeAssistant) -> None:
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
issue = ir.async_get(hass).async_get_issue(DOMAIN, "update_redirect_uri")
issue = ir.async_get(hass).async_get_issue(DOMAIN, "update_redirect_uri") # pylint: disable=home-assistant-tests-registry-fixtures
assert issue is not None
assert issue.severity == ir.IssueSeverity.WARNING
+1 -1
View File
@@ -80,7 +80,7 @@ async def test_is_valid_call(
protocol = HassVoipDatagramProtocol(hass, voip_devices)
assert not protocol.is_valid_call(call_info)
ent_reg = er.async_get(hass)
ent_reg = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
allowed_call_entity_id = ent_reg.async_get_entity_id(
"switch", voip.DOMAIN, f"{voip_device.voip_id}-allow_call"
)
@@ -311,7 +311,7 @@ async def target_entities(
}
assert set(label_registry.labels) == {"label_1", "label_2", "label_3"}
assert set(area_registry.areas) == {"kitchen", "living_room", "bathroom", "garage"}
assert set(dr.async_get(hass).devices) == {
assert set(dr.async_get(hass).devices) == { # pylint: disable=home-assistant-tests-registry-fixtures
"device1",
"device2",
"area_device",
@@ -132,7 +132,7 @@ async def test_dynamic_entity_lifecycle(
),
)
await hass.async_block_till_done()
registry = er.async_get(hass)
registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
assert registry.async_get(entity_id) is None
assert hass.states.get(entity_id) is None
# The binary_sensor with the same unique_id is untouched.
@@ -201,7 +201,7 @@ async def test_unknown_unique_id_is_noop(
assert entity_id is not None
ha_zha_data = get_zha_data(hass)
registry = er.async_get(hass)
registry = er.async_get(hass) # pylint: disable=home-assistant-tests-registry-fixtures
# Added: nothing queued, no dispatcher signal fired.
with patch(
@@ -255,7 +255,7 @@ async def test_remove_entity_reference_when_ieee_already_cleared(
ieee = zha_device_proxy.device.ieee
gateway_proxy._ha_entity_refs.pop(ieee, None)
er.async_get(hass).async_remove(entity_id)
er.async_get(hass).async_remove(entity_id) # pylint: disable=home-assistant-tests-registry-fixtures
await hass.async_block_till_done()
assert ieee not in gateway_proxy._ha_entity_refs
@@ -0,0 +1,340 @@
"""Tests for the registry fixtures checker."""
from pathlib import Path
import astroid
from astroid import nodes
from pylint.testutils import MessageTest, UnittestLinter
from pylint_home_assistant.checkers.tests.registry_fixtures import (
RegistryFixturesChecker,
)
import pytest
from tests.pylint import assert_adds_messages, assert_no_messages, walk_checker
@pytest.fixture(name="registry_fixtures_checker")
def registry_fixtures_checker_fixture(
linter: UnittestLinter,
) -> RegistryFixturesChecker:
"""Fixture to provide a registry fixtures checker."""
return RegistryFixturesChecker(linter)
def _find_async_get_call(root_node: nodes.Module) -> nodes.Call:
"""Find the first ``<alias>.async_get(...)`` call node."""
for call in root_node.nodes_of_class(nodes.Call):
func = call.func
if isinstance(func, nodes.Attribute) and func.attrname == "async_get":
return call
raise AssertionError("no async_get call found")
def _expect_registry_fixture(node: nodes.Call, helper: str) -> MessageTest:
"""Build the expected MessageTest for a registry fixture violation."""
return MessageTest(
msg_id="home-assistant-tests-registry-fixtures",
node=node,
args=(helper, helper),
line=node.lineno,
col_offset=node.col_offset,
end_line=node.end_lineno,
end_col_offset=node.end_col_offset,
)
@pytest.mark.parametrize(
("helper", "alias"),
[
("area_registry", "ar"),
("category_registry", "cr"),
("device_registry", "dr"),
("entity_registry", "er"),
("floor_registry", "fr"),
("issue_registry", "ir"),
("label_registry", "lr"),
],
)
def test_aliased_import_in_test_function_flagged(
linter: UnittestLinter,
registry_fixtures_checker: RegistryFixturesChecker,
helper: str,
alias: str,
) -> None:
"""Aliased registry import called inside a test function is flagged."""
root_node = astroid.parse(
f"""
from homeassistant.helpers import {helper} as {alias}
async def test_something(hass) -> None:
registry = {alias}.async_get(hass)
""",
"tests.components.test_integration.test_init",
)
call_node = _find_async_get_call(root_node)
with assert_adds_messages(linter, _expect_registry_fixture(call_node, helper)):
walk_checker(linter, registry_fixtures_checker, root_node)
@pytest.mark.parametrize(
"helper",
[
"area_registry",
"category_registry",
"device_registry",
"entity_registry",
"floor_registry",
"issue_registry",
"label_registry",
],
)
def test_non_aliased_import_in_test_function_flagged(
linter: UnittestLinter,
registry_fixtures_checker: RegistryFixturesChecker,
helper: str,
) -> None:
"""Non-aliased registry import called inside a test is flagged."""
root_node = astroid.parse(
f"""
from homeassistant.helpers import {helper}
async def test_something(hass) -> None:
registry = {helper}.async_get(hass)
""",
"tests.components.test_integration.test_init",
)
call_node = _find_async_get_call(root_node)
with assert_adds_messages(linter, _expect_registry_fixture(call_node, helper)):
walk_checker(linter, registry_fixtures_checker, root_node)
@pytest.mark.parametrize(
"fixture_decorator",
[
"@pytest.fixture",
"@pytest.fixture()",
'@pytest.fixture(name="my_fixture")',
],
ids=["bare", "call", "named"],
)
def test_pytest_fixture_flagged(
linter: UnittestLinter,
registry_fixtures_checker: RegistryFixturesChecker,
fixture_decorator: str,
) -> None:
"""Calls inside a @pytest.fixture function are flagged."""
root_node = astroid.parse(
f"""
import pytest
from homeassistant.helpers import device_registry as dr
{fixture_decorator}
def my_helper(hass):
return dr.async_get(hass)
""",
"tests.components.test_integration.test_init",
)
call_node = _find_async_get_call(root_node)
with assert_adds_messages(
linter, _expect_registry_fixture(call_node, "device_registry")
):
walk_checker(linter, registry_fixtures_checker, root_node)
@pytest.mark.parametrize(
("code", "helper"),
[
pytest.param(
"""
from homeassistant.helpers import entity_registry as er
async def test_something(hass) -> None:
def _helper():
return er.async_get(hass)
_helper()
""",
"entity_registry",
id="nested_helper_in_test",
),
pytest.param(
"""
import pytest
from homeassistant.helpers import entity_registry as er
@pytest.fixture
def storage_setup(hass):
async def _storage(items=None):
entity_registry = er.async_get(hass)
return entity_registry
return _storage
""",
"entity_registry",
id="nested_helper_in_fixture",
),
],
)
def test_nested_helper_flagged(
linter: UnittestLinter,
registry_fixtures_checker: RegistryFixturesChecker,
code: str,
helper: str,
) -> None:
"""Calls in nested helpers inside tests/fixtures are flagged."""
root_node = astroid.parse(code, "tests.components.test_integration.test_init")
call_node = _find_async_get_call(root_node)
with assert_adds_messages(linter, _expect_registry_fixture(call_node, helper)):
walk_checker(linter, registry_fixtures_checker, root_node)
@pytest.mark.parametrize(
("code", "module_name"),
[
pytest.param(
"""
from homeassistant.helpers import entity_registry as er
def helper(hass):
return er.async_get(hass)
""",
"tests.components.test_integration.test_init",
id="non_test_non_fixture_helper",
),
pytest.param(
"""
from homeassistant.helpers import entity_registry as er
registry = er.async_get(None)
""",
"tests.components.test_integration.test_init",
id="module_top_level",
),
pytest.param(
"""
from homeassistant.helpers import entity_registry as er
async def test_something(hass) -> None:
registry = er.async_get(hass)
""",
"homeassistant.components.test_integration",
id="not_a_test_module",
),
pytest.param(
"""
from homeassistant.helpers import entity_registry as er
async def test_something(hass) -> None:
registry = er.async_get(hass)
""",
"tests.helpers.test_entity_registry",
id="tests_helpers_excluded",
),
pytest.param(
"""
from homeassistant.helpers import entity_registry as er
async def test_something(hass) -> None:
something = other.async_get(hass)
""",
"tests.components.test_integration.test_init",
id="unrelated_attribute_target",
),
pytest.param(
"""
from homeassistant.helpers import entity_registry as er
async def test_something(hass) -> None:
entry = er.async_get_or_create(hass)
""",
"tests.components.test_integration.test_init",
id="different_method_name",
),
pytest.param(
"""
async def test_something(hass) -> None:
# No import of any registry helper at module scope.
from homeassistant.helpers import entity_registry as er
registry = er.async_get(hass)
""",
"tests.components.test_integration.test_init",
id="local_import_not_tracked",
),
pytest.param(
"""
from homeassistant.helpers import entity_registry
async def test_something(hass, entity_registry) -> None:
entry = entity_registry.async_get("sensor.test")
""",
"tests.components.test_integration.test_init",
id="fixture_parameter_shadows_import",
),
pytest.param(
"""
from homeassistant.helpers import entity_registry
async def test_something(hass) -> None:
entity_registry = get_registry()
entry = entity_registry.async_get("sensor.test")
""",
"tests.components.test_integration.test_init",
id="local_assignment_shadows_import",
),
],
)
def test_no_warning(
linter: UnittestLinter,
registry_fixtures_checker: RegistryFixturesChecker,
code: str,
module_name: str,
) -> None:
"""Cases that should not produce a warning."""
root_node = astroid.parse(code, module_name)
with assert_no_messages(linter):
walk_checker(linter, registry_fixtures_checker, root_node)
def test_conftest_file_exempt(
linter: UnittestLinter,
registry_fixtures_checker: RegistryFixturesChecker,
tmp_path: Path,
) -> None:
"""Calls inside ``conftest.py`` files are not flagged."""
conftest_path = tmp_path / "conftest.py"
conftest_path.write_text("")
root_node = astroid.parse(
"""
import pytest
from homeassistant.helpers import entity_registry as er
@pytest.fixture
def entity_registry(hass):
return er.async_get(hass)
""",
"tests.components.test_integration.conftest",
)
root_node.file = str(conftest_path)
with assert_no_messages(linter):
walk_checker(linter, registry_fixtures_checker, root_node)