forked from python-hyper/hyperlink
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* master: [requires.io] dependency update [requires.io] dependency update Spiff up the tox config a bit more There is no requirements-test.txt file in the source tree. Archor a few paths to the root of the source tree. Minor re-ordering. per CR: rephrase gibberish test docstring per CR: add https:/, enumerate the cases per CR: match __init__ match __init__ doc per CR: explain in much more detail <79 per CR: make the test a little more thorough, improve docstring fix up inconsistencies in parsing & textual representation of 'rooted' and 'uses_netloc' # Conflicts: # .gitignore # MANIFEST.in # tox.ini
- Loading branch information
Showing
5 changed files
with
127 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -815,9 +815,18 @@ class URL(object): | |
that starts with a slash. | ||
userinfo (Text): The username or colon-separated | ||
username:password pair. | ||
uses_netloc (bool): Indicates whether two slashes appear | ||
between the scheme and the host (``http://eg.com`` vs | ||
``mailto:[email protected]``). Set automatically based on scheme. | ||
uses_netloc (Optional[bool]): Indicates whether ``://`` (the "netloc | ||
separator") will appear to separate the scheme from the *path* in | ||
cases where no host is present. Setting this to ``True`` is a | ||
non-spec-compliant affordance for the common practice of having URIs | ||
that are *not* URLs (cannot have a 'host' part) but nevertheless use | ||
the common ``://`` idiom that most people associate with URLs; | ||
e.g. ``message:`` URIs like ``message://message-id`` being | ||
equivalent to ``message:message-id``. This may be inferred based on | ||
the scheme depending on whether :func:`register_scheme` has been | ||
used to register the scheme and should not be passed directly unless | ||
you know the scheme works like this and you know it has not been | ||
registered. | ||
All of these parts are also exposed as read-only attributes of | ||
URL instances, along with several useful methods. | ||
|
@@ -882,15 +891,28 @@ def __init__( | |
self._rooted = _typecheck("rooted", rooted, bool) | ||
self._userinfo = _textcheck("userinfo", userinfo, '/?#@') | ||
|
||
uses_netloc = scheme_uses_netloc(self._scheme, uses_netloc) | ||
if uses_netloc is None: | ||
uses_netloc = scheme_uses_netloc(self._scheme, uses_netloc) | ||
self._uses_netloc = _typecheck("uses_netloc", | ||
uses_netloc, bool, NoneType) | ||
# fixup for rooted consistency | ||
if self._host: | ||
will_have_authority = ( | ||
self._host or | ||
(self._port and self._port != SCHEME_PORT_MAP.get(scheme)) | ||
) | ||
if will_have_authority: | ||
# fixup for rooted consistency; if there's any 'authority' | ||
# represented in the textual URL, then the path must be rooted, and | ||
# we're definitely using a netloc (there must be a ://). | ||
self._rooted = True | ||
if (not self._rooted) and self._path and self._path[0] == '': | ||
self._uses_netloc = True | ||
if (not self._rooted) and self.path[:1] == (u'',): | ||
self._rooted = True | ||
self._path = self._path[1:] | ||
if not will_have_authority and self._path and not self._rooted: | ||
# If, after fixing up the path, there *is* a path and it *isn't* | ||
# rooted, then we are definitely not using a netloc; if we did, it | ||
# would make the path (erroneously) look like a hostname. | ||
self._uses_netloc = False | ||
|
||
def get_decoded_url(self, lazy=False): | ||
# type: (bool) -> DecodedURL | ||
|
@@ -1006,6 +1028,8 @@ def userinfo(self): | |
def uses_netloc(self): | ||
# type: () -> Optional[bool] | ||
""" | ||
Indicates whether ``://`` (the "netloc separator") will appear to | ||
separate the scheme from the *path* in cases where no host is present. | ||
""" | ||
return self._uses_netloc | ||
|
||
|
@@ -1134,14 +1158,28 @@ def replace( | |
slash. | ||
userinfo (Text): The username or colon-separated username:password | ||
pair. | ||
uses_netloc (bool): Indicates whether two slashes appear between | ||
the scheme and the host | ||
(``http://eg.com`` vs ``mailto:[email protected]``) | ||
uses_netloc (bool): Indicates whether ``://`` (the "netloc | ||
separator") will appear to separate the scheme from the *path* | ||
in cases where no host is present. Setting this to ``True`` is | ||
a non-spec-compliant affordance for the common practice of | ||
having URIs that are *not* URLs (cannot have a 'host' part) but | ||
nevertheless use the common ``://`` idiom that most people | ||
associate with URLs; e.g. ``message:`` URIs like | ||
``message://message-id`` being equivalent to | ||
``message:message-id``. This may be inferred based on the | ||
scheme depending on whether :func:`register_scheme` has been | ||
used to register the scheme and should not be passed directly | ||
unless you know the scheme works like this and you know it has | ||
not been registered. | ||
Returns: | ||
URL: A copy of the current :class:`URL`, with new values for | ||
parameters passed. | ||
""" | ||
if scheme is not _UNSET and scheme != self.scheme: | ||
# when changing schemes, reset the explicit uses_netloc preference | ||
# to honor the new scheme. | ||
uses_netloc = None | ||
return self.__class__( | ||
scheme=_optional(scheme, self.scheme), | ||
host=_optional(host, self.host), | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -817,6 +817,18 @@ def test_mailto(self): | |
self.assertEqual(URL.from_text(u"mailto:[email protected]").to_text(), | ||
u"mailto:[email protected]") | ||
|
||
def test_httpWithoutHost(self): | ||
# type: () -> None | ||
""" | ||
An HTTP URL without a hostname, but with a path, should also round-trip | ||
cleanly. | ||
""" | ||
without_host = URL.from_text(u"http:relative-path") | ||
self.assertEqual(without_host.host, u'') | ||
self.assertEqual(without_host.path, (u'relative-path',)) | ||
self.assertEqual(without_host.uses_netloc, False) | ||
self.assertEqual(without_host.to_text(), u"http:relative-path") | ||
|
||
def test_queryIterable(self): | ||
# type: () -> None | ||
""" | ||
|
@@ -938,15 +950,29 @@ def test_netloc(self): | |
# type: () -> None | ||
url = URL(scheme='https') | ||
self.assertEqual(url.uses_netloc, True) | ||
self.assertEqual(url.to_text(), u'https://') | ||
# scheme, no host, no path, no netloc hack | ||
self.assertEqual(URL.from_text('https:').uses_netloc, False) | ||
# scheme, no host, absolute path, no netloc hack | ||
self.assertEqual(URL.from_text('https:/').uses_netloc, False) | ||
# scheme, no host, no path, netloc hack to indicate :// syntax | ||
self.assertEqual(URL.from_text('https://').uses_netloc, True) | ||
|
||
url = URL(scheme='https', uses_netloc=False) | ||
self.assertEqual(url.uses_netloc, False) | ||
self.assertEqual(url.to_text(), u'https:') | ||
|
||
url = URL(scheme='git+https') | ||
self.assertEqual(url.uses_netloc, True) | ||
self.assertEqual(url.to_text(), u'git+https://') | ||
|
||
url = URL(scheme='mailto') | ||
self.assertEqual(url.uses_netloc, False) | ||
self.assertEqual(url.to_text(), u'mailto:') | ||
|
||
url = URL(scheme='ztp') | ||
self.assertEqual(url.uses_netloc, None) | ||
self.assertEqual(url.to_text(), u'ztp:') | ||
|
||
url = URL.from_text('ztp://test.com') | ||
self.assertEqual(url.uses_netloc, True) | ||
|
@@ -1116,6 +1142,34 @@ def test_autorooted(self): | |
self.assertEqual(normal_absolute.rooted, True) | ||
self.assertEqual(attempt_unrooted_absolute.rooted, True) | ||
|
||
def test_rooted_with_port_but_no_host(self): | ||
# type: () -> None | ||
""" | ||
URLs which include a ``://`` netloc-separator for any reason are | ||
inherently rooted, regardless of the value or presence of the | ||
``rooted`` constructor argument. | ||
They may include a netloc-separator because their constructor was | ||
directly invoked with an explicit host or port, or because they were | ||
parsed from a string which included the literal ``://`` separator. | ||
""" | ||
directly_constructed = URL(scheme='udp', port=4900, rooted=False) | ||
directly_constructed_implict = URL(scheme='udp', port=4900) | ||
directly_constructed_rooted = URL(scheme=u'udp', port=4900, | ||
rooted=True) | ||
self.assertEqual(directly_constructed.rooted, True) | ||
self.assertEqual(directly_constructed_implict.rooted, True) | ||
self.assertEqual(directly_constructed_rooted.rooted, True) | ||
parsed = URL.from_text('udp://:4900') | ||
self.assertEqual(str(directly_constructed), str(parsed)) | ||
self.assertEqual(str(directly_constructed_implict), str(parsed)) | ||
self.assertEqual(directly_constructed.asText(), parsed.asText()) | ||
self.assertEqual(directly_constructed, parsed) | ||
self.assertEqual(directly_constructed, directly_constructed_implict) | ||
self.assertEqual(directly_constructed, directly_constructed_rooted) | ||
self.assertEqual(directly_constructed_implict, parsed) | ||
self.assertEqual(directly_constructed_rooted, parsed) | ||
|
||
def test_wrong_constructor(self): | ||
# type: () -> None | ||
with self.assertRaises(ValueError): | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters