Skip to content
Open
Show file tree
Hide file tree
Changes from all 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: 2 additions & 2 deletions src/hyperlink/_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -1904,7 +1904,7 @@ def set(self, name, value=None):
# Preserve the original position of the query key in the list
q = [(k, v) for (k, v) in self.query if k != name]
idx = next(
(i for (i, (k, v)) in enumerate(self.query) if k == name), -1
(i for (i, (k, v)) in enumerate(self.query) if k == name), len(q)
)
q[idx:idx] = [(name, value)]
return self.replace(query=q)
Expand Down Expand Up @@ -2315,7 +2315,7 @@ def set(self, name, value=None):
"Return a new DecodedURL with query parameter *name* set to *value*"
query = self.query
q = [(k, v) for (k, v) in query if k != name]
idx = next((i for (i, (k, v)) in enumerate(query) if k == name), -1)
idx = next((i for (i, (k, v)) in enumerate(query) if k == name), len(q))
q[idx:idx] = [(name, value)]
return self.replace(query=q)

Expand Down
31 changes: 26 additions & 5 deletions src/hyperlink/test/test_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from typing import Any, Iterable, Optional, Text, Tuple, cast

from .common import HyperlinkTestCase
from .. import URL, URLParseError
from .. import URL, DecodedURL, URLParseError
from .._url import inet_pton, SCHEME_PORT_MAP


Expand Down Expand Up @@ -1317,13 +1317,34 @@ def test_twisted_compat(self):
def test_set_ordering(self):
# type: () -> None

# TODO
url = URL.from_text("http://example.com/?a=b&c")
url = url.set("x", "x")
url = url.add("x", "y")
assert url.to_text() == "http://example.com/?a=b&x=x&c&x=y"
# Would expect:
# assert url.to_text() == u'http://example.com/?a=b&c&x=x&x=y'
assert url.to_text() == "http://example.com/?a=b&c&x=x&x=y"

def test_set_new_query_parameter(self):
# type: () -> None
"""Both URL types append new parameters without moving existing ones."""
for url_type in (URL, DecodedURL):
for query in ((), (("a", "1"),), (("a", "1"), ("b", None))):
url = url_type.from_text("https://example.com/").replace(
query=query
)
result = url.set("new", "value")
self.assertEqual(result.query, query + (("new", "value"),))
self.assertEqual(url.query, query)

def test_set_existing_query_parameter(self):
# type: () -> None
"""Replacing duplicate parameters retains the first occurrence's position."""
for url_type in (URL, DecodedURL):
url = url_type.from_text(
"https://example.com/?a=1&x=old&b=2&x=other"
)
result = url.set("x", "new")
self.assertEqual(
result.query, (("a", "1"), ("x", "new"), ("b", "2"))
)

def test_schemeless_path(self):
# type: () -> None
Expand Down