(self, s, partial=False)
| 383 | IP address (v4 or v6) with optional port |
| 384 | """ |
| 385 | def valid(self, s, partial=False): |
| 386 | # parse off port, use socket to validate addr |
| 387 | type = 6 |
| 388 | p: Optional[str] = None |
| 389 | if s.startswith('v1:'): |
| 390 | s = s[3:] |
| 391 | type = 4 |
| 392 | elif s.startswith('v2:'): |
| 393 | s = s[3:] |
| 394 | type = 6 |
| 395 | elif s.startswith('any:'): |
| 396 | s = s[4:] |
| 397 | type = 4 |
| 398 | elif s.startswith('['): |
| 399 | type = 6 |
| 400 | elif s.find('.') != -1: |
| 401 | type = 4 |
| 402 | |
| 403 | if type == 4: |
| 404 | port = s.find(':') |
| 405 | if port != -1: |
| 406 | a = s[:port] |
| 407 | p = s[port + 1:] |
| 408 | if int(p) > 65535: |
| 409 | raise ArgumentValid('{0}: invalid IPv4 port'.format(p)) |
| 410 | else: |
| 411 | a = s |
| 412 | p = None |
| 413 | try: |
| 414 | socket.inet_pton(socket.AF_INET, a) |
| 415 | except OSError: |
| 416 | raise ArgumentValid('{0}: invalid IPv4 address'.format(a)) |
| 417 | else: |
| 418 | # v6 |
| 419 | if s.startswith('['): |
| 420 | end = s.find(']') |
| 421 | if end == -1: |
| 422 | raise ArgumentFormat('{0} missing terminating ]'.format(s)) |
| 423 | if s[end + 1] == ':': |
| 424 | try: |
| 425 | p = s[end + 2] |
| 426 | except ValueError: |
| 427 | raise ArgumentValid('{0}: bad port number'.format(s)) |
| 428 | a = s[1:end] |
| 429 | else: |
| 430 | a = s |
| 431 | p = None |
| 432 | try: |
| 433 | socket.inet_pton(socket.AF_INET6, a) |
| 434 | except OSError: |
| 435 | raise ArgumentValid('{0} not valid IPv6 address'.format(s)) |
| 436 | if p is not None and int(p) > 65535: |
| 437 | raise ArgumentValid("{0} not a valid port number".format(p)) |
| 438 | self.val = s |
| 439 | self.addr = a |
| 440 | self.port = p |
| 441 | |
| 442 | def __str__(self): |
nothing calls this directly
no test coverage detected