build_query and parse_query round-trip

Python
"""Build and parse query strings with merged defaults and repeated keys."""
from typing import Any
from urllib.parse import parse_qs, urlencode


def build_query(params: dict[str, Any], defaults: dict[str, Any] | None = None) -> str:
    """Encode params over defaults; list values repeat the key."""
    merged = {**(defaults or {}), **params}
    pairs = [
        (key, item)
        for key, value in merged.items()
        if value is not None
        for item in (value if isinstance(value, (list, tuple)) else [value])
    ]
    return urlencode(pairs, doseq=True)


def parse_query(query: str, *, keep_blank: bool = False) -> dict[str, Any]:
    """Read '?a=1&a=2' into {'a': ['1', '2']}; single values unwrap to strings."""
    parsed = parse_qs(query.lstrip("?"), keep_blank_values=keep_blank)
    return {key: values[0] if len(values) == 1 else values for key, values in parsed.items()}


if __name__ == "__main__":
    query = build_query({"page": 2, "tag": ["py", "api"]}, {"page": 1, "sort": "new"})
    print(query)  # page=2&sort=new&tag=py&tag=api
    print(parse_query(query))  # {'page': '2', 'sort': 'new', 'tag': ['py', 'api']}