@@ -38,7 +38,14 @@ def _validate_scheme(value: str):
3838 """Validate scheme."""
3939 # More schemes will be considered later.
4040 return (
41- value in {"ftp" , "ftps" , "git" , "http" , "https" , "rtsp" , "sftp" , "ssh" , "telnet" }
41+ value
42+ # fmt: off
43+ in {
44+ "ftp" , "ftps" , "git" , "http" , "https" ,
45+ "rtmp" , "rtmps" , "rtsp" , "sftp" ,
46+ "ssh" , "telnet" ,
47+ }
48+ # fmt: on
4249 if value
4350 else False
4451 )
@@ -112,8 +119,18 @@ def _validate_optionals(path: str, query: str, fragment: str, strict_query: bool
112119 optional_segments = True
113120 if path :
114121 optional_segments &= bool (_path_regex ().match (path ))
115- if query and parse_qs (query , strict_parsing = strict_query ):
116- optional_segments &= True
122+ try :
123+ if (
124+ query
125+ # ref: https://github.com/python/cpython/issues/117109
126+ and parse_qs (query , strict_parsing = strict_query , separator = "&" )
127+ and parse_qs (query , strict_parsing = strict_query , separator = ";" )
128+ ):
129+ optional_segments &= True
130+ except TypeError :
131+ # for Python < v3.9.2 (official v3.10)
132+ if query and parse_qs (query , strict_parsing = strict_query ):
133+ optional_segments &= True
117134 if fragment :
118135 # See RFC3986 Section 3.5 Fragment for allowed characters
119136 optional_segments &= bool (re .fullmatch (r"[0-9a-zA-Z?/:@\-._~%!$&'()*+,;=]*" , fragment ))
0 commit comments