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 <[email protected]>
+
+- 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__ = "[email protected]"
__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