_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
type_ = 'Localhost.LOCAL.'
@lru_cache(maxsize=512)
def service_type_name(type_: str, *, strict: bool = True) -> str: # pylint: disable=too-many-branches
"""
Validate a fully qualified service name, instance or subtype. [rfc6763]
Returns fully qualified service name.
Domain names used by mDNS-SD take the following forms:
<sn> . <_tcp|_udp> . local.
<Instance> . <sn> . <_tcp|_udp> . local.
<sub>._sub . <sn> . <_tcp|_udp> . local.
1) must end with 'local.'
This is true because we are implementing mDNS and since the 'm' means
multi-cast, the 'local.' domain is mandatory.
2) local is preceded with either '_udp.' or '_tcp.' unless
strict is False
3) service name <sn> precedes <_tcp|_udp> unless
strict is False
The rules for Service Names [RFC6335] state that they may be no more
than fifteen characters long (not counting the mandatory underscore),
consisting of only letters, digits, and hyphens, must begin and end
with a letter or digit, must not contain consecutive hyphens, and
must contain at least one letter.
The instance name <Instance> and sub type <sub> may be up to 63 bytes.
The portion of the Service Instance Name is a user-
friendly name consisting of arbitrary Net-Unicode text [RFC5198]. It
MUST NOT contain ASCII control characters (byte values 0x00-0x1F and
0x7F) [RFC20] but otherwise is allowed to contain any characters,
without restriction, including spaces, uppercase, lowercase,
punctuation -- including dots -- accented characters, non-Roman text,
and anything else that may be represented using Net-Unicode.
:param type_: Type, SubType or service name to validate
:return: fully qualified service name (eg: _http._tcp.local.)
"""
if len(type_) > 256:
# https://datatracker.ietf.org/doc/html/rfc6763#section-7.2
raise BadTypeInNameException(f"Full name ({type_}) must be > 256 bytes")
if type_.endswith((_TCP_PROTOCOL_LOCAL_TRAILER, _NONTCP_PROTOCOL_LOCAL_TRAILER)):
remaining = type_[: -len(_TCP_PROTOCOL_LOCAL_TRAILER)].split(".")
trailer = type_[-len(_TCP_PROTOCOL_LOCAL_TRAILER) :]
has_protocol = True
elif strict:
raise BadTypeInNameException(
f"Type '{type_}' must end with "
f"'{_TCP_PROTOCOL_LOCAL_TRAILER}' or '{_NONTCP_PROTOCOL_LOCAL_TRAILER}'"
)
elif type_.endswith(_LOCAL_TRAILER):
remaining = type_[: -len(_LOCAL_TRAILER)].split(".")
trailer = type_[-len(_LOCAL_TRAILER) + 1 :]
has_protocol = False
else:
> raise BadTypeInNameException(f"Type '{type_}' must end with '{_LOCAL_TRAILER}'")
E zeroconf._exceptions.BadTypeInNameException: Type 'Localhost.LOCAL.' must end with '.local.'
strict = False
type_ = 'Localhost.LOCAL.'
/opt/hostedtoolcache/Python/3.10.20/x64/lib/python3.10/site-packages/zeroconf/_utils/name.py:100: BadTypeInNameException
============================= slowest 10 durations =============================
0.20s call tests/test_impl.py::test_exception_dns_before_result_async_dual_mdns_resolver
0.20s call tests/test_impl.py::test_exception_mdns_before_result_async_dual_mdns_resolver
0.10s call tests/test_impl.py::test_no_cancel_swallow_dual_mdns_resolver
0.01s call tests/test_impl.py::test_resolve_localhost_with_async_mdns_resolver
0.01s setup tests/test_api.py::test_api
0.01s setup tests/test_impl.py::test_resolve_localhost_with_async_mdns_resolver
(4 durations < 0.005s hidden. Use -vv to show these durations.)
=========================== short test summary info ============================
FAILED tests/test_impl.py::test_resolve_mdns_name_mixed_case - zeroconf._exceptions.BadTypeInNameException: Type 'Localhost.LOCAL.' must end with '.local.'
========================= 1 failed, 23 passed in 1.21s =========================