[Python-modules-commits] [yarl] 01/13: Import yarl_0.10.3.orig.tar.gz
Piotr Ożarowski
piotr at moszumanska.debian.org
Tue Jun 20 18:21:32 UTC 2017
This is an automated email from the git hooks/post-receive script.
piotr pushed a commit to branch master
in repository yarl.
commit 33967f05b1739049ccfff67ed06a1a8d2c0fa2a6
Author: Piotr Ożarowski <piotr at debian.org>
Date: Tue Jun 20 20:05:35 2017 +0200
Import yarl_0.10.3.orig.tar.gz
---
CHANGES.rst | 99 ++-
PKG-INFO | 112 ++-
README.rst | 10 +-
docs/api.rst | 113 ++-
docs/index.rst | 10 +-
setup.cfg | 2 +-
setup.py | 8 +-
tests/test_quoting.py | 54 +-
tests/test_url.py | 253 +++++-
yarl.egg-info/PKG-INFO | 112 ++-
yarl/__init__.py | 207 +++--
yarl/__init__.pyi | 5 +
yarl/_quoting.c | 2217 +++++++++++++++++++++++++++++++++---------------
yarl/_quoting.pyx | 89 +-
yarl/quoting.py | 50 +-
15 files changed, 2505 insertions(+), 836 deletions(-)
diff --git a/CHANGES.rst b/CHANGES.rst
index 98ec8a2..997b842 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,6 +1,99 @@
CHANGES
=======
+0.10.3 (2017-06-13)
+-------------------
+
+* Prevent double URL args unquoting #83
+
+0.10.2 (2017-05-05)
+-------------------
+
+* Unexpected hash behaviour #75
+
+
+0.10.1 (2017-05-03)
+-------------------
+
+* Unexpected compare behaviour #73
+
+* Do not quote or unquote + if not a query string. #74
+
+
+0.10.0 (2017-03-14)
+-------------------
+
+* Added `URL.build` class method #58
+
+* Added `path_qs` attribute #42
+
+
+0.9.8 (2017-02-16)
+------------------
+
+* Do not quote ":" in path
+
+
+0.9.7 (2017-02-16)
+------------------
+
+* Load from pickle without _cache #56
+
+* Percent-encoded pluses in path variables become spaces #59
+
+
+0.9.6 (2017-02-15)
+------------------
+
+* Revert backward incompatible change (BaseURL)
+
+
+0.9.5 (2017-02-14)
+------------------
+
+* Fix BaseURL rich comparison support
+
+
+0.9.4 (2017-02-14)
+------------------
+
+* Use BaseURL
+
+
+0.9.3 (2017-02-14)
+------------------
+
+* Added BaseURL
+
+
+0.9.2 (2017-02-08)
+------------------
+
+* Remove debug print
+
+
+0.9.1 (2017-02-07)
+------------------
+
+* Do not lose tail chars #45
+
+
+0.9.0 (2017-02-07)
+------------------
+
+* Allow to quote % in non strict mode #21
+
+* Incorrect parsing of query parameters with %3B (;) inside #34
+
+* core dumps #41
+
+* tmpbuf - compiling error #43
+
+* Added `URL.update_path()` method
+
+* Added `URL.update_query()` method #47
+
+
0.8.1 (2016-12-03)
------------------
@@ -46,7 +139,7 @@ CHANGES
0.5.1 (2016-11-02)
------------------
-* Make URL counstruction faster by removing extra classmethod calls
+* Make URL construction faster by removing extra classmethod calls
0.5.0 (2016-11-02)
------------------
@@ -82,7 +175,7 @@ CHANGES
0.3.1 (2016-09-26)
------------------
-* Support sequience of pairs as with_query() parameter
+* Support sequence of pairs as with_query() parameter
0.3.0 (2016-09-26)
------------------
@@ -121,7 +214,7 @@ CHANGES
0.1.1 (2016-09-06)
------------------
-* Update REAMDE, old version used obsolete AIP
+* Update README, old version used obsolete API
0.1.0 (2016-09-06)
------------------
diff --git a/PKG-INFO b/PKG-INFO
index 7105d35..6451c74 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: yarl
-Version: 0.8.1
+Version: 0.10.3
Summary: Yet another URL library
Home-page: https://github.com/aio-libs/yarl/
Author: Andrew Svetlov
@@ -38,7 +38,7 @@ Description: yarl
>>> url
URL('https://www.python.org/~guido?arg=1#frag')
- All url parts: *scheme*, *user*, *passsword*, *host*, *port*, *path*,
+ All url parts: *scheme*, *user*, *password*, *host*, *port*, *path*,
*query* and *fragment* are accessible by properties::
>>> url.scheme
@@ -109,11 +109,11 @@ Description: yarl
* furl (https://pypi.python.org/pypi/furl)
- The libray has a rich functionality but ``furl`` object is mutable.
+ The library has a rich functionality but ``furl`` object is mutable.
I afraid to pass this object into foreign code: who knows if the
- code will modifiy my url in a terrible way while I just want to send URL
- with handy helpers for accessing URL properies.
+ code will modify my url in a terrible way while I just want to send URL
+ with handy helpers for accessing URL properties.
``furl`` has other non obvious tricky things but the main objection
is mutability.
@@ -124,7 +124,7 @@ Description: yarl
Every URL change generates a new URL object.
- But the library doesn't any decode/encode transormations leaving end
+ But the library doesn't any decode/encode transformations leaving end
user to cope with these gory details.
@@ -164,6 +164,99 @@ Description: yarl
CHANGES
=======
+ 0.10.3 (2017-06-13)
+ -------------------
+
+ * Prevent double URL args unquoting #83
+
+ 0.10.2 (2017-05-05)
+ -------------------
+
+ * Unexpected hash behaviour #75
+
+
+ 0.10.1 (2017-05-03)
+ -------------------
+
+ * Unexpected compare behaviour #73
+
+ * Do not quote or unquote + if not a query string. #74
+
+
+ 0.10.0 (2017-03-14)
+ -------------------
+
+ * Added `URL.build` class method #58
+
+ * Added `path_qs` attribute #42
+
+
+ 0.9.8 (2017-02-16)
+ ------------------
+
+ * Do not quote ":" in path
+
+
+ 0.9.7 (2017-02-16)
+ ------------------
+
+ * Load from pickle without _cache #56
+
+ * Percent-encoded pluses in path variables become spaces #59
+
+
+ 0.9.6 (2017-02-15)
+ ------------------
+
+ * Revert backward incompatible change (BaseURL)
+
+
+ 0.9.5 (2017-02-14)
+ ------------------
+
+ * Fix BaseURL rich comparison support
+
+
+ 0.9.4 (2017-02-14)
+ ------------------
+
+ * Use BaseURL
+
+
+ 0.9.3 (2017-02-14)
+ ------------------
+
+ * Added BaseURL
+
+
+ 0.9.2 (2017-02-08)
+ ------------------
+
+ * Remove debug print
+
+
+ 0.9.1 (2017-02-07)
+ ------------------
+
+ * Do not lose tail chars #45
+
+
+ 0.9.0 (2017-02-07)
+ ------------------
+
+ * Allow to quote % in non strict mode #21
+
+ * Incorrect parsing of query parameters with %3B (;) inside #34
+
+ * core dumps #41
+
+ * tmpbuf - compiling error #43
+
+ * Added `URL.update_path()` method
+
+ * Added `URL.update_query()` method #47
+
+
0.8.1 (2016-12-03)
------------------
@@ -209,7 +302,7 @@ Description: yarl
0.5.1 (2016-11-02)
------------------
- * Make URL counstruction faster by removing extra classmethod calls
+ * Make URL construction faster by removing extra classmethod calls
0.5.0 (2016-11-02)
------------------
@@ -245,7 +338,7 @@ Description: yarl
0.3.1 (2016-09-26)
------------------
- * Support sequience of pairs as with_query() parameter
+ * Support sequence of pairs as with_query() parameter
0.3.0 (2016-09-26)
------------------
@@ -284,7 +377,7 @@ Description: yarl
0.1.1 (2016-09-06)
------------------
- * Update REAMDE, old version used obsolete AIP
+ * Update README, old version used obsolete API
0.1.0 (2016-09-06)
------------------
@@ -304,4 +397,5 @@ Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
Classifier: Topic :: Internet :: WWW/HTTP
diff --git a/README.rst b/README.rst
index 2e017f8..2839099 100644
--- a/README.rst
+++ b/README.rst
@@ -30,7 +30,7 @@ Url is constructed from ``str``::
>>> url
URL('https://www.python.org/~guido?arg=1#frag')
-All url parts: *scheme*, *user*, *passsword*, *host*, *port*, *path*,
+All url parts: *scheme*, *user*, *password*, *host*, *port*, *path*,
*query* and *fragment* are accessible by properties::
>>> url.scheme
@@ -101,11 +101,11 @@ Comparison with other URL libraries
* furl (https://pypi.python.org/pypi/furl)
- The libray has a rich functionality but ``furl`` object is mutable.
+ The library has a rich functionality but ``furl`` object is mutable.
I afraid to pass this object into foreign code: who knows if the
- code will modifiy my url in a terrible way while I just want to send URL
- with handy helpers for accessing URL properies.
+ code will modify my url in a terrible way while I just want to send URL
+ with handy helpers for accessing URL properties.
``furl`` has other non obvious tricky things but the main objection
is mutability.
@@ -116,7 +116,7 @@ Comparison with other URL libraries
Every URL change generates a new URL object.
- But the library doesn't any decode/encode transormations leaving end
+ But the library doesn't any decode/encode transformations leaving end
user to cope with these gory details.
diff --git a/docs/api.rst b/docs/api.rst
index 2a55915..b273150 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -42,7 +42,7 @@ The library assumes all data uses *UTF-8* for *percent-encoded* tokens.
Unless URL contain the only *ascii* characters there is no differences.
-But for *non-ascii* case *encoding* is applyed.
+But for *non-ascii* case *encoding* is applied.
.. doctest::
@@ -200,6 +200,17 @@ There are two kinds of properties: *decoded* and *encoded* (with
>>> URL('http://example.com').path
'/'
+
+.. attribute:: URL.path_qs
+
+ Decoded *path* part of URL and query string, ``'/'`` for absolute URLs without *path* part.
+
+ .. doctest::
+
+ >>> URL('http://example.com/path/to?a1=a&a2=b').path_qs
+ '/path/to?a1=a&a2=b'
+
+
.. attribute:: URL.raw_path
Encoded *path* part of URL, ``'/'`` for absolute URLs without *path* part.
@@ -329,9 +340,9 @@ For *path* and *query* *yarl* supports additional helpers:
Absolute and relative URLs
--------------------------
-The module supports both absolute an relative URLs.
+The module supports both absolute and relative URLs.
-Absulute URL should start from either *scheme* or ``'//'``.
+Absolute URL should start from either *scheme* or ``'//'``.
.. method:: URL.is_absolute()
@@ -353,12 +364,39 @@ Absulute URL should start from either *scheme* or ``'//'``.
False
-New URL generaion
------------------
+New URL generation
+------------------
URL is an immutable object, every operation described in the
section generates a new *URL* instance.
+.. method:: URL.build(scheme, user, password, host, port, path, query, query_string, fragment, strict=False)
+
+ Creates and returns a new URL:
+
+ .. doctest::
+
+ >>> URL.build(scheme="http", host="example.com")
+ URL('http://example.com')
+
+ >>> URL.build(scheme="http", host="example.com", query={"a": "b"})
+ URL('http://example.com/?a=b')
+
+ >>> URL.build(scheme="http", host="example.com", query_string="a=b")
+ URL('http://example.com/?a=b')
+
+ >>> URL.build()
+ URL('')
+
+ Calling ``build`` method without arguments is equal to calling ``__init__`` without arguments.
+
+ .. note::
+ When ``scheme`` and ``host`` are passed new URL will be “absolute”. If only one of ``scheme`` or ``host`` is
+ passed then AssertionError will be raised.
+
+ .. note::
+ Only one of ``query`` or ``query_string`` should be passed then AssertionError will be raised.
+
.. method:: URL.with_scheme(scheme)
Return a new URL with *scheme* replaced:
@@ -423,11 +461,23 @@ section generates a new *URL* instance.
>>> URL('http://example.com:8888').with_port(None)
URL('http://example.com')
+.. method:: URL.with_path(path, encoded=False)
+
+ Return a new URL with *path* replaced, encode *path* if needed.
+
+ .. doctest::
+
+ >>> URL('http://example.com/').with_path('/path/to')
+ URL('http://example.com/path/to')
+
+
.. method:: URL.with_query(query)
URL.with_query(**kwargs)
Return a new URL with *query* part replaced.
+ Unlike :meth:`update_query` the method replaces all query parameters.
+
Accepts any :class:`~collections.abc.Mapping` (e.g. :class:`dict`,
:class:`~multidict.MultiDict` instances) or :class:`str`,
autoencode the argument if needed.
@@ -453,6 +503,57 @@ section generates a new *URL* instance.
>>> URL('http://example.com/path?a=b&b=1').with_query([('b', '2')])
URL('http://example.com/path?b=2')
+.. method:: URL.update_query(query)
+ URL.update_query(**kwargs)
+
+ Returns a new URL with *query* part updated.
+
+ Unlike :meth:`with_query` the method does not replace query
+ completely.
+
+
+ Returned ``URL`` object will contain query string which updated
+ parts from passed query parts (or parts of parsed query string).
+
+ Accepts any :class:`~collections.abc.Mapping` (e.g. :class:`dict`,
+ :class:`~multidict.MultiDict` instances) or :class:`str`,
+ autoencode the argument if needed.
+
+ A sequence of ``(key, value)`` pairs is supported as well.
+
+ Also it can take an arbitrary number of keyword arguments.
+
+ Clear *query* if ``None`` is passed.
+
+ .. doctest::
+
+ >>> URL('http://example.com/path?a=b').update_query('c=d')
+ URL('http://example.com/path?a=b&c=d')
+ >>> URL('http://example.com/path?a=b').update_query({'c': 'd'})
+ URL('http://example.com/path?a=b&c=d')
+ >>> URL('http://example.com/path?a=b').update_query({'кл': 'зн'})
+ URL('http://example.com/path?a=b&%D0%BA%D0%BB=%D0%B7%D0%BD')
+ >>> URL('http://example.com/path?a=b&b=1').update_query(b='2')
+ URL('http://example.com/path?a=b&b=2')
+ >>> URL('http://example.com/path?a=b&b=1').update_query([('b', '2')])
+ URL('http://example.com/path?a=b&b=2')
+
+ .. note::
+
+ Query string will be updated in a similar way to ``dict.update``. Multiple values will be dropped:
+
+ .. doctest::
+
+ >>> URL('http://example.com/path?a=b&c=e&c=f').update_query(c='d')
+ URL('http://example.com/path?a=b&c=d')
+
+ When passing multiple values as an argument, only last value will be applied.
+
+ .. doctest::
+
+ >>> URL('http://example.com/path?a=b').update_query('c=d&c=f')
+ URL('http://example.com/path?a=b&c=f')
+
.. method:: URL.with_fragment(port)
Return a new URL with *fragment* replaced, autoencode *fragment* if needed.
@@ -632,7 +733,7 @@ possible.
Document describing non-ascii domain name encoding.
:rfc:`3987` - Internationalized Resource Identifiers
- This specifies convertion rules for non-ascii characters in URL.
+ This specifies conversion rules for non-ascii characters in URL.
:rfc:`3986` - Uniform Resource Identifiers
This is the current standard (STD66). Any changes to :mod:`yarl` module
diff --git a/docs/index.rst b/docs/index.rst
index 1c39185..2a3acd1 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -21,7 +21,7 @@ Url is constructed from :class:`str`:
>>> url
URL('https://www.python.org/~guido?arg=1#frag')
-All url parts: *scheme*, *user*, *passsword*, *host*, *port*, *path*,
+All url parts: *scheme*, *user*, *password*, *host*, *port*, *path*,
*query* and *fragment* are accessible by properties:
.. doctest::
@@ -105,11 +105,11 @@ Comparison with other URL libraries
* furl (https://pypi.python.org/pypi/furl)
- The libray has a rich functionality but ``furl`` object is mutable.
+ The library has a rich functionality but ``furl`` object is mutable.
I afraid to pass this object into foreign code: who knows if the
- code will modifiy my url in a terrible way while I just want to send URL
- with handy helpers for accessing URL properies.
+ code will modify my url in a terrible way while I just want to send URL
+ with handy helpers for accessing URL properties.
``furl`` has other non obvious tricky things but the main objection
is mutability.
@@ -120,7 +120,7 @@ Comparison with other URL libraries
Every URL change generates a new URL object.
- But the library doesn't any decode/encode transormations leaving end
+ But the library doesn't any decode/encode transformations leaving end
user to cope with these gory details.
diff --git a/setup.cfg b/setup.cfg
index 4882edf..958c331 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -2,7 +2,7 @@
test = pytest
[egg_info]
-tag_build =
tag_date = 0
tag_svn_revision = 0
+tag_build =
diff --git a/setup.py b/setup.py
index dc133d3..4ab4004 100644
--- a/setup.py
+++ b/setup.py
@@ -17,10 +17,9 @@ except ImportError:
ext = '.pyx' if USE_CYTHON else '.c'
extensions = [Extension('yarl._quoting',
- ['yarl/_quoting' + ext],
- # extra_compile_args=["-g"],
- # extra_link_args=["-g"],
-)]
+ ['yarl/_quoting' + ext],)]
+# extra_compile_args=["-g"],
+# extra_link_args=["-g"],
if USE_CYTHON:
@@ -85,6 +84,7 @@ args = dict(
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
'Topic :: Internet :: WWW/HTTP'],
author='Andrew Svetlov',
author_email='andrew.svetlov at gmail.com',
diff --git a/tests/test_quoting.py b/tests/test_quoting.py
index 052d3fb..597e7e4 100644
--- a/tests/test_quoting.py
+++ b/tests/test_quoting.py
@@ -27,16 +27,52 @@ def test_quote_not_allowed(quote):
quote('%HH')
+def test_quote_not_allowed_non_strict(quote):
+ assert quote('%HH', strict=False) == '%25HH'
+
+
def test_quote_unfinished(quote):
with pytest.raises(ValueError):
quote('%F%F')
+def test_quote_unfinished_tail_percent(quote):
+ with pytest.raises(ValueError):
+ quote('%')
+
+
+def test_quote_unfinished_tail_percent_non_strict(quote):
+ assert quote('%', strict=False) == '%25'
+
+
+def test_quote_unfinished_tail(quote):
+ with pytest.raises(ValueError):
+ quote('%2')
+
+
+def test_quote_unfinished_tail_non_strict(quote):
+ assert quote('%2', strict=False) == '%252'
+
+
def test_quote_from_bytes(quote):
assert quote('archaeological arcana') == 'archaeological%20arcana'
assert quote('') == ''
+def test_quate_broken_unicode(quote):
+ with pytest.raises(UnicodeEncodeError):
+ quote('j\x1a\udcf4q\udcda/\udc97g\udcee\udccb\x0ch\udccb'
+ '\x18\udce4v\x1b\udce2\udcce\udccecom/y\udccepj\x16')
+
+
+def test_quate_ignore_broken_unicode(quote):
+ s = quote('j\x1a\udcf4q\udcda/\udc97g\udcee\udccb\x0ch\udccb'
+ '\x18\udce4v\x1b\udce2\udcce\udccecom/y\udccepj\x16',
+ strict=False)
+
+ assert s == 'j%1Aq%2Fg%0Ch%18v%1Bcom%2Fypj%16'
+
+
def test_unquote_to_bytes(unquote):
assert unquote('abc%20def') == 'abc def'
assert unquote('') == ''
@@ -112,6 +148,7 @@ def test_quoting_space(quote):
def test_quoting_plus(quote):
+ assert quote('alpha+beta gamma', qs=False) == 'alpha+beta%20gamma'
assert quote('alpha+beta gamma', qs=True) == 'alpha%2Bbeta+gamma'
assert quote('alpha+beta gamma', safe='+', qs=True) == 'alpha+beta+gamma'
@@ -149,7 +186,7 @@ def test_unquoting(num, unquote):
expect = chr(num)
result = unquote(given)
assert expect == result
- if expect not in '+=&':
+ if expect not in '+=&;':
result = unquote(given, qs=True)
assert expect == result
@@ -233,6 +270,17 @@ def test_quote_unquoted(quote):
assert quote('%41') == 'A'
+def test_quote_space(quote):
+ assert quote(' ', strict=False) == '%20' # NULL
+
+
+# test to see if this would work to fix
+# coverage on this file.
+def test_quote_percent_last_character(quote):
+ # % is last character in this case.
+ assert quote('%', strict=False) == '%25'
+
+
def test_unquote_unsafe(unquote):
assert unquote('%40', unsafe='@') == '%40'
@@ -285,6 +333,10 @@ def test_requote_sub_delims(quote):
assert quote("%21%24%26%27%28%29%2A%2B%2C%3B%3D") == "!$&'()*+,;="
+def test_unquoting_plus(unquote):
+ assert unquote('a+b', qs=False) == 'a+b'
+
+
def test_unquote_plus_to_space(unquote):
assert unquote('a+b', qs=True) == 'a b'
diff --git a/tests/test_url.py b/tests/test_url.py
index fcd59cf..e4b1f11 100644
--- a/tests/test_url.py
+++ b/tests/test_url.py
@@ -1,6 +1,7 @@
import sys
-from urllib.parse import SplitResult
+import pickle
import pytest
+from urllib.parse import SplitResult, urlencode
from multidict import MultiDict, MultiDictProxy
from yarl import URL
@@ -42,6 +43,19 @@ def test_origin_no_scheme():
with pytest.raises(ValueError):
url.origin()
+
+def test_abs_cmp():
+ assert URL('http://example.com:8888') == URL('http://example.com:8888')
+ assert URL('http://example.com:8888/') == URL('http://example.com:8888/')
+ assert URL('http://example.com:8888/') == URL('http://example.com:8888')
+ assert URL('http://example.com:8888') == URL('http://example.com:8888/')
+
+
+def test_abs_hash():
+ url = URL('http://example.com:8888')
+ url_trailing = URL('http://example.com:8888/')
+ assert hash(url) == hash(url_trailing)
+
# properties
@@ -150,6 +164,14 @@ def test_path_non_ascii():
assert '/путь/сюда' == url.path
+def test_path_with_spaces():
+ url = URL('http://example.com/a b/test')
+ assert '/a b/test' == url.path
+
+ url = URL('http://example.com/a b')
+ assert '/a b' == url.path
+
+
def test_raw_path_for_empty_url():
url = URL()
assert '' == url.raw_path
@@ -175,6 +197,15 @@ def test_query_string_non_ascii():
assert url.query_string == 'б=в&ю=к'
+def test_path_qs():
+ url = URL('http://example.com/')
+ assert url.path_qs == '/'
+ url = URL('http://example.com/?б=в&ю=к')
+ assert url.path_qs == '/?б=в&ю=к'
+ url = URL('http://example.com/path?б=в&ю=к')
+ assert url.path_qs == '/path?б=в&ю=к'
+
+
def test_query_string_spaces():
url = URL('http://example.com?a+b=c+d&e=f+g')
assert url.query_string == 'a b=c d&e=f g'
@@ -206,6 +237,20 @@ def test_query_empty_arg():
assert url.query == MultiDict([('a', '')])
+def test_query_dont_unqoute_twice():
+ sample_url = 'http://base.place?' + urlencode({'a': '/////'})
+ query = urlencode({'url': sample_url})
+ full_url = 'http://test_url.aha?' + query
+
+ url = URL(full_url)
+ assert url.query['url'] == sample_url
+
+
+def test_query_nonascii():
+ url = URL('http://example.com?ключ=знач')
+ assert url.query == MultiDict({'ключ': 'знач'})
+
+
def test_raw_fragment_empty():
url = URL('http://example.com')
assert '' == url.raw_fragment
@@ -334,6 +379,12 @@ def test_name_non_ascii():
url = URL('http://example.com/путь')
assert url.name == 'путь'
+
+def test_plus_in_path():
+ url = URL('http://example.com/test/x+y%2Bz/:+%2B/')
+ assert '/test/x+y+z/:++/' == url.path
+
+
# modifiers
@@ -683,11 +734,49 @@ def test_with_port_invalid_type():
URL('http://example.com').with_port('123')
+def test_with_path():
+ url = URL('http://example.com')
+ assert str(url.with_path('/test')) == 'http://example.com/test'
+
+
+def test_with_path_encoded():
+ url = URL('http://example.com')
+ assert str(url.with_path('/test',
+ encoded=True)
+ ) == 'http://example.com/test'
+
+
def test_with_query():
url = URL('http://example.com')
assert str(url.with_query({'a': '1'})) == 'http://example.com/?a=1'
+def test_update_query():
+ url = URL('http://example.com/')
+ assert str(url.update_query({'a': '1'})) == 'http://example.com/?a=1'
+
+ url = URL('http://example.com/?foo=bar')
+ expected_url = URL('http://example.com/?foo=bar&baz=foo')
+
+ assert url.update_query({'baz': 'foo'}) == expected_url
+ assert url.update_query(baz='foo') == expected_url
+ assert url.update_query("?baz=foo") == expected_url
+
+
+def test_update_query_with_args_and_kwargs():
+ url = URL('http://example.com/')
+
+ with pytest.raises(ValueError):
+ url.update_query('a', foo='bar')
+
+
+def test_update_query_with_multiple_args():
+ url = URL('http://example.com/')
+
+ with pytest.raises(ValueError):
+ url.update_query('a', 'b')
+
+
def test_with_query_list_of_pairs():
url = URL('http://example.com')
assert str(url.with_query([('a', '1')])) == 'http://example.com/?a=1'
@@ -1100,7 +1189,7 @@ def test_fragment_only_url():
def test_url_from_url():
url = URL('http://example.com')
- assert URL(url) is url
+ assert URL(url) == url
assert URL(url).raw_parts == ('/',)
@@ -1300,3 +1389,163 @@ def test_requoting():
u = URL('http://127.0.0.1/?next=http%3A//example.com/')
assert u.raw_query_string == 'next=http://example.com/'
assert str(u) == 'http://127.0.0.1/?next=http://example.com/'
+
+
+# query separators
+
+def test_ampersand_as_separator():
+ u = URL('http://127.0.0.1/?a=1&b=2')
+ assert len(u.query) == 2
+
+
+def test_ampersand_as_value():
+ u = URL('http://127.0.0.1/?a=1%26b=2')
+ assert len(u.query) == 1
+ assert u.query['a'] == '1&b=2'
+
+
+def test_semicolon_as_separator():
+ u = URL('http://127.0.0.1/?a=1;b=2')
+ assert len(u.query) == 2
+
+
+def test_semicolon_as_value():
+ u = URL('http://127.0.0.1/?a=1%3Bb=2')
+ assert len(u.query) == 1
+ assert u.query['a'] == '1;b=2'
+
+
+# serialize
+
+def test_pickle():
+ u1 = URL('test')
+ hash(u1)
+ v = pickle.dumps(u1)
+ u2 = pickle.loads(v)
+ assert u1._cache
+ assert not u2._cache
+ assert hash(u1) == hash(u2)
+
+
+def test_default_style_state():
+ u = URL('test')
+ hash(u)
+ u.__setstate__((None, {
+ '_val': 'test',
+ '_strict': False,
+ '_cache': {'hash': 1},
+ }))
+ assert not u._cache
+ assert u._val == 'test'
+ assert u._strict is False
+
+
+# build classmethod
+
+def test_build_without_arguments():
+ u = URL.build()
+ assert str(u) == ''
+
+
+def test_build_simple():
+ u = URL.build(scheme='http', host='127.0.0.1')
+ assert str(u) == 'http://127.0.0.1'
+
+
+def test_build_scheme_and_host():
+ with pytest.raises(ValueError):
+ URL.build(host='127.0.0.1')
+
+ with pytest.raises(ValueError):
+ URL.build(scheme='http')
+
+
+def test_build_with_port():
+ u = URL.build(scheme='http', host='127.0.0.1', port=8000)
+ assert str(u) == 'http://127.0.0.1:8000'
+
+
+def test_build_with_user():
+ u = URL.build(scheme='http', host='127.0.0.1', user='foo')
+ assert str(u) == 'http://foo@127.0.0.1'
+
+
+def test_build_with_user_password():
+ u = URL.build(scheme='http', host='127.0.0.1', user='foo', password='bar')
+ assert str(u) == 'http://foo:bar@127.0.0.1'
+
+
+def test_build_with_query_and_query_string():
+ with pytest.raises(ValueError):
+ URL.build(
+ scheme='http',
+ host='127.0.0.1',
+ user='foo',
+ password='bar',
+ port=8000,
+ path='/index.html',
+ query=dict(arg="value1"),
+ query_string="arg=value1",
+ fragment="top"
+ )
+
+
+def test_build_with_all():
+ u = URL.build(
+ scheme='http',
+ host='127.0.0.1',
+ user='foo',
+ password='bar',
+ port=8000,
+ path='/index.html',
+ query_string="arg=value1",
+ fragment="top"
+ )
+ assert str(u) == 'http://foo:bar@127.0.0.1:8000/index.html?arg=value1#top'
+
+
... 5126 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/yarl.git
More information about the Python-modules-commits
mailing list