| 156 | |
| 157 | |
| 158 | class ParseResult(typing.NamedTuple): |
| 159 | scheme: str |
| 160 | userinfo: str |
| 161 | host: str |
| 162 | port: int | None |
| 163 | path: str |
| 164 | query: str | None |
| 165 | fragment: str | None |
| 166 | |
| 167 | @property |
| 168 | def authority(self) -> str: |
| 169 | return "".join( |
| 170 | [ |
| 171 | f"{self.userinfo}@" if self.userinfo else "", |
| 172 | f"[{self.host}]" if ":" in self.host else self.host, |
| 173 | f":{self.port}" if self.port is not None else "", |
| 174 | ] |
| 175 | ) |
| 176 | |
| 177 | @property |
| 178 | def netloc(self) -> str: |
| 179 | return "".join( |
| 180 | [ |
| 181 | f"[{self.host}]" if ":" in self.host else self.host, |
| 182 | f":{self.port}" if self.port is not None else "", |
| 183 | ] |
| 184 | ) |
| 185 | |
| 186 | def copy_with(self, **kwargs: str | None) -> ParseResult: |
| 187 | if not kwargs: |
| 188 | return self |
| 189 | |
| 190 | defaults = { |
| 191 | "scheme": self.scheme, |
| 192 | "authority": self.authority, |
| 193 | "path": self.path, |
| 194 | "query": self.query, |
| 195 | "fragment": self.fragment, |
| 196 | } |
| 197 | defaults.update(kwargs) |
| 198 | return urlparse("", **defaults) |
| 199 | |
| 200 | def __str__(self) -> str: |
| 201 | authority = self.authority |
| 202 | return "".join( |
| 203 | [ |
| 204 | f"{self.scheme}:" if self.scheme else "", |
| 205 | f"//{authority}" if authority else "", |
| 206 | self.path, |
| 207 | f"?{self.query}" if self.query is not None else "", |
| 208 | f"#{self.fragment}" if self.fragment is not None else "", |
| 209 | ] |
| 210 | ) |
| 211 | |
| 212 | |
| 213 | def urlparse(url: str = "", **kwargs: str | None) -> ParseResult: |