@@ -24,32 +24,37 @@ def domain(value: str, /, *, rfc_1034: bool = False, rfc_2782: bool = False):
2424 value:
2525 Domain string to validate.
2626 rfc_1034:
27- Allow trailing dot in domain name.
27+ Allows optional trailing dot in the domain name.
2828 Ref: [RFC 1034](https://www.rfc-editor.org/rfc/rfc1034).
2929 rfc_2782:
3030 Domain name is of type service record.
31+ Allows optional underscores in the domain name.
3132 Ref: [RFC 2782](https://www.rfc-editor.org/rfc/rfc2782).
3233
3334
3435 Returns:
3536 (Literal[True]): If `value` is a valid domain name.
3637 (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`.
3741 """
3842 if not value :
3943 return False
4044 try :
4145 return not re .search (r"\s" , value ) and re .match (
4246 # 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 '' } ])?\.)"
4752 # 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}"
4954 # 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'$' } " ,
5156 value .encode ("idna" ).decode ("utf-8" ),
5257 re .IGNORECASE ,
5358 )
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