[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