Returns ``True`` if the given string is a well-formed IP address. Supports IPv4 and IPv6.
(ip: str)
| 285 | |
| 286 | |
| 287 | def is_valid_ip(ip: str) -> bool: |
| 288 | """Returns ``True`` if the given string is a well-formed IP address. |
| 289 | |
| 290 | Supports IPv4 and IPv6. |
| 291 | """ |
| 292 | if not ip or "\x00" in ip: |
| 293 | # getaddrinfo resolves empty strings to localhost, and truncates |
| 294 | # on zero bytes. |
| 295 | return False |
| 296 | try: |
| 297 | res = socket.getaddrinfo( |
| 298 | ip, 0, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_NUMERICHOST |
| 299 | ) |
| 300 | return bool(res) |
| 301 | except socket.gaierror as e: |
| 302 | if e.args[0] == socket.EAI_NONAME: |
| 303 | return False |
| 304 | raise |
| 305 | except UnicodeError: |
| 306 | # `socket.getaddrinfo` will raise a UnicodeError from the |
| 307 | # `idna` decoder if the input is longer than 63 characters, |
| 308 | # even for socket.AI_NUMERICHOST. See |
| 309 | # https://bugs.python.org/issue32958 for discussion |
| 310 | return False |
| 311 | return True |
| 312 | |
| 313 | |
| 314 | class Resolver(Configurable): |
no outgoing calls