Opened 17 years ago

Last modified 6 days ago

#12134 assigned Bug

contrib.admin.RelatedFieldWidgetWrapper.__deepcopy__() should copy() the widget attrs

Reported by: James Bennett Owned by: Garvit Sharma
Component: contrib.admin Version: 1.1
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Otherwise it ends up with a shallow copy which reuses the same attrs dict across separate widget instances, playing merry hell with form classes which want to change widget attrs on a per-(form)-instance basis.

Attachments (1)

12134.diff​ (489 bytes ) - added by James Bennett 17 years ago.

Download all attachments as: .zip

Change History (12)

by James Bennett, 17 years ago

Attachment: 12134.diff​ added

comment:1 by Brian Rosner, 17 years ago

Triage Stage: Unreviewed → Accepted

comment:2 by Luke Plant, 17 years ago

I think we need some more analysis of why this patch is correct/needed. Here are some simplified extracts of current code:

class RelatedFieldWidgetWrapper(forms.Widget):
    def __init__(self, widget, rel, admin_site):
        self.attrs = widget.attrs
        self.widget = widget
        # <snip>

    def __deepcopy__(self, memo):
        obj = copy.copy(self)
        obj.widget = copy.deepcopy(self.widget, memo)
        obj.attrs = self.widget.attrs
        memo[id(self)] = obj
        return obj

This means:

wrapper1 = RelatedFieldWidgetWrapper(some_widget, some_rel, some_admin_site)
wrapper2 = copy.deepcopy(wrapper1) # as happens when widget is copied via BaseForm.__init__()

assert wrapper1.attrs is wrapper1.widget.attrs
assert wrapper2.attrs is wrapper2.widget.attrs
assert wrapper1.widget is not wrapper2.widget

That all seems to be correct. The attached patch would actually break the second assert, which I'm pretty sure will break the ability of the class instance to work as a wrapper.

comment:3 by Matt McClanahan, 16 years ago

Severity: → Normal
Type: → Bug

comment:4 by Aymeric Augustin, 15 years ago

UI/UX: unset

Change UI/UX from NULL to False.

comment:5 by Aymeric Augustin, 15 years ago

Easy pickings: unset

Change Easy pickings from NULL to False.

comment:6 by Tim Graham, 11 years ago

I think #26213 gives a demonstration of a behavior which this ticket may fix.

comment:7 by Garvit Sharma, 5 weeks ago

Owner: changed from nobody to Garvit Sharma
Status: new → assigned

Claiming — patch ready, PR to follow.

comment:9 by Garvit Sharma, 6 days ago

Triage Stage: Accepted → Ready for checkin

Yes, I’ve addressed the requested changes. I’ve now changed the triage state to “Ready for checkin” and set “Needs improvement” to false.

comment:10 by Clifford Gama, 6 days ago

Triage Stage: Ready for checkin → Accepted

Hi Garvit, please refer to the ​Triage Workflow. RFC is a state marked by a reviewer, not the PR author. Thanks!

in reply to:  10 comment:11 by Garvit Sharma, 6 days ago

Replying to Clifford Gama:

Hi Garvit, please refer to the ​Triage Workflow. RFC is a state marked by a reviewer, not the PR author. Thanks!

Thanks Clifford, understood. I'll leave the triage stage for a reviewer.

Note: See TracTickets for help on using tickets.
Back to Top