diff --git a/examples/ip_secure_calculations.py b/examples/ip_secure_calculations.py
index 8f9743092..a4db5abb5 100644
--- a/examples/ip_secure_calculations.py
+++ b/examples/ip_secure_calculations.py
@@ -268,7 +268,7 @@ def main() -> None:
)
session_authenticate = bytes.fromhex(
"06 10 09 53 00 18 00 01"
- "1f 1d 59 ea 9f 12 a1 52 e5 d9 72 7f 08 46 2c de" # MAC
+ + "1f 1d 59 ea 9f 12 a1 52 e5 d9 72 7f 08 46 2c de" # MAC
)
mac_cbc_authenticate = calculate_message_authentication_code_cbc(
password_hash,
diff --git a/pyproject.toml b/pyproject.toml
index 73f8a269d..986364cbf 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -165,3 +165,6 @@ combine-as-imports = true
"RUF012",
"SLF", # private member access
] # Mutable class attributes should be annotated with `typing.ClassVar`
+
+[tool.ruff.lint.flake8-builtins]
+builtins-allowed-modules = ["datetime"]
diff --git a/requirements/testing.txt b/requirements/testing.txt
index 71d8adcab..9c109460b 100644
--- a/requirements/testing.txt
+++ b/requirements/testing.txt
@@ -7,7 +7,7 @@ pytest==8.3.4
pytest-asyncio==0.25.2
pytest-cov==6.0.0
pytest-icdiff==0.9
-ruff==0.8.6
+ruff==0.9.2
setuptools==75.8.0
tox==4.23.2
tox-gh-actions==3.2.0
diff --git a/test/knxip_tests/connect_request_test.py b/test/knxip_tests/connect_request_test.py
index 201d4a766..536e97b1d 100644
--- a/test/knxip_tests/connect_request_test.py
+++ b/test/knxip_tests/connect_request_test.py
@@ -126,7 +126,8 @@ def test_from_knx_wrong_length_of_cri(self):
def test_from_knx_wrong_length_of_cri2(self):
"""Test parsing and streaming wrong ConnectRequest."""
raw = bytes.fromhex(
- "06 10 02 05 00 18 08 01 C0 A8 2A 01 84 95 08 01 C0 A8 2A 01 CC A9 03 03"
+ "06 10 02 05 00 18 08 01 C0 A8 2A 01 84 95 08 01"
+ + "C0 A8 2A 01 CC A9 03 03"
)
with pytest.raises(CouldNotParseKNXIP):
KNXIPFrame.from_knx(raw)
@@ -134,7 +135,8 @@ def test_from_knx_wrong_length_of_cri2(self):
def test_from_knx_wrong_length_of_cri3(self):
"""Test parsing and streaming wrong ConnectRequest."""
raw = bytes.fromhex(
- "06 10 02 05 00 18 08 01 C0 A8 2A 01 84 95 08 01 C0 A8 2A 01 CC A9 01 03"
+ "06 10 02 05 00 18 08 01 C0 A8 2A 01 84 95 08 01"
+ + "C0 A8 2A 01 CC A9 01 03"
)
with pytest.raises(CouldNotParseKNXIP):
KNXIPFrame.from_knx(raw)
@@ -142,7 +144,8 @@ def test_from_knx_wrong_length_of_cri3(self):
def test_from_knx_wrong_length_of_cri4(self):
"""Test parsing and streaming wrong ConnectRequest."""
raw = bytes.fromhex(
- "06 10 02 05 00 19 08 01 C0 A8 2A 01 84 95 08 01 C0 A8 2A 01 CC A9 03 03 01"
+ "06 10 02 05 00 19 08 01 C0 A8 2A 01 84 95 08 01"
+ + "C0 A8 2A 01 CC A9 03 03 01"
)
with pytest.raises(CouldNotParseKNXIP):
KNXIPFrame.from_knx(raw)
@@ -151,7 +154,7 @@ def test_from_knx_wrong_cri(self):
"""Test parsing and streaming wrong ConnectRequest."""
raw = bytes.fromhex(
"06 10 02 05 00 1A 08 01 C0 A8 2A 01 84 95 08 01"
- "C0 A8 2A 01 CC A9 04 04 02"
+ + "C0 A8 2A 01 CC A9 04 04 02"
)
with pytest.raises(CouldNotParseKNXIP):
KNXIPFrame.from_knx(raw)
diff --git a/test/knxip_tests/session_authenticate_test.py b/test/knxip_tests/session_authenticate_test.py
index 302664f21..03b820124 100644
--- a/test/knxip_tests/session_authenticate_test.py
+++ b/test/knxip_tests/session_authenticate_test.py
@@ -13,7 +13,7 @@ def test_session_authenticate(self):
"e5 d9 72 7f 08 46 2c de"
)
raw = (
- bytes.fromhex("06 10 09 53 00 18" "00 01") # KNXnet/IP header # User ID
+ bytes.fromhex("06 10 09 53 00 18 00 01") # KNXnet/IP header # User ID
+ message_authentication_code
)
knxipframe, _ = KNXIPFrame.from_knx(raw)
diff --git a/test/knxip_tests/timer_notify_test.py b/test/knxip_tests/timer_notify_test.py
index 355e4adde..bf2da13a4 100644
--- a/test/knxip_tests/timer_notify_test.py
+++ b/test/knxip_tests/timer_notify_test.py
@@ -9,7 +9,7 @@ class TestKNXIPTimerNotify:
def test_timer_notify(self):
"""Test parsing and streaming TimerNotify KNX/IP packet."""
message_authentication_code = bytes.fromhex(
- "72 12 a0 3a aa e4 9d a8" "56 89 77 4c 1d 2b 4d a4"
+ "72 12 a0 3a aa e4 9d a8 56 89 77 4c 1d 2b 4d a4"
)
raw = (
bytes.fromhex(
diff --git a/xknx/cemi/cemi_frame.py b/xknx/cemi/cemi_frame.py
index 0b38af6fc..cb6ca888d 100644
--- a/xknx/cemi/cemi_frame.py
+++ b/xknx/cemi/cemi_frame.py
@@ -478,11 +478,7 @@ def from_knx(cls, raw: bytes) -> CEMIData:
def __repr__(self) -> str:
"""Return object as readable string."""
- return (
- f"CEMIMPropWriteRequest("
- f"{self.property_info}"
- f'data="{self.data.hex()}" )'
- )
+ return f'CEMIMPropWriteRequest({self.property_info}data="{self.data.hex()}" )'
class CEMIMPropWriteResponse(CEMIData):
diff --git a/xknx/knxip/connect_response.py b/xknx/knxip/connect_response.py
index 37f660bf6..340eaaf44 100644
--- a/xknx/knxip/connect_response.py
+++ b/xknx/knxip/connect_response.py
@@ -141,8 +141,4 @@ def __repr__(self) -> str:
if self._is_tunnel_crd() and self.individual_address
else ""
)
- return (
- ""
- )
+ return f''
diff --git a/xknx/knxip/description_response.py b/xknx/knxip/description_response.py
index 43feba861..a3d5c9378 100644
--- a/xknx/knxip/description_response.py
+++ b/xknx/knxip/description_response.py
@@ -52,4 +52,4 @@ def to_knx(self) -> bytes:
def __repr__(self) -> str:
"""Return object as readable string."""
_dibs_str = ",\n".join(dib.__repr__() for dib in self.dibs)
- return "'
+ return f''