Skip to content

Commit bdcca7b

Browse files
committed
Implement get on CaseInsensitiveDict
get was previously provided by the parent class which had to raise KeyError for missing values. Since try/except is only cheap for the non-exception case the performance was not good when the key was missing similar to python/cpython#106665 but in the HA case we call this even more frequently
1 parent ac4171a commit bdcca7b

File tree

3 files changed

+28
-26
lines changed

3 files changed

+28
-26
lines changed

async_upnp_client/advertisement.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,24 +66,26 @@ def __init__(
6666

6767
def _on_data(self, request_line: str, headers: CaseInsensitiveDict) -> None:
6868
"""Handle data."""
69-
if headers.get("MAN") == SSDP_DISCOVER:
69+
if headers.get_lower("man") == SSDP_DISCOVER:
7070
# Ignore discover packets.
7171
return
72-
if "NTS" not in headers:
72+
73+
notification_sub_type = headers.get_lower("nts")
74+
if notification_sub_type is None:
7375
_LOGGER.debug("Got non-advertisement packet: %s, %s", request_line, headers)
7476
return
7577

76-
_LOGGER.debug(
77-
"Received advertisement, _remote_addr: %s, NT: %s, NTS: %s, USN: %s, location: %s",
78-
headers.get("_remote_addr", ""),
79-
headers.get("NT", "<no NT>"),
80-
headers.get("NTS", "<no NTS>"),
81-
headers.get("USN", "<no USN>"),
82-
headers.get("location", ""),
83-
)
78+
if _LOGGER.isEnabledFor(logging.DEBUG):
79+
_LOGGER.debug(
80+
"Received advertisement, _remote_addr: %s, NT: %s, NTS: %s, USN: %s, location: %s",
81+
headers.get_lower("_remote_addr", ""),
82+
headers.get_lower("nt", "<no NT>"),
83+
headers.get_lower("nts", "<no NTS>"),
84+
headers.get_lower("usn", "<no USN>"),
85+
headers.get_lower("location", ""),
86+
)
8487

8588
headers["_source"] = SsdpSource.ADVERTISEMENT
86-
notification_sub_type = headers["NTS"]
8789
if notification_sub_type == NotificationSubType.SSDP_ALIVE:
8890
if self.async_on_alive:
8991
coro = self.async_on_alive(headers)

async_upnp_client/ssdp_listener.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@
4141
def valid_search_headers(headers: CaseInsensitiveDict) -> bool:
4242
"""Validate if this search is usable."""
4343
# pylint: disable=invalid-name
44-
udn = headers.get("_udn") # type: Optional[str]
45-
st = headers.get("st") # type: Optional[str]
46-
location = headers.get("location", "") # type: str
44+
udn = headers.get_lower("_udn") # type: Optional[str]
45+
st = headers.get_lower("st") # type: Optional[str]
46+
location = headers.get_lower("location", "") # type: str
4747
return bool(
4848
udn
4949
and st
@@ -60,10 +60,10 @@ def valid_search_headers(headers: CaseInsensitiveDict) -> bool:
6060
def valid_advertisement_headers(headers: CaseInsensitiveDict) -> bool:
6161
"""Validate if this advertisement is usable for connecting to a device."""
6262
# pylint: disable=invalid-name
63-
udn = headers.get("_udn") # type: Optional[str]
64-
nt = headers.get("nt") # type: Optional[str]
65-
nts = headers.get("nts") # type: Optional[str]
66-
location = headers.get("location", "") # type: str
63+
udn = headers.get_lower("_udn") # type: Optional[str]
64+
nt = headers.get_lower("nt") # type: Optional[str]
65+
nts = headers.get_lower("nts") # type: Optional[str]
66+
location = headers.get_lower("location", "") # type: str
6767
return bool(
6868
udn
6969
and nt
@@ -81,15 +81,15 @@ def valid_advertisement_headers(headers: CaseInsensitiveDict) -> bool:
8181
def valid_byebye_headers(headers: CaseInsensitiveDict) -> bool:
8282
"""Validate if this advertisement has required headers for byebye."""
8383
# pylint: disable=invalid-name
84-
udn = headers.get("_udn") # type: Optional[str]
85-
nt = headers.get("nt") # type: Optional[str]
86-
nts = headers.get("nts") # type: Optional[str]
84+
udn = headers.get_lower("_udn") # type: Optional[str]
85+
nt = headers.get_lower("nt") # type: Optional[str]
86+
nts = headers.get_lower("nts") # type: Optional[str]
8787
return bool(udn and nt and nts)
8888

8989

9090
def extract_valid_to(headers: CaseInsensitiveDict) -> datetime:
9191
"""Extract/create valid to."""
92-
cache_control = headers.get("cache-control", "")
92+
cache_control = headers.get_lower("cache-control", "")
9393
match = CACHE_CONTROL_RE.search(cache_control)
9494
if match:
9595
max_age = int(match[1])
@@ -247,7 +247,7 @@ def ip_version_from_location(location: str) -> Optional[int]:
247247

248248
def location_changed(ssdp_device: SsdpDevice, headers: CaseInsensitiveDict) -> bool:
249249
"""Test if location changed for device."""
250-
new_location = headers.get("location", "")
250+
new_location = headers.get_lower("location", "")
251251
if not new_location:
252252
return False
253253

async_upnp_client/utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ def as_lower_dict(self) -> Dict[str, Any]:
4141
"""Return the underlying dict in lowercase."""
4242
return {k.lower(): v for k, v in self._data.items()}
4343

44-
def get_lower(self, lower_key: str) -> Any:
44+
def get_lower(self, lower_key: str, default: Any = None) -> Any:
4545
"""Get a lower case key."""
4646
data_key = self._case_map.get(lower_key, _SENTINEL)
4747
if data_key is not _SENTINEL:
48-
return self._data[data_key]
49-
return None
48+
return self._data.get(data_key, default)
49+
return default
5050

5151
def replace(self, new_data: abcMapping) -> None:
5252
"""Replace the underlying dict."""

0 commit comments

Comments
 (0)