Hello community, here is the log from the commit of package python-furl for openSUSE:Leap:15.2 checked in at 2020-03-16 12:21:00 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/python-furl (Old) and /work/SRC/openSUSE:Leap:15.2/.python-furl.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-furl" Mon Mar 16 12:21:00 2020 rev:2 rq:782048 version:2.1.0 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/python-furl/python-furl.changes 2020-02-22 18:50:34.760493588 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.python-furl.new.3160/python-furl.changes 2020-03-16 12:21:01.431708180 +0100 @@ -1,0 +2,20 @@ +Thu Mar 5 12:33:35 UTC 2020 - [email protected] + +- version update to 2.1.0 + Added: a dont_quote= parameter to Query.encode() and a + query_dont_quote= parameter to furl.tostr() that exempt valid query + characters from being percent-encoded, either in their entirety with + dont_quote=True, or selectively with dont_quote=<string>, like + dont_quote='/?@_'. + + Changed: Move package info from __init__.py into the more standard + __version__.py. + + Fixed: Support Unicode usernames and passwords in Python 2. + + Fixed: Update orderedmultdict to v1.0.1 to resolve a DeprecationWarning. + + Fixed: Encode '/' consistently in query strings across both + quote_plus=True and quote_plus=False. + +------------------------------------------------------------------- Old: ---- furl-2.0.0.tar.gz New: ---- furl-2.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-furl.spec ++++++ --- /var/tmp/diff_new_pack.EQTc88/_old 2020-03-16 12:21:01.691708223 +0100 +++ /var/tmp/diff_new_pack.EQTc88/_new 2020-03-16 12:21:01.695708223 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-furl # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 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-furl -Version: 2.0.0 +Version: 2.1.0 Release: 0 Summary: A Python URL manipulation library License: Unlicense ++++++ furl-2.0.0.tar.gz -> furl-2.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/furl-2.0.0/API.md new/furl-2.1.0/API.md --- old/furl-2.0.0/API.md 2018-09-26 03:53:12.000000000 +0200 +++ new/furl-2.1.0/API.md 2019-05-26 23:41:16.000000000 +0200 @@ -198,6 +198,7 @@ ```python >>> from __future__ import division # For Python 2.x. +>>> >>> f = furl('path') >>> f.path /= 'with' >>> f.path = f.path / 'more' / 'path segments/' @@ -326,11 +327,11 @@ 'http://sprop.su/?param' ``` -__encode(delimiter='&', quote_plus=True)__ can be used to encode query strings -with delimiters like `;` and encode key-value pairs with standard -percent-encoding (i.e. `%20` not `+`). The default delimiter is `&` and the -default key-value encoding is application/x-www-form-urlencoded (i.e. `+` not -`%20`). +__encode(delimiter='&', quote_plus=True, dont_quote='')__ can be used to encode +query strings with delimiters like `;`, encode spaces as `+` instead of `%20` +(i.e. application/x-www-form-urlencoded encoded), or avoid percent-encoding +valid query charactes entirely (valid query characters are +`/?:@-._~!$&'()*+,;=`). ```python >>> f.query = 'space=jams&woofs=squeeze+dog' @@ -342,6 +343,20 @@ 'space=jams&woofs=squeeze%20dog' ``` +`dont_quote` accepts `True`, `False`, or a string of valid query characters to +not percent-enode. If `True`, all valid query characters `/?:@-._~!$&'()*+,;=` +aren't percent-encoded. + +```python +>>> f.query = 'one,two/three' +>>> f.query.encode() +'one%2Ctwo%2Fthree' +>>> f.query.encode(dont_quote=True) +'one,two/three' +>>> f.query.encode(dont_quote=',') +'one,two%2Fthree' +``` + For a dictionary representation of a query, use __asdict()__. ```python @@ -592,16 +607,19 @@ 'http://www.google.com/path/add/seg%20ments/?example=arg#frag' ``` -__tostr(query_delimiter='&', query_quote_plus=True)__ creates and returns a URL -string. `query_delimiter` and `query_quote_plus` are passed unmodified to -`Query.encode()`. +__tostr(query_delimiter='&', query_quote_plus=True, query_dont_quote='')__ +creates and returns a URL string. `query_delimiter`, `query_quote_plus`, and +`query_dont_quote` are passed unmodified to `Query.encode()` as `delimiter`, +`quote_plus`, and `dont_quote` respectively. ```python >>> f = furl('http://spep.ru/?a+b=c+d&two%20tap=cat%20nap%24') >>> f.tostr() 'http://spep.ru/?a+b=c+d&two+tap=cat+nap$' ->> f.tostr(query_delimiter=';', query_quote_plus=False) +>>> f.tostr(query_delimiter=';', query_quote_plus=False) 'http://spep.ru/?a%20b=c%20d;two%20tap=cat%20nap$' +>>> f.tostr(query_dont_quote='$') +'http://spep.ru/?a+b=c+d&two+tap=cat+nap$' ``` `furl.url` is a shortcut for `furl.tostr()`. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/furl-2.0.0/PKG-INFO new/furl-2.1.0/PKG-INFO --- old/furl-2.0.0/PKG-INFO 2018-10-02 23:55:01.000000000 +0200 +++ new/furl-2.1.0/PKG-INFO 2019-09-20 22:58:29.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: furl -Version: 2.0.0 +Version: 2.1.0 Summary: URL manipulation made simple. Home-page: https://github.com/gruns/furl Author: Ansgar Grunseid diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/furl-2.0.0/README.md new/furl-2.1.0/README.md --- old/furl-2.0.0/README.md 2018-09-29 06:46:48.000000000 +0200 +++ new/furl-2.1.0/README.md 2019-05-26 23:45:22.000000000 +0200 @@ -23,15 +23,16 @@ and supports\ Python 2, Python 3, PyPy2, and PyPy3. -Code time: Query arguments are easy. Really easy. +Code time: Paths and query arguments are easy. Really easy. ```python >>> from furl import furl >>> f = furl('http://www.google.com/?one=1&two=2') +>>> f /= 'path' >>> f.args['three'] = '3' >>> del f.args['one'] >>> f.url -'http://www.google.com/?two=2&three=3' +'http://www.google.com/path?two=2&three=3' ``` Or use furl's inline modification methods. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/furl-2.0.0/furl/__init__.py new/furl-2.1.0/furl/__init__.py --- old/furl-2.0.0/furl/__init__.py 2018-10-02 00:34:01.000000000 +0200 +++ new/furl-2.1.0/furl/__init__.py 2018-12-06 00:12:55.000000000 +0100 @@ -11,10 +11,3 @@ # from .furl import * # noqa - -__title__ = 'furl' -__version__ = '2.0.0' -__license__ = 'Unlicense' -__author__ = 'Ansgar Grunseid' -__contact__ = '[email protected]' -__url__ = 'https://github.com/gruns/furl' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/furl-2.0.0/furl/__version__.py new/furl-2.1.0/furl/__version__.py --- old/furl-2.0.0/furl/__version__.py 1970-01-01 01:00:00.000000000 +0100 +++ new/furl-2.1.0/furl/__version__.py 2019-09-20 22:51:26.000000000 +0200 @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +# +# furl - URL manipulation made simple. +# +# Ansgar Grunseid +# grunseid.com +# [email protected] +# +# License: Build Amazing Things (Unlicense) +# + +__title__ = 'furl' +__version__ = '2.1.0' +__license__ = 'Unlicense' +__author__ = 'Ansgar Grunseid' +__contact__ = '[email protected]' +__url__ = 'https://github.com/gruns/furl' +__description__ = 'URL manipulation made simple.' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/furl-2.0.0/furl/furl.py new/furl-2.1.0/furl/furl.py --- old/furl-2.0.0/furl/furl.py 2018-09-30 08:54:35.000000000 +0200 +++ new/furl-2.1.0/furl/furl.py 2019-04-26 08:14:17.000000000 +0200 @@ -114,6 +114,27 @@ return decorator +def create_quote_fn(safe_charset, quote_plus): + def quote_fn(s, dont_quote): + if dont_quote is True: + safe = safe_charset + elif dont_quote is False: + safe = '' + else: # <dont_quote> is expected to be a string. + safe = dont_quote + + # Prune duplicates and characters not in <safe_charset>. + safe = ''.join(set(safe) & set(safe_charset)) # E.g. '?^#?' -> '?'. + + quoted = quote(s, safe) + if quote_plus: + quoted = quoted.replace('%20', '+') + + return quoted + + return quote_fn + + # # TODO(grun): Update some of the regex functions below to reflect the fact that # the valid encoding of Path segments differs slightly from the valid encoding @@ -430,13 +451,12 @@ take such strings, like load(), add(), set(), remove(), etc. """ - # RFC 3986: - # - # segment = *pchar - # pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - # sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - # / "*" / "+" / "," / ";" / "=" + # From RFC 3986: + # segment = *pchar + # pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + # sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + # / "*" / "+" / "," / ";" / "=" SAFE_SEGMENT_CHARS = ":@-._~!$&'()*+,;=" def __init__(self, path='', force_absolute=lambda _: False, strict=False): @@ -846,6 +866,15 @@ take such strings, like load(), add(), set(), remove(), etc. """ + # From RFC 3986: + # query = *( pchar / "/" / "?" ) + # pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + # sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + # / "*" / "+" / "," / ";" / "=" + SAFE_KEY_CHARS = "/?:@-._~!$'()*+,;" + SAFE_VALUE_CHARS = SAFE_KEY_CHARS + '=' + def __init__(self, query='', strict=False): self.strict = strict @@ -918,42 +947,59 @@ for key, value in items: self._params.add(key, value) - def encode(self, delimiter='&', quote_plus=True, delimeter=_absent): + def encode(self, delimiter='&', quote_plus=True, dont_quote='', + delimeter=_absent): """ Examples: + Query('a=a&b=#').encode() == 'a=a&b=%23' Query('a=a&b=#').encode(';') == 'a=a;b=%23' - Query('a+b=c+d').encode(quote_plus=False) == 'a%20b=c%20d' + Query('a+b=c@d').encode(dont_quote='@') == 'a+b=c@d' + Query('a+b=c@d').encode(quote_plus=False) == 'a%20b=c%40d' Until furl v0.4.6, the 'delimiter' argument was incorrectly spelled 'delimeter'. For backwards compatibility, accept both the correct 'delimiter' and the old, mispelled 'delimeter'. + Keys and values are encoded application/x-www-form-urlencoded if + <quote_plus> is True, percent-encoded otherwise. + + <dont_quote> exempts valid query characters from being + percent-encoded, either in their entirety with dont_quote=True, + or selectively with dont_quote=<string>, like + dont_quote='/?@_'. Invalid query characters -- those not in + self.SAFE_KEY_CHARS, like '#' and '^' -- are always encoded, + even if included in <dont_quote>. For example: + + Query('#=^').encode(dont_quote='#^') == '%23=%5E'. + + Returns: A URL encoded query string using <delimiter> as the delimiter separating key:value pairs. The most common and default delimiter is '&', but ';' can also be specified. ';' is - W3C recommended. Parameter keys and values are encoded - application/x-www-form-urlencoded if <quote_plus> is True, - percent-encoded otherwise. + W3C recommended. """ if delimeter is not _absent: delimiter = delimeter + quote_key = create_quote_fn(self.SAFE_KEY_CHARS, quote_plus) + quote_value = create_quote_fn(self.SAFE_VALUE_CHARS, quote_plus) + pairs = [] - sixurl = urllib.parse # six.moves.urllib.parse - quote_fn = sixurl.quote_plus if quote_plus else sixurl.quote for key, value in self.params.iterallitems(): utf8key = utf8(key, utf8(attemptstr(key))) - utf8value = utf8(value, utf8(attemptstr(value))) - - quoted_key = quote_fn(utf8key) - safe_value_chars = '=' if not quoted_key else '' - quoted_value = quote_fn(utf8value, safe_value_chars) + quoted_key = quote_key(utf8key, dont_quote) - if value is None: # Example: http://sprop.su/?param. + if value is None: # Example: http://sprop.su/?key. pair = quoted_key - else: - pair = '='.join([quoted_key, quoted_value]) + else: # Example: http://sprop.su/?key=value. + utf8value = utf8(value, utf8(attemptstr(value))) + quoted_value = quote_value(utf8value, dont_quote) + + if not quoted_key: # Unquote '=' to allow queries like '?==='. + quoted_value = quoted_value.replace('%3D', '=') + + pair = '%s=%s' % (quoted_key, quoted_value) pairs.append(pair) @@ -1300,15 +1346,15 @@ query=_absent, query_params=_absent, username=_absent, password=_absent, strict=False): """ - Raises: ValueError on invalid url. + Raises: ValueError on invalid URL or invalid URL component(s) provided. """ URLPathCompositionInterface.__init__(self, strict=strict) QueryCompositionInterface.__init__(self, strict=strict) FragmentCompositionInterface.__init__(self, strict=strict) self.strict = strict - self.load(url) # Raises ValueError on invalid url. - self.set( + self.load(url) # Raises ValueError on invalid URL. + self.set( # Raises ValueError on invalid URL component(s). args=args, path=path, fragment=fragment, scheme=scheme, netloc=netloc, origin=origin, fragment_path=fragment_path, fragment_args=fragment_args, fragment_separator=fragment_separator, @@ -1406,9 +1452,9 @@ @property def netloc(self): - userpass = quote(self.username or '', safe='') + userpass = quote(utf8(self.username) or '', safe='') if self.password is not None: - userpass += ':' + quote(self.password, safe='') + userpass += ':' + quote(utf8(self.password), safe='') if userpass or self.username is not None: userpass += '@' @@ -1551,7 +1597,8 @@ fragment_args=_absent, fragment_separator=_absent, host=_absent, port=_absent, query=_absent, query_params=_absent, username=_absent, password=_absent): - """Set components of a url and return this furl instance, <self>. + """ + Set components of a url and return this furl instance, <self>. If any overlapping, and hence possibly conflicting, parameters are provided, appropriate UserWarning's will be raised. The @@ -1734,12 +1781,15 @@ return self - def tostr(self, query_delimiter='&', query_quote_plus=True): + def tostr(self, query_delimiter='&', query_quote_plus=True, + query_dont_quote=''): + encoded_query = self.query.encode( + query_delimiter, query_quote_plus, query_dont_quote) url = urllib.parse.urlunsplit(( self.scheme or '', # Must be text type in Python 3. self.netloc, str(self.path), - self.query.encode(query_delimiter, query_quote_plus), + encoded_query, str(self.fragment), )) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/furl-2.0.0/furl.egg-info/PKG-INFO new/furl-2.1.0/furl.egg-info/PKG-INFO --- old/furl-2.0.0/furl.egg-info/PKG-INFO 2018-10-02 23:55:01.000000000 +0200 +++ new/furl-2.1.0/furl.egg-info/PKG-INFO 2019-09-20 22:58:29.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: furl -Version: 2.0.0 +Version: 2.1.0 Summary: URL manipulation made simple. Home-page: https://github.com/gruns/furl Author: Ansgar Grunseid diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/furl-2.0.0/furl.egg-info/SOURCES.txt new/furl-2.1.0/furl.egg-info/SOURCES.txt --- old/furl-2.0.0/furl.egg-info/SOURCES.txt 2018-10-02 23:55:01.000000000 +0200 +++ new/furl-2.1.0/furl.egg-info/SOURCES.txt 2019-09-20 22:58:29.000000000 +0200 @@ -5,6 +5,7 @@ setup.cfg setup.py furl/__init__.py +furl/__version__.py furl/common.py furl/compat.py furl/furl.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/furl-2.0.0/furl.egg-info/requires.txt new/furl-2.1.0/furl.egg-info/requires.txt --- old/furl-2.0.0/furl.egg-info/requires.txt 2018-10-02 23:55:01.000000000 +0200 +++ new/furl-2.1.0/furl.egg-info/requires.txt 2019-09-20 22:58:29.000000000 +0200 @@ -1,2 +1,2 @@ six>=1.8.0 -orderedmultidict>=1.0 +orderedmultidict>=1.0.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/furl-2.0.0/setup.py new/furl-2.1.0/setup.py --- old/furl-2.0.0/setup.py 2018-09-11 08:02:01.000000000 +0200 +++ new/furl-2.1.0/setup.py 2019-09-20 22:48:05.000000000 +0200 @@ -12,16 +12,15 @@ # import os -import re import sys from os.path import dirname, join as pjoin from setuptools import setup, find_packages, Command from setuptools.command.test import test as TestCommand -with open(pjoin(dirname(__file__), 'furl', '__init__.py')) as fo: - regex = r".*__version__ = '(.*?)'" - VERSION = re.compile(regex, re.S).match(fo.read()).group(1) +meta = {} +with open(pjoin('furl', '__version__.py')) as f: + exec(f.read(), meta) class Publish(Command): @@ -37,8 +36,8 @@ def run(self): os.system('python setup.py sdist bdist_wheel') - sdist = 'dist/furl-%s.tar.gz' % VERSION - wheel = 'dist/furl-%s-py2.py3-none-any.whl' % VERSION + sdist = 'dist/furl-%s.tar.gz' % meta['__version__'] + wheel = 'dist/furl-%s-py2.py3-none-any.whl' % meta['__version__'] rc = os.system('twine upload "%s" "%s"' % (sdist, wheel)) sys.exit(rc) @@ -49,9 +48,9 @@ Run the unit tests. By default, `python setup.py test` fails if tests/ isn't a Python - module (that is, if the tests/ directory doesn't contain an - __init__.py file). But the tests/ directory shouldn't contain an - __init__.py file and tests/ shouldn't be a Python module. See + module; i.e. if the tests/ directory doesn't contain an __init__.py + file). But the tests/ directory shouldn't contain an __init__.py + file and tests/ shouldn't be a Python module. See http://doc.pytest.org/en/latest/goodpractices.html @@ -60,20 +59,20 @@ """ def run_tests(self): from unittest import TestLoader, TextTestRunner - tests_dir = pjoin(dirname(__file__), 'tests') + tests_dir = pjoin(dirname(__file__), 'tests/') suite = TestLoader().discover(tests_dir) result = TextTestRunner().run(suite) sys.exit(0 if result.wasSuccessful() else -1) setup( - name='furl', - version=VERSION, - author='Ansgar Grunseid', - author_email='[email protected]', - url='https://github.com/gruns/furl', - license='Unlicense', - description='URL manipulation made simple.', + name=meta['__title__'], + license=meta['__license__'], + version=meta['__version__'], + author=meta['__author__'], + author_email=meta['__contact__'], + url=meta['__url__'], + description=meta['__description__'], long_description=( 'Information and documentation can be found at ' 'https://github.com/gruns/furl.'), @@ -97,13 +96,16 @@ 'Programming Language :: Python :: Implementation :: PyPy', 'Programming Language :: Python :: Implementation :: CPython', ], + tests_require=[ + 'flake8', + 'six>=1.8.0', + ], install_requires=[ 'six>=1.8.0', - 'orderedmultidict>=1.0', + 'orderedmultidict>=1.0.1', ], cmdclass={ 'test': RunTests, 'publish': Publish, }, - tests_require=['flake8', 'six>=1.8.0'], ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/furl-2.0.0/tests/test_furl.py new/furl-2.1.0/tests/test_furl.py --- old/furl-2.0.0/tests/test_furl.py 2018-10-02 00:51:06.000000000 +0200 +++ new/furl-2.1.0/tests/test_furl.py 2019-02-06 23:19:04.000000000 +0100 @@ -834,6 +834,19 @@ assert query.encode(';') == 'a=b+c;d=e+f' assert query.encode(';', quote_plus=False) == 'a=b%20c;d=e%20f' + # Encode '/' consistently across quote_plus=True and quote_plus=False. + query = furl.Query('a /b') + assert query.encode(quote_plus=True) == 'a+%2Fb' + assert query.encode(quote_plus=False) == 'a%20%2Fb' + + # dont_quote= accepts both True and a string of safe characters not to + # percent-encode. Unsafe query characters, like '^' and '#', are always + # percent-encoded. + query = furl.Query('a %2B/b?#') + assert query.encode(dont_quote='^') == 'a+%2B%2Fb%3F%23' + assert query.encode(quote_plus=True, dont_quote=True) == 'a++/b?%23' + assert query.encode(quote_plus=False, dont_quote=True) == 'a%20+/b?%23' + def test_asdict(self): pairs = [('a', '1'), ('ロリポップ', 'testä')] key_encoded = '%E3%83%AD%E3%83%AA%E3%83%9D%E3%83%83%E3%83%97' @@ -1386,6 +1399,13 @@ f.password = '' assert f.username is None and f.password == '' and f.url == '//:@' + # Unicode. + username = u'kødp' + password = u'ålæg' + f = furl.furl(u'https://%s:%[email protected]/' % (username, password)) + assert f.username == username and f.password == password + assert f.url == 'https://k%C3%B8dp:%c3%a5l%c3%[email protected]/' + def test_basics(self): url = 'hTtP://www.pumps.com/' f = furl.furl(url) @@ -2026,14 +2046,27 @@ assert f.url == 'foo:blah' def test_tostr(self): - f = furl.furl('http://blast.off/?a+b=c+d&two%20tap=cat%20nap%24') + f = furl.furl('http://blast.off/?a+b=c+d&two%20tap=cat%20nap%24%21') assert f.tostr() == f.url assert (f.tostr(query_delimiter=';') == - 'http://blast.off/?a+b=c+d;two+tap=cat+nap%24') + 'http://blast.off/?a+b=c+d;two+tap=cat+nap%24%21') assert (f.tostr(query_quote_plus=False) == - 'http://blast.off/?a%20b=c%20d&two%20tap=cat%20nap%24') + 'http://blast.off/?a%20b=c%20d&two%20tap=cat%20nap%24%21') assert (f.tostr(query_delimiter=';', query_quote_plus=False) == - 'http://blast.off/?a%20b=c%20d;two%20tap=cat%20nap%24') + 'http://blast.off/?a%20b=c%20d;two%20tap=cat%20nap%24%21') + assert (f.tostr(query_quote_plus=False, query_dont_quote=True) == + 'http://blast.off/?a%20b=c%20d&two%20tap=cat%20nap$!') + # query_dont_quote ignores invalid query characters, like '$'. + assert (f.tostr(query_quote_plus=False, query_dont_quote='$') == + 'http://blast.off/?a%20b=c%20d&two%20tap=cat%20nap$%21') + + url = 'https://klugg.com/?hi=*' + url_encoded = 'https://klugg.com/?hi=%2A&url=' + f = furl.furl(url).set(args=[('hi', '*'), ('url', url)]) + assert f.tostr() == url_encoded + quote_plus(url) + assert f.tostr(query_dont_quote=True) == url + '&url=' + url + assert f.tostr(query_dont_quote='*') == ( + url + '&url=' + quote_plus(url, '*')) def test_equality(self): assert furl.furl() is not furl.furl() and furl.furl() == furl.furl()
