#21740 closed Cleanup/optimization (fixed)
client.py uses mutable default arguments, which is bad practice
Reported by: | sleepydragon | Owned by: | anonymous |
---|---|---|---|
Component: | Testing framework | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
In django/test/client.py there are several methods that have data={} in their argument lists. The {} dictionary is a mutable type and it is not recommended to use mutable objects as default arguments. This is because each invocation of the method where data is not specified will use the same dict object. This enables completely unrelated method calls to affect each other.
The fix that I recommend is to instead use data=None in the argument list for the affected methods and then in the method body check for None and create a new dict if it is None. That way each method invocation gets their own, local dict object. I have attached a patch for review.
I'm fairly new to Django so it's possible that data=None is actually a meaningful value. If that is the case then this approach will need to be tweaked a bit.
Attachments (2)
Change History (12)
by , 11 years ago
Attachment: | client_mutable_argument_fix_01.patch added |
---|
comment:1 by , 11 years ago
Triage Stage: | Unreviewed → Accepted |
---|---|
Version: | 1.6 → master |
comment:2 by , 11 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
by , 11 years ago
Attachment: | client_mutable_argument_fix_02.patch added |
---|
comment:4 by , 11 years ago
To make sense, a test should fail before applying the patch, which is not the case here. I'll commit an amended patch soon (without tests).
comment:5 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:6 by , 10 years ago
Resolution: | fixed |
---|---|
Status: | closed → new |
This fix actually changed the behavior of the test client. I have some tests about HTTP header handling, which I pass an empty string as the request content. So it is like:
self.client.post(url, '', content_type='application/json', **{ 'CUSTOM_HEADER': header_1, })
Before this change everything worked fine.
The request.body became "{}" after this change. That is because when data is an empty string
data or {}
returns {} instead of ""
comment:8 by , 10 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
@tony-zhu FYI, it's preferred to open a new ticket for new bugs after a ticket is released.
PR looks good me; it just needs release notes.
comment:9 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
It looks like the
dict
creation should be moved at theRequestFactory
level which also suffer from the same issues.