diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ceb8ee7f9c4..40757c09e95 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.1 + rev: v0.4.2 hooks: - id: ruff args: diff --git a/homeassistant/components/emoncms_history/__init__.py b/homeassistant/components/emoncms_history/__init__.py index ab3f2671b99..7de3a4f2ef8 100644 --- a/homeassistant/components/emoncms_history/__init__.py +++ b/homeassistant/components/emoncms_history/__init__.py @@ -86,8 +86,8 @@ def setup(hass: HomeAssistant, config: ConfigType) -> bool: continue if payload_dict: - payload = "{%s}" % ",".join( - f"{key}:{val}" for key, val in payload_dict.items() + payload = "{{{}}}".format( + ",".join(f"{key}:{val}" for key, val in payload_dict.items()) ) send_data( diff --git a/homeassistant/components/lamarzocco/coordinator.py b/homeassistant/components/lamarzocco/coordinator.py index 7901b0bb3fa..412fe9ee3ce 100644 --- a/homeassistant/components/lamarzocco/coordinator.py +++ b/homeassistant/components/lamarzocco/coordinator.py @@ -147,7 +147,7 @@ class LaMarzoccoUpdateCoordinator(DataUpdateCoordinator[None]): raise ConfigEntryAuthFailed(msg) from ex except RequestNotSuccessful as ex: _LOGGER.debug(ex, exc_info=True) - raise UpdateFailed("Querying API failed. Error: %s" % ex) from ex + raise UpdateFailed(f"Querying API failed. Error: {ex}") from ex def async_get_ble_device(self) -> BLEDevice | None: """Get a Bleak Client for the machine.""" diff --git a/homeassistant/components/nest/media_source.py b/homeassistant/components/nest/media_source.py index d48006c449d..6c481806e4f 100644 --- a/homeassistant/components/nest/media_source.py +++ b/homeassistant/components/nest/media_source.py @@ -322,7 +322,7 @@ class NestMediaSource(MediaSource): devices = async_get_media_source_devices(self.hass) if not (device := devices.get(media_id.device_id)): raise Unresolvable( - "Unable to find device with identifier: %s" % item.identifier + f"Unable to find device with identifier: {item.identifier}" ) if not media_id.event_token: # The device resolves to the most recent event if available @@ -330,7 +330,7 @@ class NestMediaSource(MediaSource): last_event_id := await _async_get_recent_event_id(media_id, device) ): raise Unresolvable( - "Unable to resolve recent event for device: %s" % item.identifier + f"Unable to resolve recent event for device: {item.identifier}" ) media_id = last_event_id @@ -377,7 +377,7 @@ class NestMediaSource(MediaSource): # Browse either a device or events within a device if not (device := devices.get(media_id.device_id)): raise BrowseError( - "Unable to find device with identiifer: %s" % item.identifier + f"Unable to find device with identiifer: {item.identifier}" ) # Clip previews are a session with multiple possible event types (e.g. # person, motion, etc) and a single mp4 @@ -399,7 +399,7 @@ class NestMediaSource(MediaSource): # Browse a specific event if not (single_clip := clips.get(media_id.event_token)): raise BrowseError( - "Unable to find event with identiifer: %s" % item.identifier + f"Unable to find event with identiifer: {item.identifier}" ) return _browse_clip_preview(media_id, device, single_clip) @@ -419,7 +419,7 @@ class NestMediaSource(MediaSource): # Browse a specific event if not (single_image := images.get(media_id.event_token)): raise BrowseError( - "Unable to find event with identiifer: %s" % item.identifier + f"Unable to find event with identiifer: {item.identifier}" ) return _browse_image_event(media_id, device, single_image) diff --git a/homeassistant/components/netio/switch.py b/homeassistant/components/netio/switch.py index 0f0c85c1720..4cc77e44ec4 100644 --- a/homeassistant/components/netio/switch.py +++ b/homeassistant/components/netio/switch.py @@ -165,7 +165,7 @@ class NetioSwitch(SwitchEntity): def _set(self, value): val = list("uuuu") val[int(self.outlet) - 1] = "1" if value else "0" - self.netio.get("port list %s" % "".join(val)) + self.netio.get("port list {}".format("".join(val))) self.netio.states[int(self.outlet) - 1] = value self.schedule_update_ha_state() diff --git a/homeassistant/components/rss_feed_template/__init__.py b/homeassistant/components/rss_feed_template/__init__.py index 8d2e47315ef..debff5a6e96 100644 --- a/homeassistant/components/rss_feed_template/__init__.py +++ b/homeassistant/components/rss_feed_template/__init__.py @@ -91,9 +91,7 @@ class RssView(HomeAssistantView): response += '\n' response += " \n" if self._title is not None: - response += " %s\n" % escape( - self._title.async_render(parse_result=False) - ) + response += f" {escape(self._title.async_render(parse_result=False))}\n" else: response += " Home Assistant\n" diff --git a/homeassistant/components/stream/worker.py b/homeassistant/components/stream/worker.py index 670d6b93c0e..956c93d01a0 100644 --- a/homeassistant/components/stream/worker.py +++ b/homeassistant/components/stream/worker.py @@ -592,7 +592,7 @@ def stream_worker( except av.AVError as ex: container.close() raise StreamWorkerError( - "Error demuxing stream while finding first packet: %s" % str(ex) + f"Error demuxing stream while finding first packet: {str(ex)}" ) from ex muxer = StreamMuxer( @@ -617,7 +617,7 @@ def stream_worker( except StopIteration as ex: raise StreamEndedError("Stream ended; no additional packets") from ex except av.AVError as ex: - raise StreamWorkerError("Error demuxing stream: %s" % str(ex)) from ex + raise StreamWorkerError(f"Error demuxing stream: {str(ex)}") from ex muxer.mux_packet(packet) diff --git a/homeassistant/components/tedee/coordinator.py b/homeassistant/components/tedee/coordinator.py index f3043b1d78d..069a7893974 100644 --- a/homeassistant/components/tedee/coordinator.py +++ b/homeassistant/components/tedee/coordinator.py @@ -100,9 +100,9 @@ class TedeeApiCoordinator(DataUpdateCoordinator[dict[int, TedeeLock]]): except TedeeDataUpdateException as ex: _LOGGER.debug("Error while updating data: %s", str(ex)) - raise UpdateFailed("Error while updating data: %s" % str(ex)) from ex + raise UpdateFailed(f"Error while updating data: {str(ex)}") from ex except (TedeeClientException, TimeoutError) as ex: - raise UpdateFailed("Querying API failed. Error: %s" % str(ex)) from ex + raise UpdateFailed(f"Querying API failed. Error: {str(ex)}") from ex def _async_add_remove_locks(self) -> None: """Add new locks, remove non-existing locks.""" diff --git a/homeassistant/components/tedee/lock.py b/homeassistant/components/tedee/lock.py index a720652bcbc..1c47ff2a6c1 100644 --- a/homeassistant/components/tedee/lock.py +++ b/homeassistant/components/tedee/lock.py @@ -90,7 +90,7 @@ class TedeeLockEntity(TedeeEntity, LockEntity): await self.coordinator.async_request_refresh() except (TedeeClientException, Exception) as ex: raise HomeAssistantError( - "Failed to unlock the door. Lock %s" % self._lock.lock_id + f"Failed to unlock the door. Lock {self._lock.lock_id}" ) from ex async def async_lock(self, **kwargs: Any) -> None: @@ -103,7 +103,7 @@ class TedeeLockEntity(TedeeEntity, LockEntity): await self.coordinator.async_request_refresh() except (TedeeClientException, Exception) as ex: raise HomeAssistantError( - "Failed to lock the door. Lock %s" % self._lock.lock_id + f"Failed to lock the door. Lock {self._lock.lock_id}" ) from ex @@ -125,5 +125,5 @@ class TedeeLockWithLatchEntity(TedeeLockEntity): await self.coordinator.async_request_refresh() except (TedeeClientException, Exception) as ex: raise HomeAssistantError( - "Failed to unlatch the door. Lock %s" % self._lock.lock_id + f"Failed to unlatch the door. Lock {self._lock.lock_id}" ) from ex diff --git a/homeassistant/components/verisure/lock.py b/homeassistant/components/verisure/lock.py index 227356a2525..da2bc2ced2b 100644 --- a/homeassistant/components/verisure/lock.py +++ b/homeassistant/components/verisure/lock.py @@ -112,7 +112,7 @@ class VerisureDoorlock(CoordinatorEntity[VerisureDataUpdateCoordinator], LockEnt digits = self.coordinator.entry.options.get( CONF_LOCK_CODE_DIGITS, DEFAULT_LOCK_CODE_DIGITS ) - return "^\\d{%s}$" % digits + return f"^\\d{{{digits}}}$" @property def is_locked(self) -> bool: diff --git a/homeassistant/helpers/device_registry.py b/homeassistant/helpers/device_registry.py index 00d0a0ba62f..aec5dbc6c4a 100644 --- a/homeassistant/helpers/device_registry.py +++ b/homeassistant/helpers/device_registry.py @@ -615,7 +615,7 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): return name.format(**translation_placeholders) except KeyError as err: if get_release_channel() is not ReleaseChannel.STABLE: - raise HomeAssistantError("Missing placeholder %s" % err) from err + raise HomeAssistantError(f"Missing placeholder {err}") from err report_issue = async_suggest_report_issue( self.hass, integration_domain=domain ) diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index a91b4c32d21..a2fc16f8a82 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -660,7 +660,7 @@ class Entity( except KeyError as err: if not self._name_translation_placeholders_reported: if get_release_channel() is not ReleaseChannel.STABLE: - raise HomeAssistantError("Missing placeholder %s" % err) from err + raise HomeAssistantError(f"Missing placeholder {err}") from err report_issue = self._suggest_report_issue() _LOGGER.warning( ( diff --git a/homeassistant/util/uuid.py b/homeassistant/util/uuid.py index d924eab934d..b7e9c2ae4f8 100644 --- a/homeassistant/util/uuid.py +++ b/homeassistant/util/uuid.py @@ -9,4 +9,4 @@ def random_uuid_hex() -> str: This uuid should not be used for cryptographically secure operations. """ - return "%032x" % getrandbits(32 * 4) + return f"{getrandbits(32 * 4):032x}" diff --git a/pyproject.toml b/pyproject.toml index baf919c2da5..d3f2af6bbf9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -659,7 +659,7 @@ filterwarnings = [ ] [tool.ruff] -required-version = ">=0.4.1" +required-version = ">=0.4.2" [tool.ruff.lint] select = [ diff --git a/requirements_test_pre_commit.txt b/requirements_test_pre_commit.txt index 4f21f6d4a0c..05e98a945d2 100644 --- a/requirements_test_pre_commit.txt +++ b/requirements_test_pre_commit.txt @@ -1,5 +1,5 @@ # Automatically generated from .pre-commit-config.yaml by gen_requirements_all.py, do not edit codespell==2.2.6 -ruff==0.4.1 +ruff==0.4.2 yamllint==1.35.1 diff --git a/tests/components/freebox/conftest.py b/tests/components/freebox/conftest.py index cf520043755..2fe4e1b77de 100644 --- a/tests/components/freebox/conftest.py +++ b/tests/components/freebox/conftest.py @@ -108,8 +108,7 @@ def mock_router_bridge_mode(mock_device_registry_devices, router): router().lan.get_hosts_list = AsyncMock( side_effect=HttpRequestError( - "Request failed (APIResponse: %s)" - % json.dumps(DATA_LAN_GET_HOSTS_LIST_MODE_BRIDGE) + f"Request failed (APIResponse: {json.dumps(DATA_LAN_GET_HOSTS_LIST_MODE_BRIDGE)})" ) ) diff --git a/tests/components/nest/test_media_source.py b/tests/components/nest/test_media_source.py index def99633435..419b3648124 100644 --- a/tests/components/nest/test_media_source.py +++ b/tests/components/nest/test_media_source.py @@ -399,7 +399,7 @@ async def test_camera_event( client = await hass_client() response = await client.get(media.url) - assert response.status == HTTPStatus.OK, "Response not matched: %s" % response + assert response.status == HTTPStatus.OK, f"Response not matched: {response}" contents = await response.read() assert contents == IMAGE_BYTES_FROM_EVENT @@ -572,7 +572,7 @@ async def test_multiple_image_events_in_session( client = await hass_client() response = await client.get(media.url) - assert response.status == HTTPStatus.OK, "Response not matched: %s" % response + assert response.status == HTTPStatus.OK, f"Response not matched: {response}" contents = await response.read() assert contents == IMAGE_BYTES_FROM_EVENT + b"-2" @@ -585,7 +585,7 @@ async def test_multiple_image_events_in_session( client = await hass_client() response = await client.get(media.url) - assert response.status == HTTPStatus.OK, "Response not matched: %s" % response + assert response.status == HTTPStatus.OK, f"Response not matched: {response}" contents = await response.read() assert contents == IMAGE_BYTES_FROM_EVENT + b"-1" @@ -673,7 +673,7 @@ async def test_multiple_clip_preview_events_in_session( client = await hass_client() response = await client.get(media.url) - assert response.status == HTTPStatus.OK, "Response not matched: %s" % response + assert response.status == HTTPStatus.OK, f"Response not matched: {response}" contents = await response.read() assert contents == IMAGE_BYTES_FROM_EVENT @@ -685,7 +685,7 @@ async def test_multiple_clip_preview_events_in_session( assert media.mime_type == "video/mp4" response = await client.get(media.url) - assert response.status == HTTPStatus.OK, "Response not matched: %s" % response + assert response.status == HTTPStatus.OK, f"Response not matched: {response}" contents = await response.read() assert contents == IMAGE_BYTES_FROM_EVENT @@ -888,7 +888,7 @@ async def test_camera_event_clip_preview( client = await hass_client() response = await client.get(media.url) - assert response.status == HTTPStatus.OK, "Response not matched: %s" % response + assert response.status == HTTPStatus.OK, f"Response not matched: {response}" contents = await response.read() assert contents == mp4.getvalue() @@ -896,7 +896,7 @@ async def test_camera_event_clip_preview( response = await client.get( f"/api/nest/event_media/{device.id}/{event_identifier}/thumbnail" ) - assert response.status == HTTPStatus.OK, "Response not matched: %s" % response + assert response.status == HTTPStatus.OK, f"Response not matched: {response}" await response.read() # Animated gif format not tested @@ -907,9 +907,7 @@ async def test_event_media_render_invalid_device_id( await setup_platform() client = await hass_client() response = await client.get("/api/nest/event_media/invalid-device-id") - assert response.status == HTTPStatus.NOT_FOUND, ( - "Response not matched: %s" % response - ) + assert response.status == HTTPStatus.NOT_FOUND, f"Response not matched: {response}" async def test_event_media_render_invalid_event_id( @@ -924,9 +922,7 @@ async def test_event_media_render_invalid_event_id( client = await hass_client() response = await client.get(f"/api/nest/event_media/{device.id}/invalid-event-id") - assert response.status == HTTPStatus.NOT_FOUND, ( - "Response not matched: %s" % response - ) + assert response.status == HTTPStatus.NOT_FOUND, f"Response not matched: {response}" async def test_event_media_failure( @@ -981,9 +977,7 @@ async def test_event_media_failure( # Media is not available to be fetched client = await hass_client() response = await client.get(media.url) - assert response.status == HTTPStatus.NOT_FOUND, ( - "Response not matched: %s" % response - ) + assert response.status == HTTPStatus.NOT_FOUND, f"Response not matched: {response}" async def test_media_permission_unauthorized( @@ -1011,9 +1005,9 @@ async def test_media_permission_unauthorized( client = await hass_client() response = await client.get(media_url) - assert response.status == HTTPStatus.UNAUTHORIZED, ( - "Response not matched: %s" % response - ) + assert ( + response.status == HTTPStatus.UNAUTHORIZED + ), f"Response not matched: {response}" async def test_multiple_devices( @@ -1157,7 +1151,7 @@ async def test_media_store_persistence( # Fetch event media client = await hass_client() response = await client.get(media.url) - assert response.status == HTTPStatus.OK, "Response not matched: %s" % response + assert response.status == HTTPStatus.OK, f"Response not matched: {response}" contents = await response.read() assert contents == IMAGE_BYTES_FROM_EVENT @@ -1198,7 +1192,7 @@ async def test_media_store_persistence( # Verify media exists response = await client.get(media.url) - assert response.status == HTTPStatus.OK, "Response not matched: %s" % response + assert response.status == HTTPStatus.OK, f"Response not matched: {response}" contents = await response.read() assert contents == IMAGE_BYTES_FROM_EVENT @@ -1254,9 +1248,7 @@ async def test_media_store_save_filesystem_error( # We fail to retrieve the media from the server since the origin filesystem op failed client = await hass_client() response = await client.get(media.url) - assert response.status == HTTPStatus.NOT_FOUND, ( - "Response not matched: %s" % response - ) + assert response.status == HTTPStatus.NOT_FOUND, f"Response not matched: {response}" async def test_media_store_load_filesystem_error( @@ -1307,9 +1299,9 @@ async def test_media_store_load_filesystem_error( response = await client.get( f"/api/nest/event_media/{device.id}/{event_identifier}" ) - assert response.status == HTTPStatus.NOT_FOUND, ( - "Response not matched: %s" % response - ) + assert ( + response.status == HTTPStatus.NOT_FOUND + ), f"Response not matched: {response}" @pytest.mark.parametrize(("device_traits", "cache_size"), [(BATTERY_CAMERA_TRAITS, 5)]) @@ -1384,7 +1376,7 @@ async def test_camera_event_media_eviction( for i in reversed(range(3, 8)): child_event = next(child_events) response = await client.get(f"/api/nest/event_media/{child_event.identifier}") - assert response.status == HTTPStatus.OK, "Response not matched: %s" % response + assert response.status == HTTPStatus.OK, f"Response not matched: {response}" contents = await response.read() assert contents == f"image-bytes-{i}".encode() await hass.async_block_till_done() @@ -1444,7 +1436,7 @@ async def test_camera_image_resize( client = await hass_client() response = await client.get(browse.thumbnail) - assert response.status == HTTPStatus.OK, "Response not matched: %s" % response + assert response.status == HTTPStatus.OK, f"Response not matched: {response}" contents = await response.read() assert contents == IMAGE_BYTES_FROM_EVENT diff --git a/tests/components/rainbird/conftest.py b/tests/components/rainbird/conftest.py index 10101986007..59471f5eed4 100644 --- a/tests/components/rainbird/conftest.py +++ b/tests/components/rainbird/conftest.py @@ -187,7 +187,7 @@ def aioclient_mock(hass: HomeAssistant) -> Generator[AiohttpClientMocker, None, def rainbird_json_response(result: dict[str, str]) -> bytes: """Create a fake API response.""" return encryption.encrypt( - '{"jsonrpc": "2.0", "result": %s, "id": 1} ' % json.dumps(result), + f'{{"jsonrpc": "2.0", "result": {json.dumps(result)}, "id": 1}} ', PASSWORD, ) diff --git a/tests/conftest.py b/tests/conftest.py index 3a95e0e58b3..7efd4246a1f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -499,7 +499,7 @@ def aiohttp_client( elif isinstance(__param, BaseTestServer): client = TestClient(__param, loop=loop, **kwargs) else: - raise TypeError("Unknown argument type: %r" % type(__param)) + raise TypeError(f"Unknown argument type: {type(__param)!r}") await client.start_server() clients.append(client) @@ -542,8 +542,8 @@ async def hass( else: exceptions.append( Exception( - "Received exception handler without exception, but with message: %s" - % context["message"] + "Received exception handler without exception, " + f"but with message: {context["message"]}" ) ) orig_exception_handler(loop, context) diff --git a/tests/helpers/test_template.py b/tests/helpers/test_template.py index 1e2e512cf3d..ae9dcbe50d5 100644 --- a/tests/helpers/test_template.py +++ b/tests/helpers/test_template.py @@ -707,7 +707,7 @@ def test_multiply(hass: HomeAssistant) -> None: for inp, out in tests.items(): assert ( template.Template( - "{{ %s | multiply(10) | round }}" % inp, hass + f"{{{{ {inp} | multiply(10) | round }}}}", hass ).async_render() == out ) @@ -775,7 +775,9 @@ def test_sine(hass: HomeAssistant) -> None: for value, expected in tests: assert ( - template.Template("{{ %s | sin | round(3) }}" % value, hass).async_render() + template.Template( + f"{{{{ {value} | sin | round(3) }}}}", hass + ).async_render() == expected ) assert render(hass, f"{{{{ sin({value}) | round(3) }}}}") == expected @@ -805,7 +807,9 @@ def test_cos(hass: HomeAssistant) -> None: for value, expected in tests: assert ( - template.Template("{{ %s | cos | round(3) }}" % value, hass).async_render() + template.Template( + f"{{{{ {value} | cos | round(3) }}}}", hass + ).async_render() == expected ) assert render(hass, f"{{{{ cos({value}) | round(3) }}}}") == expected @@ -835,7 +839,9 @@ def test_tan(hass: HomeAssistant) -> None: for value, expected in tests: assert ( - template.Template("{{ %s | tan | round(3) }}" % value, hass).async_render() + template.Template( + f"{{{{ {value} | tan | round(3) }}}}", hass + ).async_render() == expected ) assert render(hass, f"{{{{ tan({value}) | round(3) }}}}") == expected @@ -865,7 +871,9 @@ def test_sqrt(hass: HomeAssistant) -> None: for value, expected in tests: assert ( - template.Template("{{ %s | sqrt | round(3) }}" % value, hass).async_render() + template.Template( + f"{{{{ {value} | sqrt | round(3) }}}}", hass + ).async_render() == expected ) assert render(hass, f"{{{{ sqrt({value}) | round(3) }}}}") == expected @@ -895,7 +903,9 @@ def test_arc_sine(hass: HomeAssistant) -> None: for value, expected in tests: assert ( - template.Template("{{ %s | asin | round(3) }}" % value, hass).async_render() + template.Template( + f"{{{{ {value} | asin | round(3) }}}}", hass + ).async_render() == expected ) assert render(hass, f"{{{{ asin({value}) | round(3) }}}}") == expected @@ -909,7 +919,9 @@ def test_arc_sine(hass: HomeAssistant) -> None: for value in invalid_tests: with pytest.raises(TemplateError): - template.Template("{{ %s | asin | round(3) }}" % value, hass).async_render() + template.Template( + f"{{{{ {value} | asin | round(3) }}}}", hass + ).async_render() with pytest.raises(TemplateError): assert render(hass, f"{{{{ asin({value}) | round(3) }}}}") @@ -932,7 +944,9 @@ def test_arc_cos(hass: HomeAssistant) -> None: for value, expected in tests: assert ( - template.Template("{{ %s | acos | round(3) }}" % value, hass).async_render() + template.Template( + f"{{{{ {value} | acos | round(3) }}}}", hass + ).async_render() == expected ) assert render(hass, f"{{{{ acos({value}) | round(3) }}}}") == expected @@ -946,7 +960,9 @@ def test_arc_cos(hass: HomeAssistant) -> None: for value in invalid_tests: with pytest.raises(TemplateError): - template.Template("{{ %s | acos | round(3) }}" % value, hass).async_render() + template.Template( + f"{{{{ {value} | acos | round(3) }}}}", hass + ).async_render() with pytest.raises(TemplateError): assert render(hass, f"{{{{ acos({value}) | round(3) }}}}") @@ -973,7 +989,9 @@ def test_arc_tan(hass: HomeAssistant) -> None: for value, expected in tests: assert ( - template.Template("{{ %s | atan | round(3) }}" % value, hass).async_render() + template.Template( + f"{{{{ {value} | atan | round(3) }}}}", hass + ).async_render() == expected ) assert render(hass, f"{{{{ atan({value}) | round(3) }}}}") == expected @@ -1122,7 +1140,7 @@ def test_timestamp_local(hass: HomeAssistant) -> None: for inp, out in tests: assert ( - template.Template("{{ %s | timestamp_local }}" % inp, hass).async_render() + template.Template(f"{{{{ {inp} | timestamp_local }}}}", hass).async_render() == out ) @@ -1133,7 +1151,7 @@ def test_timestamp_local(hass: HomeAssistant) -> None: for inp in invalid_tests: with pytest.raises(TemplateError): - template.Template("{{ %s | timestamp_local }}" % inp, hass).async_render() + template.Template(f"{{{{ {inp} | timestamp_local }}}}", hass).async_render() # Test handling of default return value assert render(hass, "{{ None | timestamp_local(1) }}") == 1 @@ -1616,7 +1634,7 @@ def test_ordinal(hass: HomeAssistant) -> None: for value, expected in tests: assert ( - template.Template("{{ %s | ordinal }}" % value, hass).async_render() + template.Template(f"{{{{ {value} | ordinal }}}}", hass).async_render() == expected ) @@ -1631,7 +1649,7 @@ def test_timestamp_utc(hass: HomeAssistant) -> None: for inp, out in tests: assert ( - template.Template("{{ %s | timestamp_utc }}" % inp, hass).async_render() + template.Template(f"{{{{ {inp} | timestamp_utc }}}}", hass).async_render() == out ) @@ -1642,7 +1660,7 @@ def test_timestamp_utc(hass: HomeAssistant) -> None: for inp in invalid_tests: with pytest.raises(TemplateError): - template.Template("{{ %s | timestamp_utc }}" % inp, hass).async_render() + template.Template(f"{{{{ {inp} | timestamp_utc }}}}", hass).async_render() # Test handling of default return value assert render(hass, "{{ None | timestamp_utc(1) }}") == 1 @@ -4618,7 +4636,9 @@ def test_closest_function_invalid_state(hass: HomeAssistant) -> None: for state in ("states.zone.non_existing", '"zone.non_existing"'): assert ( - template.Template("{{ closest(%s, states) }}" % state, hass).async_render() + template.Template( + f"{{{{ closest({state}, states) }}}}", hass + ).async_render() is None )