@@ -647,6 +647,8 @@ def raw_host(self) -> Union[str, None]:
647647
648648 None for relative URLs.
649649
650+ When working with IPv6 addresses, use the `host_subcomponent` property instead
651+ as it will return the host subcomponent with brackets.
650652 """
651653 # Use host instead of hostname for sake of shortness
652654 # May add .hostname prop later
@@ -660,16 +662,35 @@ def host(self) -> Union[str, None]:
660662 None for relative URLs.
661663
662664 """
663- raw = self .raw_host
664- if raw is None :
665+ if (raw := self .raw_host ) is None :
665666 return None
666- if "%" in raw :
667- # Hack for scoped IPv6 addresses like
668- # fe80::2%Перевірка
669- # presence of '%' sign means only IPv6 address, so idna is useless.
667+ if raw and raw [- 1 ].isdigit () or ":" in raw :
668+ # IP addresses are never IDNA encoded
670669 return raw
671670 return _idna_decode (raw )
672671
672+ @cached_property
673+ def host_subcomponent (self ) -> Union [str , None ]:
674+ """Return the host subcomponent part of URL.
675+
676+ None for relative URLs.
677+
678+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2
679+
680+ `IP-literal = "[" ( IPv6address / IPvFuture ) "]"`
681+
682+ Examples:
683+ - `http://example.com:8080` -> `example.com`
684+ - `http://example.com:80` -> `example.com`
685+ - `https://127.0.0.1:8443` -> `127.0.0.1`
686+ - `https://[::1]:8443` -> `[::1]`
687+ - `http://[::1]` -> `[::1]`
688+
689+ """
690+ if (raw := self .raw_host ) is None :
691+ return None
692+ return f"[{ raw } ]" if ":" in raw else raw
693+
673694 @cached_property
674695 def port (self ) -> Union [int , None ]:
675696 """Port part of URL, with scheme-based fallback.
@@ -953,7 +974,8 @@ def _encode_host(cls, host: str, human: bool = False) -> str:
953974 # - 127.0.0.1 (last character is a digit)
954975 # - 2001:db8::ff00:42:8329 (contains a colon)
955976 # - 2001:db8::ff00:42:8329%eth0 (contains a colon)
956- # - [2001:db8::ff00:42:8329] (contains a colon)
977+ # - [2001:db8::ff00:42:8329] (contains a colon -- brackets should
978+ # have been removed before it gets here)
957979 # Rare IP Address formats are not supported per:
958980 # https://datatracker.ietf.org/doc/html/rfc3986#section-7.4
959981 #
0 commit comments