3
3
4
4
Usage is straightforward::
5
5
6
- >>> from hyperlink import URL
7
- >>> url = URL.from_text (u'http://github.com/mahmoud/hyperlink?utm_source=docs')
6
+ >>> import hyperlink
7
+ >>> url = hyperlink.parse (u'http://github.com/mahmoud/hyperlink?utm_source=docs')
8
8
>>> url.host
9
9
u'github.com'
10
10
>>> secure_url = url.replace(scheme=u'https')
11
11
>>> secure_url.get('utm_source')[0]
12
12
u'docs'
13
13
14
- As seen here, the API revolves around the lightweight and immutable
15
- :class:`URL` type, documented below.
14
+ Hyperlink's API centers on the :class:`DecodedURL` type, which wraps
15
+ the lower-level :class:`URL`, both of which can be returned by the
16
+ :func:`parse()` convenience function.
17
+
16
18
""" # noqa: E501
17
19
18
20
import re
@@ -1743,13 +1745,23 @@ def remove(
1743
1745
1744
1746
EncodedURL = URL # An alias better describing what the URL really is
1745
1747
1748
+ _EMPTY_URL = URL ()
1746
1749
1747
1750
class DecodedURL (object ):
1748
- """DecodedURL is a type meant to act as a higher-level interface to
1749
- the URL. It is the `unicode` to URL's `bytes`. `DecodedURL` has
1750
- almost exactly the same API as `URL`, but everything going in and
1751
- out is in its maximally decoded state. All percent decoding is
1752
- handled automatically.
1751
+ """:class:`DecodedURL` is a type designed to act as a higher-level
1752
+ interface to :class:`URL` and the recommended type for most
1753
+ operations. By analogy, :class:`DecodedURL` is the
1754
+ :class:`unicode` to URL's :class:`bytes`.
1755
+
1756
+ :class:`DecodedURL` automatically handles encoding and decoding
1757
+ all its components, such that all inputs and outputs are in a
1758
+ maximally-decoded state. Note that this means, for some special
1759
+ cases, a URL may not "roundtrip" character-for-character, but this
1760
+ is considered a good tradeoff for the safety of automatic
1761
+ encoding.
1762
+
1763
+ Otherwise, :class:`DecodedURL` has almost exactly the same API as
1764
+ :class:`URL`.
1753
1765
1754
1766
Where applicable, a UTF-8 encoding is presumed. Be advised that
1755
1767
some interactions can raise :exc:`UnicodeEncodeErrors` and
@@ -1763,8 +1775,18 @@ class DecodedURL(object):
1763
1775
lazy (bool): Set to True to avoid pre-decode all parts of the URL to
1764
1776
check for validity. Defaults to False.
1765
1777
1778
+ .. note::
1779
+
1780
+ The :class:`DecodedURL` initializer takes a :class:`URL` object,
1781
+ not URL components, like :class:`URL`. To programmatically
1782
+ construct a :class:`DecodedURL`, you can use this pattern:
1783
+
1784
+ >>> DecodedURL().replace(host='pypi.org', path=('projects', 'hyperlink').to_text()
1785
+ "http://pypi.org/projects/hyperlink"
1786
+
1787
+
1766
1788
"""
1767
- def __init__ (self , url , lazy = False ):
1789
+ def __init__ (self , url = _EMPTY_URL , lazy = False ):
1768
1790
# type: (URL, bool) -> None
1769
1791
self ._url = url
1770
1792
if not lazy :
@@ -2098,7 +2120,7 @@ def parse(url, decoded=True, lazy=False):
2098
2120
decoded (bool): Whether or not to return a :class:`DecodedURL`,
2099
2121
which automatically handles all
2100
2122
encoding/decoding/quoting/unquoting for all the various
2101
- accessors of parts of the URL, or an :class:`EncodedURL `,
2123
+ accessors of parts of the URL, or a :class:`URL `,
2102
2124
which has the same API, but requires handling of special
2103
2125
characters for different parts of the URL.
2104
2126
0 commit comments