Skip to content

Commit

Permalink
Mode detailed address parsing error messages (#1418)
Browse files Browse the repository at this point in the history
  • Loading branch information
farmio authored Feb 21, 2024
1 parent b5b8f08 commit 26c4db6
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 11 deletions.
5 changes: 5 additions & 0 deletions test/telegram_tests/address_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,3 +376,8 @@ def test_parse_device_invalid(self, address_test):
"""Test if the function raises CouldNotParseAddress on invalid values."""
with pytest.raises(CouldNotParseAddress):
parse_device_group_address(address_test)

def test_parse_device_invalid_group_address_message(self):
"""Test if the error message is from GroupAddress, not InternalGroupAddress for strings."""
with pytest.raises(CouldNotParseAddress, match=r".*Sub group out of range.*"):
parse_device_group_address("0/0/700")
48 changes: 37 additions & 11 deletions xknx/telegram/address.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
Self = TypeVar("Self", bound="BaseAddress")


INVALID_PREFIX_MESSAGE = "Invalid prefix for internal group address"


def parse_device_group_address(
address: DeviceAddressableType,
) -> DeviceGroupAddress:
Expand All @@ -39,7 +42,12 @@ def parse_device_group_address(
group_address = GroupAddress(address) # type: ignore[arg-type] # InternalGroupAddress will raise
except CouldNotParseAddress as ex:
if isinstance(address, (str, InternalGroupAddress)):
return InternalGroupAddress(address)
try:
return InternalGroupAddress(address)
except CouldNotParseAddress as internal_ex:
# prefer to raise original exception from GroupAddress
if internal_ex.message != INVALID_PREFIX_MESSAGE:
raise internal_ex
raise ex

if group_address.raw == 0:
Expand Down Expand Up @@ -110,7 +118,9 @@ def __init__(self, address: IndividualAddressableType) -> None:
raise CouldNotParseAddress(address, message="Invalid type")

if not 0 <= self.raw <= 65535:
raise CouldNotParseAddress(address, message="Address out of range")
raise CouldNotParseAddress(
address, message="Address out of range (0..65535)"
)

def __string_to_int(self, address: str) -> int:
"""
Expand All @@ -129,11 +139,17 @@ def __string_to_int(self, address: str) -> int:
main = int(match.group("main"))
line = int(match.group("line"))
if area > self.MAX_AREA:
raise CouldNotParseAddress(address, message="Area part out of range")
raise CouldNotParseAddress(
address, message=f"Area part out of range (0..{self.MAX_AREA})"
)
if main > self.MAX_MAIN:
raise CouldNotParseAddress(address, message="Line part out of range")
raise CouldNotParseAddress(
address, message=f"Line part out of range (0..{self.MAX_MAIN})"
)
if line > self.MAX_LINE:
raise CouldNotParseAddress(address, message="Device part out of range")
raise CouldNotParseAddress(
address, message=f"Device part out of range (0..{self.MAX_LINE})"
)
return (area << 12) + (main << 8) + line

@property
Expand Down Expand Up @@ -216,7 +232,9 @@ def __init__(self, address: GroupAddressableType) -> None:
raise CouldNotParseAddress(address, message="Invalid type")

if not 0 <= self.raw <= 65535:
raise CouldNotParseAddress(address, message="Address out of range")
raise CouldNotParseAddress(
address, message="Address out of range (0..65535)"
)

def __string_to_int(self, address: str) -> int:
"""
Expand All @@ -237,14 +255,22 @@ def __string_to_int(self, address: str) -> int:
)
sub = int(match.group("sub"))
if main > self.MAX_MAIN:
raise CouldNotParseAddress(address, message="Main group out of range")
raise CouldNotParseAddress(
address, message=f"Main group out of range (0..{self.MAX_MAIN})"
)
if middle is not None:
if middle > self.MAX_MIDDLE:
raise CouldNotParseAddress(address, message="Middle group out of range")
raise CouldNotParseAddress(
address, message=f"Middle group out of range (0..{self.MAX_MIDDLE})"
)
if sub > self.MAX_SUB_LONG:
raise CouldNotParseAddress(address, message="Sub group out of range")
raise CouldNotParseAddress(
address, message=f"Sub group out of range (0..{self.MAX_SUB_LONG})"
)
elif sub > self.MAX_SUB_SHORT:
raise CouldNotParseAddress(address, message="Sub group out of range")
raise CouldNotParseAddress(
address, message=f"Sub group out of range (0..{self.MAX_SUB_SHORT})"
)
return (
(main << 11) + (middle << 8) + sub
if middle is not None
Expand Down Expand Up @@ -324,7 +350,7 @@ def __init__(self, address: str | InternalGroupAddress) -> None:

prefix_length = 1
if len(address) < 2 or address[0].lower() != "i":
raise CouldNotParseAddress(address, message="Invalid prefix")
raise CouldNotParseAddress(address, message=INVALID_PREFIX_MESSAGE)
if address[1] in "-_":
prefix_length = 2

Expand Down

0 comments on commit 26c4db6

Please sign in to comment.