-
Notifications
You must be signed in to change notification settings - Fork 104
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
Add parameter without removing duplicated value in query string #126
Add parameter without removing duplicated value in query string #126
Conversation
…rs to URL query string
Codecov Report
@@ Coverage Diff @@
## master #126 +/- ##
==========================================
+ Coverage 95.3% 95.37% +0.06%
==========================================
Files 7 7
Lines 469 476 +7
Branches 93 97 +4
==========================================
+ Hits 447 454 +7
Misses 15 15
Partials 7 7
|
@rennerocha Could you add tests for the case where the key you are adding or replacing already exists among the parameters? Specially when it exists twice in the existing URL. I think only the first match is replaced, I’m not sure whether or not that is intended. |
You are right: Not sure what should be the correct behavior. Another option is remove the duplicates and return Any other thoughts? |
Well, given the name of the function and the previous behavior, I suspect that we should remove all existing parameters matching the specified name. |
@Gallaecio Did the change as you suggested. The only drawback is that it will not be possible to add duplicated values using this function, as the input is a dictionary. |
w3lib/url.py
Outdated
del params[name] | ||
elif name not in changing_params: | ||
new_args.append((name, value)) | ||
new_args.extend([(name, value) for name, value in params.items()]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for list comprehension here, only new_args.extend(params.items())
is enough.
You can use list(params.items())
to make it explicit.
Also, new_args += params.items()
would be more pythonic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I removed the side-effect over the input parameters, I need this list comprehension to filter the values that I don't want (the modified ones). Replaced .extend
to +=
anyway.
w3lib/url.py
Outdated
new_args = OrderedDict(args) | ||
new_args.update(params) | ||
new_args = [] | ||
changing_params = list(params.keys()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is it converted to a list? a set would be more correct and .keys()
method call is not required: changing_params = set(params)
.
w3lib/url.py
Outdated
new_args = [] | ||
changing_params = list(params.keys()) | ||
for name, value in args: | ||
if name in params.keys(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to get the list of .keys()
, it should be possible to test like if name in params
if params
is a dict.
w3lib/url.py
Outdated
for name, value in args: | ||
if name in params.keys(): | ||
new_args.append((name, params[name])) | ||
del params[name] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think mutating params
is a good idea, I'd prefer to flag seen params in another set and ignore them on line 215.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something in the line of
def _add_or_replace_parameters(url, params):
parsed = urlsplit(url)
args = parse_qsl(parsed.query, keep_blank_values=True)
acc = []
seen = set()
for k, v in args:
if k in params:
if k not in seen:
acc.append((k, params[k]))
seen.add(k)
else:
acc.append((k, v))
acc += ((k, v) for k, v in params.items() if k not in seen)
query = urlencode(acc)
return urlunsplit(parsed._replace(query=query))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think mutating
params
is a good idea, I'd prefer to flag seen params in another set and ignore them on line 215.
As the input argument is a dict, it makes sense that it shouldn't be modified by the function. I included a test case to avoid this scenario as well.
Codecov Report
@@ Coverage Diff @@
## master #126 +/- ##
==========================================
+ Coverage 95.3% 95.37% +0.06%
==========================================
Files 7 7
Lines 469 476 +7
Branches 93 97 +4
==========================================
+ Hits 447 454 +7
Misses 15 15
Partials 7 7
|
Codecov Report
@@ Coverage Diff @@
## master #126 +/- ##
==========================================
- Coverage 95.3% 95.19% -0.12%
==========================================
Files 7 7
Lines 469 479 +10
Branches 93 98 +5
==========================================
+ Hits 447 456 +9
Misses 15 15
- Partials 7 8 +1
|
w3lib/url.py
Outdated
if name in params: | ||
if name not in seen_params: | ||
new_args.append((name, params[name])) | ||
seen_params.add(name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💄 It does not matter much, but…
seen_params.add(name) | |
seen_params.add(name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's good 💅 :)
w3lib/url.py
Outdated
if name not in seen_params: | ||
new_args.append((name, params[name])) | ||
seen_params.add(name) | ||
elif name not in changing_params: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was checking the coverage data, and I may be missing something, but I think this could be replaced by an else
, and the changing_params
variable may be unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
else
block should be fine per #126 (comment) and
no need for changing_params
either
@rennerocha We may have a new release soon 😀. Please let us know if you think you’ll have time to address #126 (comment) in the following days. |
Hi! Yes, I will work on this comment in the next days. Hopefully on time for the next release! |
@Gallaecio I removed the nested conditional. I believe it is clearer now. Could you please review it again? |
Hi guys @dangra @ejulio @Gallaecio, how about merge this pull? |
This should fix #125.