9
9
IPv6Network ,
10
10
NetmaskValueError ,
11
11
)
12
+ import re
13
+ from typing import Optional
12
14
13
15
# local
14
16
from .utils import validator
15
17
16
18
19
+ def _check_private_ip (value : str , is_private : Optional [bool ]):
20
+ if is_private is None :
21
+ return True
22
+ if is_private and (
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 True
37
+ return False
38
+
39
+
17
40
@validator
18
- def ipv4 (value : str , / , * , cidr : bool = True , strict : bool = False , host_bit : bool = True ):
41
+ def ipv4 (
42
+ value : str ,
43
+ / ,
44
+ * ,
45
+ cidr : bool = True ,
46
+ strict : bool = False ,
47
+ private : Optional [bool ] = None ,
48
+ host_bit : bool = True ,
49
+ ):
19
50
"""Returns whether a given value is a valid IPv4 address.
20
51
21
52
From Python version 3.9.5 leading zeros are no longer tolerated
@@ -36,9 +67,11 @@ def ipv4(value: str, /, *, cidr: bool = True, strict: bool = False, host_bit: bo
36
67
value:
37
68
IP address string to validate.
38
69
cidr:
39
- IP address string may contain CIDR notation
70
+ IP address string may contain CIDR notation.
40
71
strict:
41
- IP address string is strictly in CIDR notation
72
+ IP address string is strictly in CIDR notation.
73
+ private:
74
+ IP address is public if `False`, private/local/loopback/broadcast if `True`.
42
75
host_bit:
43
76
If `False` and host bits (along with network bits) _are_ set in the supplied
44
77
address, this function raises a validation error. ref [IPv4Network][2].
@@ -54,8 +87,8 @@ def ipv4(value: str, /, *, cidr: bool = True, strict: bool = False, host_bit: bo
54
87
if cidr :
55
88
if strict and value .count ("/" ) != 1 :
56
89
raise ValueError ("IPv4 address was expected in CIDR notation" )
57
- return IPv4Network (value , strict = not host_bit )
58
- return IPv4Address (value )
90
+ return IPv4Network (value , strict = not host_bit ) and _check_private_ip ( value , private )
91
+ return IPv4Address (value ) and _check_private_ip ( value , private )
59
92
except (ValueError , AddressValueError , NetmaskValueError ):
60
93
return False
61
94
@@ -81,9 +114,9 @@ def ipv6(value: str, /, *, cidr: bool = True, strict: bool = False, host_bit: bo
81
114
value:
82
115
IP address string to validate.
83
116
cidr:
84
- IP address string may contain CIDR annotation
117
+ IP address string may contain CIDR annotation.
85
118
strict:
86
- IP address string is strictly in CIDR notation
119
+ IP address string is strictly in CIDR notation.
87
120
host_bit:
88
121
If `False` and host bits (along with network bits) _are_ set in the supplied
89
122
address, this function raises a validation error. ref [IPv6Network][2].
0 commit comments