Skip to content

Commit 7aee9aa

Browse files
allow to update query string using mod operator (#435)
* allow to update query string using mod operator Co-authored-by: Andrew Svetlov <[email protected]>
1 parent 116aefb commit 7aee9aa

File tree

7 files changed

+38
-2
lines changed

7 files changed

+38
-2
lines changed

CHANGES/435.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Allow using `mod` operator (`%`) for updating query string (an alias for `update_query()` method).

README.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,11 @@ All url manipulations produce a new url object:
5757

5858
.. code-block:: pycon
5959
60-
>>> url.parent / 'downloads/source'
61-
URL('https://www.python.org/downloads/source')
60+
>>> url = URL('https://www.python.org')
61+
>>> url / 'foo' / 'bar'
62+
URL('https://www.python.org/foo/bar')
63+
>>> url / 'foo' % {'bar': 'baz'}
64+
URL('https://www.python.org/foo?bar=baz')
6265
6366
Strings passed to constructor and modification methods are
6467
automatically encoded giving canonical representation as result:

docs/api.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,9 @@ section generates a new *URL* instance.
592592

593593
Clear *query* if ``None`` is passed.
594594

595+
Mod operator (``%``) can be used as alternative to the direct call of
596+
:meth:`URL.update_query`.
597+
595598
.. note::
596599

597600
The library accepts :class:`str` and :class:`int` as query argument values.
@@ -620,6 +623,8 @@ section generates a new *URL* instance.
620623
URL('http://example.com/path?a=b&c=d')
621624
>>> URL('http://example.com/path?a=b').update_query('c=d&c=f')
622625
URL('http://example.com/path?a=b&c=d&c=f')
626+
>>> URL('http://example.com/path?a=b') % {'c': 'd'}
627+
URL('http://example.com/path?a=b&c=d')
623628

624629
.. versionchanged:: 1.0
625630

docs/index.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ All URL manipulations produces a new URL object:
4646
>>> url.parent / 'downloads/source'
4747
URL('https://www.python.org/downloads/source')
4848

49+
A URL object can be modified with ``/`` and ``%`` operators:
50+
51+
.. doctest::
52+
53+
>>> url = URL('https://www.python.org')
54+
>>> url / 'foo' / 'bar'
55+
URL('https://www.python.org/foo/bar')
56+
>>> url / 'foo' % {'bar': 'baz'}
57+
URL('https://www.python.org/foo?bar=baz')
58+
4959
Strings passed to constructor and modification methods are
5060
automatically encoded giving canonical representation as result:
5161

tests/test_update_query.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,3 +268,16 @@ def test_update_query_multiple_keys():
268268
u2 = url.update_query([("a", "3"), ("a", "4")])
269269

270270
assert str(u2) == "http://example.com/path?a=3&a=4"
271+
272+
273+
# mod operator
274+
275+
276+
def test_update_query_with_mod_operator():
277+
url = URL("http://example.com/")
278+
assert str(url % {"a": "1"}) == "http://example.com/?a=1"
279+
assert str(url % [("a", "1")]) == "http://example.com/?a=1"
280+
assert str(url % "a=1&b=2") == "http://example.com/?a=1&b=2"
281+
assert str(url % {"a": "1"} % {"b": "2"}) == "http://example.com/?a=1&b=2"
282+
assert str(url % {"a": "1"} % {"a": "3", "b": "2"}) == "http://example.com/?a=3&b=2"
283+
assert str(url / "foo" % {"a": "1"}) == "http://example.com/foo?a=1"

yarl/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,9 @@ def __truediv__(self, name):
308308
self._val._replace(path=new_path, query="", fragment=""), encoded=True
309309
)
310310

311+
def __mod__(self, query):
312+
return self.update_query(query)
313+
311314
def __bool__(self) -> bool:
312315
return bool(
313316
self._val.netloc or self._val.path or self._val.query or self._val.fragment

yarl/__init__.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class URL:
5656
def __gt__(self, other: Any) -> bool: ...
5757
def __hash__(self) -> int: ...
5858
def __truediv__(self, name: str) -> URL: ...
59+
def __mod__(self, query: Query) -> URL: ...
5960
def is_absolute(self) -> bool: ...
6061
def is_default_port(self) -> bool: ...
6162
def origin(self) -> URL: ...

0 commit comments

Comments
 (0)