@@ -24,32 +24,37 @@ def domain(value: str, /, *, rfc_1034: bool = False, rfc_2782: bool = False):
24
24
value:
25
25
Domain string to validate.
26
26
rfc_1034:
27
- Allow trailing dot in domain name.
27
+ Allows optional trailing dot in the domain name.
28
28
Ref: [RFC 1034](https://www.rfc-editor.org/rfc/rfc1034).
29
29
rfc_2782:
30
30
Domain name is of type service record.
31
+ Allows optional underscores in the domain name.
31
32
Ref: [RFC 2782](https://www.rfc-editor.org/rfc/rfc2782).
32
33
33
34
34
35
Returns:
35
36
(Literal[True]): If `value` is a valid domain name.
36
37
(ValidationError): If `value` is an invalid domain name.
38
+
39
+ Raises:
40
+ (UnicodeError): If `value` cannot be encoded into `idna` or decoded into `utf-8`.
37
41
"""
38
42
if not value :
39
43
return False
40
44
try :
41
45
return not re .search (r"\s" , value ) and re .match (
42
46
# First character of the domain
43
- rf"^(?:[a-zA-Z0-9{ '_' if rfc_2782 else '' } ]"
44
- # Sub domain + hostname
45
- + rf"(?:[a-zA-Z0-9-{ '_' if rfc_2782 else '' } ]{{0,61}}"
46
- + rf"[A-Za-z0-9{ '_' if rfc_2782 else '' } ])?\.)"
47
+ rf"^(?:[a-z0-9{ r'_?' if rfc_2782 else '' } ]"
48
+ # Sub-domain
49
+ + rf"(?:[a-z0-9-{ r'_?' if rfc_2782 else '' } ]{{0,61}}"
50
+ # Hostname
51
+ + rf"[a-z0-9{ r'_?' if rfc_2782 else '' } ])?\.)"
47
52
# First 61 characters of the gTLD
48
- + r"+[A-Za- z0-9][A-Za -z0-9-_]{0,61}"
53
+ + r"+[a- z0-9][a -z0-9-_]{0,61}"
49
54
# Last character of the gTLD
50
- + rf"[A-Za- z]{ r'.$' if rfc_1034 else r'$' } " ,
55
+ + rf"[a- z]{ r'.? $' if rfc_1034 else r'$' } " ,
51
56
value .encode ("idna" ).decode ("utf-8" ),
52
57
re .IGNORECASE ,
53
58
)
54
- except UnicodeError :
55
- return False
59
+ except UnicodeError as err :
60
+ raise UnicodeError ( f"Unable to encode/decode { value } " ) from err
0 commit comments