Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-hyperlink for 
openSUSE:Factory checked in at 2021-03-16 15:42:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-hyperlink (Old)
 and      /work/SRC/openSUSE:Factory/.python-hyperlink.new.2401 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-hyperlink"

Tue Mar 16 15:42:19 2021 rev:5 rq:878749 version:21.0.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-hyperlink/python-hyperlink.changes        
2020-10-25 18:09:11.079490914 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-hyperlink.new.2401/python-hyperlink.changes  
    2021-03-16 15:43:36.868961333 +0100
@@ -1,0 +2,9 @@
+Sat Mar 13 13:07:05 UTC 2021 - Dirk M??ller <dmuel...@suse.com>
+
+- update to 21.0.0:
+  * Update plus sign (+) handling to work with/like HTML form encoding (POST)
+    by default, fixes #129, and associated roundtripping (#146).
+  * Package IDNA tables.
+  * Long overdue dependency bumps
+
+-------------------------------------------------------------------

Old:
----
  hyperlink-20.0.1.tar.gz

New:
----
  hyperlink-21.0.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-hyperlink.spec ++++++
--- /var/tmp/diff_new_pack.5weBmg/_old  2021-03-16 15:43:37.308962037 +0100
+++ /var/tmp/diff_new_pack.5weBmg/_new  2021-03-16 15:43:37.308962037 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-hyperlink
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-hyperlink
-Version:        20.0.1
+Version:        21.0.0
 Release:        0
 Summary:        Immutable URL support for Python
 License:        MIT

++++++ hyperlink-20.0.1.tar.gz -> hyperlink-21.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperlink-20.0.1/CHANGELOG.md 
new/hyperlink-21.0.0/CHANGELOG.md
--- old/hyperlink-20.0.1/CHANGELOG.md   2020-08-04 08:34:08.000000000 +0200
+++ new/hyperlink-21.0.0/CHANGELOG.md   2020-08-05 05:36:26.000000000 +0200
@@ -1,5 +1,13 @@
 # Hyperlink Changelog
 
+## 20.0.1
+
+*(August 4, 2020)*
+
+Rerelease to fix packaging metadata around conditional requirements.
+See [issue #133](https://github.com/python-hyper/hyperlink/issues/133)
+for more details.
+
 ## 20.0.0
 
 *(August 3, 2020)*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperlink-20.0.1/PKG-INFO 
new/hyperlink-21.0.0/PKG-INFO
--- old/hyperlink-20.0.1/PKG-INFO       2020-08-05 05:34:31.000000000 +0200
+++ new/hyperlink-21.0.0/PKG-INFO       2021-01-08 06:51:20.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: hyperlink
-Version: 20.0.1
+Version: 21.0.0
 Summary: A featureful, immutable, and correct URL for Python.
 Home-page: https://github.com/python-hyper/hyperlink
 Author: Mahmoud Hashemi and Glyph Lefkowitz
@@ -28,6 +28,7 @@
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: License :: OSI Approved :: MIT License
 Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperlink-20.0.1/docs/conf.py 
new/hyperlink-21.0.0/docs/conf.py
--- old/hyperlink-20.0.1/docs/conf.py   2020-08-04 08:36:18.000000000 +0200
+++ new/hyperlink-21.0.0/docs/conf.py   2020-08-05 05:34:50.000000000 +0200
@@ -65,7 +65,7 @@
 author = u'Mahmoud Hashemi'
 
 version = '20.0'
-release = '20.0.0'
+release = '20.0.1'
 
 if os.name != 'nt':
     today_fmt = '%B %d, %Y'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperlink-20.0.1/setup.py 
new/hyperlink-21.0.0/setup.py
--- old/hyperlink-20.0.1/setup.py       2020-08-05 05:33:04.000000000 +0200
+++ new/hyperlink-21.0.0/setup.py       2021-01-08 06:47:35.000000000 +0100
@@ -11,7 +11,7 @@
 
 
 __author__ = "Mahmoud Hashemi and Glyph Lefkowitz"
-__version__ = "20.0.1"
+__version__ = "21.0.0"
 __contact__ = "mahm...@hatnote.com"
 __url__ = "https://github.com/python-hyper/hyperlink";
 __license__ = "MIT"
@@ -27,7 +27,7 @@
     url=__url__,
     packages=find_packages(where="src"),
     package_dir={"": "src"},
-    package_data=dict(hyperlink=["py.typed"]),
+    package_data=dict(hyperlink=["py.typed", "idna-tables-properties.csv.gz"]),
     zip_safe=False,
     license=__license__,
     platforms="any",
@@ -47,6 +47,7 @@
         "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
+        "Programming Language :: Python :: 3.9",
         "Programming Language :: Python :: Implementation :: PyPy",
         "License :: OSI Approved :: MIT License",
     ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperlink-20.0.1/src/hyperlink/_url.py 
new/hyperlink-21.0.0/src/hyperlink/_url.py
--- old/hyperlink-20.0.1/src/hyperlink/_url.py  2020-08-04 08:14:29.000000000 
+0200
+++ new/hyperlink-21.0.0/src/hyperlink/_url.py  2021-01-08 06:36:07.000000000 
+0100
@@ -183,7 +183,7 @@
 _SCHEMELESS_PATH_DELIMS = _ALL_DELIMS - _SCHEMELESS_PATH_SAFE
 _FRAGMENT_SAFE = _UNRESERVED_CHARS | _PATH_SAFE | set(u"/?")
 _FRAGMENT_DELIMS = _ALL_DELIMS - _FRAGMENT_SAFE
-_QUERY_VALUE_SAFE = _UNRESERVED_CHARS | _FRAGMENT_SAFE - set(u"&+")
+_QUERY_VALUE_SAFE = _UNRESERVED_CHARS | _FRAGMENT_SAFE - set(u"&")
 _QUERY_VALUE_DELIMS = _ALL_DELIMS - _QUERY_VALUE_SAFE
 _QUERY_KEY_SAFE = _UNRESERVED_CHARS | _QUERY_VALUE_SAFE - set(u"=")
 _QUERY_KEY_DELIMS = _ALL_DELIMS - _QUERY_KEY_SAFE
@@ -467,9 +467,13 @@
 )
 # As of Mar 11, 2017, there were 44 netloc schemes, and 13 non-netloc
 
+NO_QUERY_PLUS_SCHEMES = set()
 
-def register_scheme(text, uses_netloc=True, default_port=None):
-    # type: (Text, bool, Optional[int]) -> None
+
+def register_scheme(
+    text, uses_netloc=True, default_port=None, query_plus_is_space=True
+):
+    # type: (Text, bool, Optional[int], bool) -> None
     """Registers new scheme information, resulting in correct port and
     slash behavior from the URL object. There are dozens of standard
     schemes preregistered, so this function is mostly meant for
@@ -478,13 +482,15 @@
     `file an issue`_!
 
     Args:
-        text (Text): A string representation of the scheme.
+        text: A string representation of the scheme.
             (the 'http' in 'http://hatnote.com')
-        uses_netloc (bool): Does the scheme support specifying a
+        uses_netloc: Does the scheme support specifying a
             network host? For instance, "http" does, "mailto" does
             not. Defaults to True.
-        default_port (Optional[int]): The default port, if any, for
+        default_port: The default port, if any, for
             netloc-using schemes.
+        query_plus_is_space: If true, a "+" in the query string should be
+            decoded as a space by DecodedURL.
 
     .. _file an issue: https://github.com/mahmoud/hyperlink/issues
     """
@@ -510,6 +516,9 @@
     else:
         raise ValueError("uses_netloc expected bool, not: %r" % uses_netloc)
 
+    if not query_plus_is_space:
+        NO_QUERY_PLUS_SCHEMES.add(text)
+
     return
 
 
@@ -922,43 +931,41 @@
         https://example.com/hello/world
 
     The constructor runs basic type checks. All strings are expected
-    to be decoded (:class:`unicode` in Python 2). All arguments are
-    optional, defaulting to appropriately empty values. A full list of
-    constructor arguments is below.
+    to be text (:class:`str` in Python 3, :class:`unicode` in Python 2). All
+    arguments are optional, defaulting to appropriately empty values. A full
+    list of constructor arguments is below.
 
     Args:
-       scheme (Optional[Text]): The text name of the scheme.
-       host (Optional[Text]): The host portion of the network location
-       port (Optional[int]): The port part of the network location. If
-          ``None`` or no port is passed, the port will default to
-          the default port of the scheme, if it is known. See the
-          ``SCHEME_PORT_MAP`` and :func:`register_default_port`
-          for more info.
-       path (Iterable[Text]): A tuple of strings representing the
-          slash-separated parts of the path.
-       query (Sequence[Tuple[Text, Optional[Text]]]): The query parameters, as
-           a dictionary or as an sequence of key-value pairs.
-       fragment (Text): The fragment part of the URL.
-       rooted (bool): A rooted URL is one which indicates an absolute path.
-          This is True on any URL that includes a host, or any relative URL
-          that starts with a slash.
-       userinfo (Text): The username or colon-separated
-          username:password pair.
-       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.
+        scheme: The text name of the scheme.
+        host: The host portion of the network location
+        port: The port part of the network location. If ``None`` or no port is
+            passed, the port will default to the default port of the scheme, if
+            it is known. See the ``SCHEME_PORT_MAP`` and
+            :func:`register_default_port` for more info.
+        path: A tuple of strings representing the slash-separated parts of the
+            path, each percent-encoded.
+        query: The query parameters, as a dictionary or as an sequence of
+            percent-encoded key-value pairs.
+        fragment: The fragment part of the URL.
+        rooted: A rooted URL is one which indicates an absolute path.
+            This is True on any URL that includes a host, or any relative URL
+            that starts with a slash.
+        userinfo: The username or colon-separated username:password pair.
+        uses_netloc: 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.
+    All of these parts are also exposed as read-only attributes of :class:`URL`
+    instances, along with several useful methods.
 
     .. _RFC 3986: https://tools.ietf.org/html/rfc3986
     .. _RFC 3987: https://tools.ietf.org/html/rfc3987
@@ -1187,9 +1194,9 @@
         u'user:pass@localhost:8080'
 
         Args:
-            with_password (bool): Whether the return value of this
-                method include the password in the URL, if it is
-                set. Defaults to False.
+            with_password: Whether the return value of this method include the
+            password in the URL, if it is set.
+            Defaults to False.
 
         Returns:
             Text: The authority (network location and user information) portion
@@ -1298,32 +1305,29 @@
         the value on the current URL.
 
         Args:
-            scheme (Optional[Text]): The text name of the scheme.
-            host (Optional[Text]): The host portion of the network location.
-            path (Iterable[Text]): A tuple of strings representing the
-                slash-separated parts of the path.
-            query (Sequence[Tuple[Text, Optional[Text]]]): The query
-                parameters, as a dictionary or as an sequence of key-value
-                pairs.
-            fragment (Text): The fragment part of the URL.
-            port (Optional[int]): The port part of the network location.
-            rooted (Optional[bool]): Whether or not the path begins with a
-                slash.
-            userinfo (Text): The username or colon-separated username:password
-                pair.
-            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.
+            scheme: The text name of the scheme.
+            host: The host portion of the network location.
+            path: A tuple of strings representing the slash-separated parts of
+                the path.
+            query: The query parameters, as a dictionary or as an sequence of
+                key-value pairs.
+            fragment: The fragment part of the URL.
+            port: The port part of the network location.
+            rooted: Whether or not the path begins with a slash.
+            userinfo: The username or colon-separated username:password pair.
+            uses_netloc: 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
@@ -1363,7 +1367,7 @@
         sure to decode those bytestrings.
 
         Args:
-           text (Text): A valid URL string.
+           text: A valid URL string.
 
         Returns:
            URL: The structured object version of the parsed string.
@@ -1469,15 +1473,14 @@
         name.
 
         Args:
-            scheme (bool): Convert the scheme to lowercase
-            host (bool): Convert the host to lowercase
-            path (bool): Normalize the path (see above for details)
-            query (bool): Normalize the query string
-            fragment (bool): Normalize the fragment
-            userinfo (bool): Normalize the userinfo
-            percents (bool): Encode isolated percent signs for any
-                percent-encoded fields which are being normalized
-                (defaults to True).
+            scheme: Convert the scheme to lowercase
+            host: Convert the host to lowercase
+            path: Normalize the path (see above for details)
+            query: Normalize the query string
+            fragment: Normalize the fragment
+            userinfo: Normalize the userinfo
+            percents: Encode isolated percent signs for any percent-encoded
+                fields which are being normalized (defaults to `True`).
 
         >>> url = URL.from_text(u'Http://example.COM/a/../b/./c%2f?%61%')
         >>> print(url.normalize().to_text())
@@ -1537,9 +1540,9 @@
             u'http://localhost/a/b/c/d?x=y'
 
         Args:
-            segments (Text): Additional parts to be joined and added to
-                the path, like :func:`os.path.join`. Special characters
-                in segments will be percent encoded.
+            segments: Additional parts to be joined and added to the path, like
+            :func:`os.path.join`. Special characters in segments will be
+            percent encoded.
 
         Returns:
            URL: A copy of the current URL with the extra path segments.
@@ -1562,7 +1565,7 @@
         sibling of this URL path.
 
         Args:
-            segment (Text): A single path segment.
+            segment: A single path segment.
 
         Returns:
             URL: A copy of the current URL with the last path segment
@@ -1861,11 +1864,11 @@
             URL.from_text(u'https://example.com/?x=y&x=z')
 
         Args:
-            name (Text): The name of the query parameter to add.
+            name: The name of the query parameter to add.
                 The part before the ``=``.
-            value (Optional[Text]): The value of the query parameter to add.
-                The part after the ``=``. Defaults to ``None``, meaning no
-                value.
+            value: The value of the query parameter to add.
+                The part after the ``=``.
+                Defaults to ``None``, meaning no value.
 
         Returns:
             URL: A new :class:`URL` instance with the parameter added.
@@ -1884,11 +1887,11 @@
             URL.from_text(u'https://example.com/?x=z')
 
         Args:
-            name (Text): The name of the query parameter to set.
+            name: The name of the query parameter to set.
                 The part before the ``=``.
-            value (Optional[Text]): The value of the query parameter to set.
-                The part after the ``=``. Defaults to ``None``, meaning no
-                value.
+            value: The value of the query parameter to set.
+                The part after the ``=``.
+                Defaults to ``None``, meaning no value.
 
         Returns:
             URL: A new :class:`URL` instance with the parameter set.
@@ -1915,7 +1918,7 @@
         list is always returned, and this method raises no exceptions.
 
         Args:
-            name (Text): The name of the query parameter to get.
+            name: The name of the query parameter to get.
 
         Returns:
             List[Optional[Text]]: A list of all the values associated with the
@@ -1936,12 +1939,11 @@
         parameter is not already set.
 
         Args:
-            name (Text): The name of the query parameter to remove.
-            value (Text): Optional value to additionally filter on.
+            name: The name of the query parameter to remove.
+            value: Optional value to additionally filter on.
                 Setting this removes query parameters which match both name
                 and value.
-            limit (Optional[int]): Optional maximum number of parameters to
-                remove.
+            limit: Optional maximum number of parameters to remove.
 
         Returns:
             URL: A new :class:`URL` instance with the parameter removed.
@@ -1976,6 +1978,16 @@
 _EMPTY_URL = URL()
 
 
+def _replace_plus(text):
+    # type: (Text) -> Text
+    return text.replace("+", "%20")
+
+
+def _no_op(text):
+    # type: (Text) -> Text
+    return text
+
+
 class DecodedURL(object):
     """
     :class:`DecodedURL` is a type designed to act as a higher-level
@@ -2001,9 +2013,13 @@
     special characters encoded with codecs other than UTF-8.
 
     Args:
-        url (URL): A :class:`URL` object to wrap.
-        lazy (bool): Set to True to avoid pre-decode all parts of the URL to
-            check for validity. Defaults to False.
+        url: A :class:`URL` object to wrap.
+        lazy: Set to True to avoid pre-decode all parts of the URL to check for
+            validity.
+            Defaults to False.
+        query_plus_is_space: + characters in the query string should be treated
+            as spaces when decoding.  If unspecified, the default is taken from
+            the scheme.
 
     .. note::
 
@@ -2018,9 +2034,12 @@
     .. versionadded:: 18.0.0
     """
 
-    def __init__(self, url=_EMPTY_URL, lazy=False):
-        # type: (URL, bool) -> None
+    def __init__(self, url=_EMPTY_URL, lazy=False, query_plus_is_space=None):
+        # type: (URL, bool, Optional[bool]) -> None
         self._url = url
+        if query_plus_is_space is None:
+            query_plus_is_space = url.scheme not in NO_QUERY_PLUS_SCHEMES
+        self._query_plus_is_space = query_plus_is_space
         if not lazy:
             # cache the following, while triggering any decoding
             # issues with decodable fields
@@ -2028,18 +2047,19 @@
         return
 
     @classmethod
-    def from_text(cls, text, lazy=False):
-        # type: (Text, bool) -> DecodedURL
+    def from_text(cls, text, lazy=False, query_plus_is_space=None):
+        # type: (Text, bool, Optional[bool]) -> DecodedURL
         """\
         Make a `DecodedURL` instance from any text string containing a URL.
 
         Args:
-          text (Text): Text containing the URL
-          lazy (bool): Whether to pre-decode all parts of the URL to check for
-              validity. Defaults to True.
+          text: Text containing the URL
+          lazy: Whether to pre-decode all parts of the URL to check for
+              validity.
+              Defaults to True.
         """
         _url = URL.from_text(text)
-        return cls(_url, lazy=lazy)
+        return cls(_url, lazy=lazy, query_plus_is_space=query_plus_is_space)
 
     @property
     def encoded_url(self):
@@ -2064,6 +2084,14 @@
         "Passthrough to :meth:`~hyperlink.URL.to_iri()`"
         return self._url.to_iri()
 
+    def _clone(self, url):
+        # type: (URL) -> DecodedURL
+        return self.__class__(
+            url,
+            # TODO: propagate laziness?
+            query_plus_is_space=self._query_plus_is_space,
+        )
+
     def click(self, href=u""):
         # type: (Union[Text, URL, DecodedURL]) -> DecodedURL
         """Return a new DecodedURL wrapping the result of
@@ -2071,7 +2099,9 @@
         """
         if isinstance(href, DecodedURL):
             href = href._url
-        return self.__class__(self._url.click(href=href))
+        return self._clone(
+            self._url.click(href=href),
+        )
 
     def sibling(self, segment):
         # type: (Text) -> DecodedURL
@@ -2079,7 +2109,9 @@
         return a new `DecodedURL` wrapping the result of
         :meth:`~hyperlink.URL.sibling()`
         """
-        return self.__class__(self._url.sibling(_encode_reserved(segment)))
+        return self._clone(
+            self._url.sibling(_encode_reserved(segment)),
+        )
 
     def child(self, *segments):
         # type: (Text) -> DecodedURL
@@ -2090,7 +2122,7 @@
         if not segments:
             return self
         new_segs = [_encode_reserved(s) for s in segments]
-        return self.__class__(self._url.child(*new_segs))
+        return self._clone(self._url.child(*new_segs))
 
     def normalize(
         self,
@@ -2106,7 +2138,7 @@
         """Return a new `DecodedURL` wrapping the result of
         :meth:`~hyperlink.URL.normalize()`
         """
-        return self.__class__(
+        return self._clone(
             self._url.normalize(
                 scheme, host, path, query, fragment, userinfo, percents
             )
@@ -2153,11 +2185,18 @@
     def query(self):
         # type: () -> QueryPairs
         if not hasattr(self, "_query"):
+            if self._query_plus_is_space:
+                predecode = _replace_plus
+            else:
+                predecode = _no_op
+
             self._query = cast(
                 QueryPairs,
                 tuple(
                     tuple(
-                        _percent_decode(x, raise_subencoding_exc=True)
+                        _percent_decode(
+                            predecode(x), raise_subencoding_exc=True
+                        )
                         if x is not None
                         else None
                         for x in (k, v)
@@ -2253,7 +2292,7 @@
             userinfo=userinfo_text,
             uses_netloc=uses_netloc,
         )
-        return self.__class__(url=new_url)
+        return self._clone(url=new_url)
 
     def get(self, name):
         # type: (Text) -> List[Optional[Text]]
@@ -2386,16 +2425,16 @@
     https://github.com/python-hyper/hyperlink
 
     Args:
-        url (str): A text string representation of a URL.
+        url: A text string representation of a URL.
 
-        decoded (bool): Whether or not to return a :class:`DecodedURL`,
+        decoded: Whether or not to return a :class:`DecodedURL`,
             which automatically handles all
             encoding/decoding/quoting/unquoting for all the various
             accessors of parts of the URL, or a :class:`URL`,
             which has the same API, but requires handling of special
             characters for different parts of the URL.
 
-        lazy (bool): In the case of `decoded=True`, this controls
+        lazy: In the case of `decoded=True`, this controls
             whether the URL is decoded immediately or as accessed. The
             default, `lazy=False`, checks all encoded parts of the URL
             for decodability.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperlink-20.0.1/src/hyperlink/hypothesis.py 
new/hyperlink-21.0.0/src/hyperlink/hypothesis.py
--- old/hyperlink-20.0.1/src/hyperlink/hypothesis.py    2020-08-04 
08:14:29.000000000 +0200
+++ new/hyperlink-21.0.0/src/hyperlink/hypothesis.py    2021-01-08 
06:36:07.000000000 +0100
@@ -78,7 +78,8 @@
             )
             with open_gzip(dataFileName) as dataFile:
                 reader = csv_reader(
-                    (line.decode("utf-8") for line in dataFile), delimiter=",",
+                    (line.decode("utf-8") for line in dataFile),
+                    delimiter=",",
                 )
                 next(reader)  # Skip header row
                 for row in reader:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperlink-20.0.1/src/hyperlink/test/common.py 
new/hyperlink-21.0.0/src/hyperlink/test/common.py
--- old/hyperlink-20.0.1/src/hyperlink/test/common.py   2020-08-04 
08:14:29.000000000 +0200
+++ new/hyperlink-21.0.0/src/hyperlink/test/common.py   2021-01-08 
06:36:07.000000000 +0100
@@ -16,26 +16,26 @@
     ):
         # type: (...) -> Any
         """Fail unless an exception of class expected_exception is raised
-           by callableObj when invoked with arguments args and keyword
-           arguments kwargs. If a different type of exception is
-           raised, it will not be caught, and the test case will be
-           deemed to have suffered an error, exactly as for an
-           unexpected exception.
+        by callableObj when invoked with arguments args and keyword
+        arguments kwargs. If a different type of exception is
+        raised, it will not be caught, and the test case will be
+        deemed to have suffered an error, exactly as for an
+        unexpected exception.
 
-           If called with callableObj omitted or None, will return a
-           context object used like this::
+        If called with callableObj omitted or None, will return a
+        context object used like this::
 
-                with self.assertRaises(SomeException):
-                    do_something()
+             with self.assertRaises(SomeException):
+                 do_something()
 
-           The context manager keeps a reference to the exception as
-           the 'exception' attribute. This allows you to inspect the
-           exception after the assertion::
+        The context manager keeps a reference to the exception as
+        the 'exception' attribute. This allows you to inspect the
+        exception after the assertion::
 
-               with self.assertRaises(SomeException) as cm:
-                   do_something()
-               the_exception = cm.exception
-               self.assertEqual(the_exception.error_code, 3)
+            with self.assertRaises(SomeException) as cm:
+                do_something()
+            the_exception = cm.exception
+            self.assertEqual(the_exception.error_code, 3)
         """
         context = _AssertRaisesContext(expected_exception, self)
         if callableObj is None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperlink-20.0.1/src/hyperlink/test/test_common.py 
new/hyperlink-21.0.0/src/hyperlink/test/test_common.py
--- old/hyperlink-20.0.1/src/hyperlink/test/test_common.py      2020-08-04 
08:14:29.000000000 +0200
+++ new/hyperlink-21.0.0/src/hyperlink/test/test_common.py      2021-01-08 
06:36:07.000000000 +0100
@@ -7,15 +7,11 @@
 
 
 class _ExpectedException(Exception):
-    """An exception used to test HyperlinkTestCase.assertRaises.
-
-    """
+    """An exception used to test HyperlinkTestCase.assertRaises."""
 
 
 class _UnexpectedException(Exception):
-    """An exception used to test HyperlinkTestCase.assertRaises.
-
-    """
+    """An exception used to test HyperlinkTestCase.assertRaises."""
 
 
 class TestHyperlink(TestCase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hyperlink-20.0.1/src/hyperlink/test/test_decoded_url.py 
new/hyperlink-21.0.0/src/hyperlink/test/test_decoded_url.py
--- old/hyperlink-20.0.1/src/hyperlink/test/test_decoded_url.py 2020-08-04 
08:14:29.000000000 +0200
+++ new/hyperlink-21.0.0/src/hyperlink/test/test_decoded_url.py 2021-01-08 
06:36:07.000000000 +0100
@@ -210,3 +210,19 @@
         assert clicked.host == durl.host
         assert clicked.path == durl_dest.path
         assert clicked.path == ("t??st",)
+
+    def test_decode_plus(self):
+        # type: () -> None
+        durl = DecodedURL.from_text("/x+y%2B?a=b+c%2B")
+        assert durl.path == ("x+y+",)
+        assert durl.get("a") == ["b c+"]
+        assert durl.query == (("a", "b c+"),)
+
+    def test_decode_nonplussed(self):
+        # type: () -> None
+        durl = DecodedURL.from_text(
+            "/x+y%2B?a=b+c%2B", query_plus_is_space=False
+        )
+        assert durl.path == ("x+y+",)
+        assert durl.get("a") == ["b+c+"]
+        assert durl.query == (("a", "b+c+"),)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hyperlink-20.0.1/src/hyperlink/test/test_scheme_registration.py 
new/hyperlink-21.0.0/src/hyperlink/test/test_scheme_registration.py
--- old/hyperlink-20.0.1/src/hyperlink/test/test_scheme_registration.py 
2020-08-04 08:14:29.000000000 +0200
+++ new/hyperlink-21.0.0/src/hyperlink/test/test_scheme_registration.py 
2021-01-08 06:36:07.000000000 +0100
@@ -5,7 +5,7 @@
 
 from .. import _url
 from .common import HyperlinkTestCase
-from .._url import register_scheme, URL
+from .._url import register_scheme, URL, DecodedURL
 
 
 class TestSchemeRegistration(HyperlinkTestCase):
@@ -70,3 +70,13 @@
         # type: () -> None
         with self.assertRaises(ValueError):
             register_scheme("nope", default_port=cast(bool, object()))
+
+    def test_register_no_quote_plus_scheme(self):
+        # type: () -> None
+        register_scheme("keepplus", query_plus_is_space=False)
+        plus_is_not_space = DecodedURL.from_text(
+            "keepplus://example.com/?q=a+b"
+        )
+        plus_is_space = DecodedURL.from_text("https://example.com/?q=a+b";)
+        assert plus_is_not_space.get("q") == ["a+b"]
+        assert plus_is_space.get("q") == ["a b"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperlink-20.0.1/src/hyperlink/test/test_url.py 
new/hyperlink-21.0.0/src/hyperlink/test/test_url.py
--- old/hyperlink-20.0.1/src/hyperlink/test/test_url.py 2020-08-04 
08:14:29.000000000 +0200
+++ new/hyperlink-21.0.0/src/hyperlink/test/test_url.py 2021-01-08 
06:36:07.000000000 +0100
@@ -133,6 +133,8 @@
     "https://example.com/?a=%23";,  # hash in query param value
     "https://example.com/?a=%26";,  # ampersand in query param value
     "https://example.com/?a=%3D";,  # equals in query param value
+    "https://example.com/?foo+bar=baz";,  # plus in query param name
+    "https://example.com/?foo=bar+baz";,  # plus in query param value
     # double-encoded percent sign in all percent-encodable positions:
     "http://(%2525):(%2525)@example.com/(%2525)/?(%2525)=(%2525)#(%2525)",
     # colon in first part of schemeless relative url
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperlink-20.0.1/src/hyperlink.egg-info/PKG-INFO 
new/hyperlink-21.0.0/src/hyperlink.egg-info/PKG-INFO
--- old/hyperlink-20.0.1/src/hyperlink.egg-info/PKG-INFO        2020-08-05 
05:34:31.000000000 +0200
+++ new/hyperlink-21.0.0/src/hyperlink.egg-info/PKG-INFO        2021-01-08 
06:51:20.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: hyperlink
-Version: 20.0.1
+Version: 21.0.0
 Summary: A featureful, immutable, and correct URL for Python.
 Home-page: https://github.com/python-hyper/hyperlink
 Author: Mahmoud Hashemi and Glyph Lefkowitz
@@ -28,6 +28,7 @@
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: License :: OSI Approved :: MIT License
 Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hyperlink-20.0.1/tox.ini new/hyperlink-21.0.0/tox.ini
--- old/hyperlink-20.0.1/tox.ini        2020-08-04 08:14:29.000000000 +0200
+++ new/hyperlink-21.0.0/tox.ini        2021-01-08 06:36:07.000000000 +0100
@@ -48,7 +48,7 @@
     {[default]deps}
 
     # In Python 2, we need to pull in typing, mock
-    py{26,27,py2}: typing==3.7.4.1
+    py{26,27,py2}: typing==3.7.4.3
     py{26,27,py2}: mock==3.0.5  # rq.filter: <4
 
     # For pytest
@@ -58,7 +58,7 @@
     # For code coverage
     {[testenv:coverage_report]deps}
     py{26,27,34,py2}: pytest-cov==2.8.1  # rq.filter: <2.9
-    py{35,36,37,38,39,py3}: pytest-cov==2.10.0
+    py{35,36,37,38,39,py3}: pytest-cov==2.10.1
 
     # For hypothesis. Note Python 3.4 isn't supported by hypothesis.
     py{26,27,py2}: hypothesis==4.43.9  # rq.filter: <4.44
@@ -89,7 +89,7 @@
 skip_install = True
 
 deps =
-    black==19.10b0
+    black==20.8b1
 
 setenv =
     BLACK_LINT_ARGS=--check
@@ -120,14 +120,13 @@
 skip_install = True
 
 deps =
-    flake8-bugbear==20.1.4
-    flake8==3.8.3
+    flake8-bugbear==20.11.1
+    flake8==3.8.4
     mccabe==0.6.1
     pep8-naming==0.11.1
     pycodestyle==2.6.0
-    pydocstyle==5.0.2
-    # pin pyflakes pending a release with 
https://github.com/PyCQA/pyflakes/pull/455
-    git+git://github.com/PyCQA/pyflakes@ffe9386#egg=pyflakes
+    pydocstyle==5.1.1
+    pyflakes==2.2.0
 
 commands =
     flake8 {posargs:setup.py src/{env:PY_MODULE}}
@@ -184,7 +183,7 @@
 basepython = {[default]basepython}
 
 deps =
-    mypy==0.782
+    mypy==0.790
 
     {[default]deps}
 
@@ -247,7 +246,8 @@
 skip_install = True
 
 deps =
-    coverage==4.5.4  # rq.filter: <5  # coverage 5.0 drops Python 3.4 support
+    # coverage 5.0 drops Python 3.4 support
+    coverage==4.5.4  # rq.filter: <5
 
 setenv =
     {[default]setenv}
@@ -276,7 +276,7 @@
 
 deps =
     {[testenv:coverage_report]deps}
-    codecov==2.1.7
+    codecov==2.1.11
 
 passenv =
     # See 
https://github.com/codecov/codecov-python/blob/master/README.md#using-tox
@@ -318,8 +318,8 @@
 basepython = {[default]basepython}
 
 deps =
-    Sphinx==2.4.4
-    sphinx-rtd-theme==0.5.0
+    Sphinx==3.4.3
+    sphinx-rtd-theme==0.5.1
 
 commands =
     sphinx-build                           \
@@ -336,7 +336,7 @@
 
 deps =
     {[testenv:docs]deps}
-    sphinx-autobuild==0.7.1
+    sphinx-autobuild==2020.9.1
 
 commands =
     sphinx-autobuild                       \
@@ -359,9 +359,9 @@
 skip_install = True
 
 deps =
-   check-manifest==0.42
-   readme-renderer==26.0
-   twine==3.1.1
+   check-manifest==0.46
+   readme-renderer==28.0
+   twine==3.3.0
 
 commands =
    check-manifest

Reply via email to