Enable ruff B010 rule and replace setattr with direct attribute assignmet (#170527)

This commit is contained in:
Franck Nijhof
2026-05-13 23:39:32 +02:00
committed by GitHub
parent d7568a8f16
commit 555d838290
17 changed files with 37 additions and 42 deletions
+1 -1
View File
@@ -207,7 +207,7 @@ def validate_state(state: str) -> str:
def callback[_CallableT: Callable[..., Any]](func: _CallableT) -> _CallableT:
"""Annotation to mark method as safe to call from within the event loop."""
setattr(func, "_hass_callback", True)
setattr(func, "_hass_callback", True) # noqa: B010
return func
+1 -3
View File
@@ -367,9 +367,7 @@ async def async_process_ha_core_config(hass: HomeAssistant, config: dict) -> Non
[{"type": "totp", "id": "totp", "name": "Authenticator app"}],
)
setattr(
hass, "auth", await auth.auth_manager_from_config(hass, auth_conf, mfa_conf)
)
hass.auth = await auth.auth_manager_from_config(hass, auth_conf, mfa_conf)
await hass.config.async_load()
+1 -1
View File
@@ -1411,7 +1411,7 @@ def _make_entity_service_schema(schema: dict, extra: int) -> VolSchemaType:
),
_HAS_ENTITY_SERVICE_FIELD,
)
setattr(validator, "_entity_service_schema", True)
setattr(validator, "_entity_service_schema", True) # noqa: B010
return validator
+1 -1
View File
@@ -43,7 +43,7 @@ def deprecated_substitute[_ObjectT: object](
inspect.getfile(self.__class__),
)
warnings[module_name] = True
setattr(func, "_deprecated_substitute_warnings", warnings)
setattr(func, "_deprecated_substitute_warnings", warnings) # noqa: B010
# Return the old property
return getattr(self, substitute_name)
@@ -475,7 +475,7 @@ class SchemaOptionsFlowHandler(OptionsFlow):
)
if async_setup_preview:
setattr(self, "async_setup_preview", async_setup_preview)
setattr(self, "async_setup_preview", async_setup_preview) # noqa: B010
@property
def options(self) -> dict[str, Any]:
+1
View File
@@ -658,6 +658,7 @@ select = [
"B006", # Do not use mutable data structures for argument defaults
"B007", # Loop control variable {name} not used within loop body
"B009", # Do not call getattr with a constant attribute value. It is not any safer than normal property access.
"B010", # Do not call setattr with a constant attribute value. It is not any safer than normal property access.
"B011", # Do not call assert False since python -O removes these calls
"B012", # Use of break/continue/return inside a finally block
"B013", # A length-one tuple literal is redundant in exception handlers
+2 -2
View File
@@ -1248,7 +1248,7 @@ def patch_yaml_files(files_dict, endswith=True):
if fname in files_dict:
_LOGGER.debug("patch_yaml_files match %s", fname)
res = StringIO(files_dict[fname])
setattr(res, "name", fname)
res.name = fname
return res
# Match using endswith
@@ -1256,7 +1256,7 @@ def patch_yaml_files(files_dict, endswith=True):
if fname.endswith(ends):
_LOGGER.debug("patch_yaml_files end match %s: %s", ends, fname)
res = StringIO(files_dict[ends])
setattr(res, "name", fname)
res.name = fname
return res
# Fallback for hass.components (i.e. services.yaml)
+1 -1
View File
@@ -41,7 +41,7 @@ async def test_switch(hass: HomeAssistant, client: MagicMock) -> None:
await common.async_turn_off(hass, ENTITY_SWITCH)
client.configure_filter_cycle.assert_called_with(2, enabled=False)
setattr(client, "filter_cycle_2_enabled", False)
client.filter_cycle_2_enabled = False
client.emit("")
await hass.async_block_till_done()
+1 -5
View File
@@ -45,11 +45,7 @@ async def test_nested() -> None:
def mock_client_fixture() -> Generator[MagicMock]:
"""Mock the pubsub client."""
with patch(f"{GOOGLE_PUBSUB_PATH}.PublisherClient") as client:
setattr(
client,
"from_service_account_json",
MagicMock(return_value=MagicMock()),
)
client.from_service_account_json = MagicMock(return_value=MagicMock())
yield client
+1 -1
View File
@@ -198,6 +198,6 @@ class MockLight(MockToggleEntity, LightEntity):
]:
setattr(self, key, value)
if key == "white":
setattr(self, "brightness", value)
self.brightness = value
if key in TURN_ON_ARG_TO_COLOR_MODE:
self._attr_color_mode = TURN_ON_ARG_TO_COLOR_MODE[key]
+1 -1
View File
@@ -2836,7 +2836,7 @@ def mock_client_fixture():
with mock.patch(f"{PROMETHEUS_PATH}.prometheus_client") as client:
counter_client = mock.MagicMock()
client.Counter = mock.MagicMock(return_value=counter_client)
setattr(counter_client, "labels", mock.MagicMock(return_value=mock.MagicMock()))
counter_client.labels = mock.MagicMock(return_value=mock.MagicMock())
yield counter_client
+10 -10
View File
@@ -279,11 +279,11 @@ def make_dnd_timer(dataclass_template: RoborockBase) -> AsyncMock:
)
async def set_dnd_timer(timer: DnDTimer) -> None:
setattr(dnd_trait, "start_hour", timer.start_hour)
setattr(dnd_trait, "start_minute", timer.start_minute)
setattr(dnd_trait, "end_hour", timer.end_hour)
setattr(dnd_trait, "end_minute", timer.end_minute)
setattr(dnd_trait, "enabled", timer.enabled)
dnd_trait.start_hour = timer.start_hour
dnd_trait.start_minute = timer.start_minute
dnd_trait.end_hour = timer.end_hour
dnd_trait.end_minute = timer.end_minute
dnd_trait.enabled = timer.enabled
dnd_trait.set_dnd_timer = AsyncMock()
dnd_trait.set_dnd_timer.side_effect = set_dnd_timer
@@ -298,11 +298,11 @@ def make_valley_electric_timer(dataclass_template: RoborockBase) -> AsyncMock:
)
async def set_timer(timer: ValleyElectricityTimer) -> None:
setattr(valley_electric_timer_trait, "start_hour", timer.start_hour)
setattr(valley_electric_timer_trait, "start_minute", timer.start_minute)
setattr(valley_electric_timer_trait, "end_hour", timer.end_hour)
setattr(valley_electric_timer_trait, "end_minute", timer.end_minute)
setattr(valley_electric_timer_trait, "enabled", timer.enabled)
valley_electric_timer_trait.start_hour = timer.start_hour
valley_electric_timer_trait.start_minute = timer.start_minute
valley_electric_timer_trait.end_hour = timer.end_hour
valley_electric_timer_trait.end_minute = timer.end_minute
valley_electric_timer_trait.enabled = timer.enabled
valley_electric_timer_trait.set_timer = AsyncMock()
valley_electric_timer_trait.set_timer.side_effect = set_timer
+1 -1
View File
@@ -214,7 +214,7 @@ def mock_client(mock_location: TotalConnectLocation) -> Generator[TotalConnectCl
"can_bypass_zones": True,
"can_clear_bypass": True,
}
setattr(client, "_user", user_mock)
client._user = user_mock
yield client
+4 -4
View File
@@ -85,13 +85,13 @@ async def test_sync_turn_on(hass: HomeAssistant) -> None:
water_heater.hass = hass
# Test with turn_on method defined
setattr(water_heater, "turn_on", MagicMock())
water_heater.turn_on = MagicMock()
await water_heater.async_turn_on()
assert water_heater.turn_on.call_count == 1
# Test with async_turn_on method defined
setattr(water_heater, "async_turn_on", AsyncMock())
water_heater.async_turn_on = AsyncMock()
await water_heater.async_turn_on()
assert water_heater.async_turn_on.call_count == 1
@@ -103,13 +103,13 @@ async def test_sync_turn_off(hass: HomeAssistant) -> None:
water_heater.hass = hass
# Test with turn_off method defined
setattr(water_heater, "turn_off", MagicMock())
water_heater.turn_off = MagicMock()
await water_heater.async_turn_off()
assert water_heater.turn_off.call_count == 1
# Test with async_turn_off method defined
setattr(water_heater, "async_turn_off", AsyncMock())
water_heater.async_turn_off = AsyncMock()
await water_heater.async_turn_off()
assert water_heater.async_turn_off.call_count == 1
+3 -3
View File
@@ -229,9 +229,9 @@ def pytest_runtest_setup() -> None:
_validate_host(host)
return (host, [], [host])
setattr(socket, "getaddrinfo", getaddrinfo_patched)
setattr(socket, "gethostbyname", gethostbyname_patched)
setattr(socket, "gethostbyname_ex", gethostbyname_ex_patched)
socket.getaddrinfo = getaddrinfo_patched
socket.gethostbyname = gethostbyname_patched
socket.gethostbyname_ex = gethostbyname_ex_patched
pytest_socket.SocketBlockedError = HASocketBlockedError
+6 -6
View File
@@ -1128,8 +1128,8 @@ def test_deprecated_or_removed_logger_with_config_attributes(
option_status = "is deprecated"
replacement = f"'mars' option near {file}:{line} {option_status}, please replace it with '{replacement_key}'"
config = OrderedDict([("mars", "blah")])
setattr(config, "__config_file__", file)
setattr(config, "__line__", line)
config.__config_file__ = file
config.__line__ = line
validated = cv.deprecated("mars", replacement_key=replacement_key, default=False)(
config
@@ -1146,8 +1146,8 @@ def test_deprecated_or_removed_logger_with_config_attributes(
option_status = "has been removed"
replacement = f"'mars' option near {file}:{line} {option_status}, please remove it from your configuration"
config = OrderedDict([("mars", "blah")])
setattr(config, "__config_file__", file)
setattr(config, "__line__", line)
config.__config_file__ = file
config.__line__ = line
validated = cv.removed("mars", default=False, raise_if_present=False)(config)
assert "mars" not in validated # Removed because by cv.removed
@@ -1167,7 +1167,7 @@ def test_deprecated_logger_with_one_config_attribute(
line: int = 54
replacement = f"'mars' option near {file}:{line} is deprecated"
config = OrderedDict([("mars", "blah")])
setattr(config, "__config_file__", file)
config.__config_file__ = file
cv.deprecated("mars", replacement_key="jupiter", default=False)(config)
@@ -1181,7 +1181,7 @@ def test_deprecated_logger_with_one_config_attribute(
assert len(caplog.records) == 0
config = OrderedDict([("mars", "blah")])
setattr(config, "__line__", line)
config.__line__ = line
cv.deprecated("mars", replacement_key="jupiter", default=False)(config)
@@ -98,6 +98,6 @@ class MockLight(MockToggleEntity, LightEntity):
]:
setattr(self, key, value)
if key == "white":
setattr(self, "brightness", value)
self.brightness = value
if key in TURN_ON_ARG_TO_COLOR_MODE:
self._attr_color_mode = TURN_ON_ARG_TO_COLOR_MODE[key]