@@ -815,9 +815,9 @@ class URL(object):
815815 that starts with a slash.
816816 userinfo (Text): The username or colon-separated
817817 username:password pair.
818- uses_netloc (bool): Indicates whether two slashes appear
819- between the scheme and the host (``http://eg.com`` vs
820- ``mailto:e@g.com``). Set automatically based on scheme.
818+ uses_netloc (bool): Indicates whether ``://`` will appear to separate
819+ the scheme from the path, even in cases where no host is present.
820+ May be implied by scheme, or set explictly .
821821
822822 All of these parts are also exposed as read-only attributes of
823823 URL instances, along with several useful methods.
@@ -882,15 +882,28 @@ def __init__(
882882 self ._rooted = _typecheck ("rooted" , rooted , bool )
883883 self ._userinfo = _textcheck ("userinfo" , userinfo , '/?#@' )
884884
885- uses_netloc = scheme_uses_netloc (self ._scheme , uses_netloc )
885+ if uses_netloc is None :
886+ uses_netloc = scheme_uses_netloc (self ._scheme , uses_netloc )
886887 self ._uses_netloc = _typecheck ("uses_netloc" ,
887888 uses_netloc , bool , NoneType )
888- # fixup for rooted consistency
889- if self ._host :
889+ will_have_authority = (
890+ self ._host or
891+ (self ._port and self ._port != SCHEME_PORT_MAP .get (scheme ))
892+ )
893+ if will_have_authority :
894+ # fixup for rooted consistency; if there's any 'authority'
895+ # represented in the textual URL, then the path must be rooted, and
896+ # we're definitely using a netloc (there must be a ://).
890897 self ._rooted = True
891- if (not self ._rooted ) and self ._path and self ._path [0 ] == '' :
898+ self ._uses_netloc = True
899+ if (not self ._rooted ) and self .path [:1 ] == (u'' ,):
892900 self ._rooted = True
893901 self ._path = self ._path [1 :]
902+ if not will_have_authority and self ._path and not self ._rooted :
903+ # If, after fixing up the path, there *is* a path and it *isn't*
904+ # rooted, then we are definitely not using a netloc; if we did, it
905+ # would make the path (erroneously) look like a hostname.
906+ self ._uses_netloc = False
894907
895908 def get_decoded_url (self , lazy = False ):
896909 # type: (bool) -> DecodedURL
@@ -1006,6 +1019,8 @@ def userinfo(self):
10061019 def uses_netloc (self ):
10071020 # type: () -> Optional[bool]
10081021 """
1022+ Whether the textual URL representation will contain a ``://`` netloc
1023+ separator.
10091024 """
10101025 return self ._uses_netloc
10111026
@@ -1134,14 +1149,17 @@ def replace(
11341149 slash.
11351150 userinfo (Text): The username or colon-separated username:password
11361151 pair.
1137- uses_netloc (bool): Indicates whether two slashes appear between
1138- the scheme and the host
1139- (``http://eg.com`` vs ``mailto:e@g.com``)
1152+ uses_netloc (bool): Indicates whether rooted paths should include a
1153+ scheme-separator by default.
11401154
11411155 Returns:
11421156 URL: A copy of the current :class:`URL`, with new values for
11431157 parameters passed.
11441158 """
1159+ if scheme is not _UNSET and scheme != self .scheme :
1160+ # when changing schemes, reset the explicit uses_netloc preference
1161+ # to honor the new scheme.
1162+ uses_netloc = None
11451163 return self .__class__ (
11461164 scheme = _optional (scheme , self .scheme ),
11471165 host = _optional (host , self .host ),
0 commit comments