Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URL comparison is order-based for query parameters #280

Open
LVerneyPEReN opened this issue Mar 4, 2021 · 2 comments
Open

URL comparison is order-based for query parameters #280

LVerneyPEReN opened this issue Mar 4, 2021 · 2 comments

Comments

@LVerneyPEReN
Copy link

Hi,

I am using boltons to do URL comparisons, being agnostic of the URL representation, and it works great so far except for query parameters.

Typically, with percent encoding, this is working as expected:

>>> a = boltons.urlutils.URL('http://example.com/foo, bar')
>>> b = boltons.urlutils.URL('http://example.com/foo%2C%20bar')
>>> a == b
True

However, when taking query parameters into account, the comparison seems to be ordered (while I would expect the order of query parameters to have no impact). See:

>>> a = boltons.urlutils.URL('http://example.com/foo, bar?foo=bar&bar=foo')
>>> b = boltons.urlutils.URL('http://example.com/foo%2C%20bar?bar=foo&foo=bar')
>>> a == b
False

I solved the issue with a bit of monkey patching, but is there a reason for having an ordered comparison here?

My solution:

def query_params_dict_eq_monkey_patch(self, other):
    """
    >>> a = boltons.urlutils.URL('http://example.com/foo, bar?foo=bar&bar=foo')
    >>> b = boltons.urlutils.URL('http://example.com/foo%2C%20bar?bar=foo&foo=bar')
    >>> a == b
    True
    """
    return dict(self) == dict(other)
boltons.urlutils.QueryParamDict.__eq__ = query_params_dict_eq_monkey_patch

Thanks!

@mahmoud
Copy link
Owner

mahmoud commented May 17, 2021

Thanks for the detailed report! I'm fairly certain that by the standard, query parameter order is significant. In practice, when query parameters are all unique, an unordered dict is almost always a sufficient representation. However, multiple values for the same key are sometimes turned into/treated as a list of values, and the natural significance of order is a lot more apparent there. That's the reason URL uses an OrderedMultiDict instead of a normal dict.

Still, I think you've got a valid use case. Have you considered subclassing URL and adding your __eq__ there instead?

@LVerneyPEReN
Copy link
Author

I'm fairly certain that by the standard, query parameter order is significant.

Indeed, https://stackoverflow.com/a/25687581.

Have you considered subclassing URL and adding your eq there instead?

Sure, it does the trick for now. So basically, the issue is solved on my side :) Not sure if it's worth having anything related in Boltons?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants