Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/validators/ip_address.py: 86%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

35 statements  

1"""IP Address.""" 

2 

3# standard 

4from ipaddress import ( 

5 AddressValueError, 

6 IPv4Address, 

7 IPv4Network, 

8 IPv6Address, 

9 IPv6Network, 

10 NetmaskValueError, 

11) 

12import re 

13from typing import Optional 

14 

15# local 

16from .utils import validator 

17 

18 

19def _check_private_ip(value: str, is_private: Optional[bool]): 

20 if is_private is None: 

21 return True 

22 if ( 

23 any( 

24 value.startswith(l_bit) 

25 for l_bit in { 

26 "10.", # private 

27 "192.168.", # private 

28 "169.254.", # link-local 

29 "127.", # localhost 

30 "0.0.0.0", # loopback #nosec 

31 } 

32 ) 

33 or re.match(r"^172\.(?:1[6-9]|2\d|3[0-1])\.", value) # private 

34 or re.match(r"^(?:22[4-9]|23[0-9]|24[0-9]|25[0-5])\.", value) # broadcast 

35 ): 

36 return is_private 

37 

38 return not is_private 

39 

40 

41@validator 

42def ipv4( 

43 value: str, 

44 /, 

45 *, 

46 cidr: bool = True, 

47 strict: bool = False, 

48 private: Optional[bool] = None, 

49 host_bit: bool = True, 

50): 

51 """Returns whether a given value is a valid IPv4 address. 

52 

53 From Python version 3.9.5 leading zeros are no longer tolerated 

54 and are treated as an error. The initial version of ipv4 validator 

55 was inspired from [WTForms IPAddress validator][1]. 

56 

57 [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py 

58 

59 Examples: 

60 >>> ipv4('123.0.0.7') 

61 True 

62 >>> ipv4('1.1.1.1/8') 

63 True 

64 >>> ipv4('900.80.70.11') 

65 ValidationError(func=ipv4, args={'value': '900.80.70.11'}) 

66 

67 Args: 

68 value: 

69 IP address string to validate. 

70 cidr: 

71 IP address string may contain CIDR notation. 

72 strict: 

73 IP address string is strictly in CIDR notation. 

74 private: 

75 IP address is public if `False`, private/local/loopback/broadcast if `True`. 

76 host_bit: 

77 If `False` and host bits (along with network bits) _are_ set in the supplied 

78 address, this function raises a validation error. ref [IPv4Network][2]. 

79 [2]: https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv4Network 

80 

81 Returns: 

82 (Literal[True]): If `value` is a valid IPv4 address. 

83 (ValidationError): If `value` is an invalid IPv4 address. 

84 """ 

85 if not value: 

86 return False 

87 try: 

88 if cidr: 

89 if strict and value.count("/") != 1: 

90 raise ValueError("IPv4 address was expected in CIDR notation") 

91 return IPv4Network(value, strict=not host_bit) and _check_private_ip(value, private) 

92 return IPv4Address(value) and _check_private_ip(value, private) 

93 except (ValueError, AddressValueError, NetmaskValueError): 

94 return False 

95 

96 

97@validator 

98def ipv6(value: str, /, *, cidr: bool = True, strict: bool = False, host_bit: bool = True): 

99 """Returns if a given value is a valid IPv6 address. 

100 

101 Including IPv4-mapped IPv6 addresses. The initial version of ipv6 validator 

102 was inspired from [WTForms IPAddress validator][1]. 

103 

104 [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py 

105 

106 Examples: 

107 >>> ipv6('::ffff:192.0.2.128') 

108 True 

109 >>> ipv6('::1/128') 

110 True 

111 >>> ipv6('abc.0.0.1') 

112 ValidationError(func=ipv6, args={'value': 'abc.0.0.1'}) 

113 

114 Args: 

115 value: 

116 IP address string to validate. 

117 cidr: 

118 IP address string may contain CIDR annotation. 

119 strict: 

120 IP address string is strictly in CIDR notation. 

121 host_bit: 

122 If `False` and host bits (along with network bits) _are_ set in the supplied 

123 address, this function raises a validation error. ref [IPv6Network][2]. 

124 [2]: https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv6Network 

125 

126 Returns: 

127 (Literal[True]): If `value` is a valid IPv6 address. 

128 (ValidationError): If `value` is an invalid IPv6 address. 

129 """ 

130 if not value: 

131 return False 

132 try: 

133 if cidr: 

134 if strict and value.count("/") != 1: 

135 raise ValueError("IPv6 address was expected in CIDR notation") 

136 return IPv6Network(value, strict=not host_bit) 

137 return IPv6Address(value) 

138 except (ValueError, AddressValueError, NetmaskValueError): 

139 return False