Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES/435.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Allow to use mod operator (`%`) for updating query string:

url = URL("http://example.com")
assert url % {"a": "1"} == URL("http://example.com?a=1")
Comment thread
asvetlov marked this conversation as resolved.
Outdated
8 changes: 8 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ All url manipulations produce a new url object::
>>> url.parent / 'downloads/source'
URL('https://www.python.org/downloads/source')

Url can be modified with ``/`` and ``%`` operators::

Comment thread
asvetlov marked this conversation as resolved.
Outdated
>>> url = URL('https://www.python.org')
>>> url / 'foo' / 'bar'
URL('https://www.python.org/foo/bar')
>>> url / 'foo' % {'bar': 'baz'}
URL('https://www.python.org/foo?bar=baz')

Strings passed to constructor and modification methods are
automatically encoded giving canonical representation as result::

Expand Down
5 changes: 5 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,9 @@ section generates a new *URL* instance.

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

Mod operator (``%``) can be used as alternative to the direct call of
``URL.update_query``.
Comment thread
asvetlov marked this conversation as resolved.
Outdated

.. note::

The library accepts :class:`str` and :class:`int` as query argument values.
Expand All @@ -610,6 +613,8 @@ section generates a new *URL* instance.
URL('http://example.com/path?a=b&c=d')
>>> URL('http://example.com/path?a=b').update_query('c=d&c=f')
URL('http://example.com/path?a=b&c=d&c=f')
>>> URL('http://example.com/path?a=b') % {'c': 'd'}
URL('http://example.com/path?a=b&c=d')

.. versionchanged:: 1.0

Expand Down
10 changes: 10 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ All URL manipulations produces a new URL object:
>>> url.parent / 'downloads/source'
URL('https://www.python.org/downloads/source')

Url can be modified with ``/`` and ``%`` operators:
Comment thread
asvetlov marked this conversation as resolved.
Outdated

.. doctest::

>>> url = URL('https://www.python.org')
>>> url / 'foo' / 'bar'
URL('https://www.python.org/foo/bar')
>>> url / 'foo' % {'bar': 'baz'}
URL('https://www.python.org/foo?bar=baz')

Strings passed to constructor and modification methods are
automatically encoded giving canonical representation as result:

Expand Down
13 changes: 13 additions & 0 deletions tests/test_update_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,16 @@ def test_update_query_multiple_keys():
u2 = url.update_query([("a", "3"), ("a", "4")])

assert str(u2) == "http://example.com/path?a=3&a=4"


# mod operator


def test_update_query_with_mod_operator():
url = URL("http://example.com/")
assert str(url % {"a": "1"}) == "http://example.com/?a=1"
assert str(url % [("a", "1")]) == "http://example.com/?a=1"
assert str(url % "a=1&b=2") == "http://example.com/?a=1&b=2"
assert str(url % {"a": "1"} % {"b": "2"}) == "http://example.com/?a=1&b=2"
assert str(url % {"a": "1"} % {"a": "3", "b": "2"}) == "http://example.com/?a=3&b=2"
assert str(url / "foo" % {"a": "1"}) == "http://example.com/foo?a=1"
3 changes: 3 additions & 0 deletions yarl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,9 @@ def __truediv__(self, name):
self._val._replace(path=new_path, query="", fragment=""), encoded=True
)

def __mod__(self, query):
return self.update_query(query)

def __bool__(self) -> bool:
return bool(
self._val.netloc or self._val.path or self._val.query or self._val.fragment
Expand Down
1 change: 1 addition & 0 deletions yarl/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class URL:
def __gt__(self, other: Any) -> bool: ...
def __hash__(self) -> int: ...
def __truediv__(self, name: str) -> URL: ...
def __mod__(self, query: Query) -> URL: ...
def is_absolute(self) -> bool: ...
def is_default_port(self) -> bool: ...
def origin(self) -> URL: ...
Expand Down