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