Opened 14 years ago
Closed 14 years ago
#17161 closed Bug (invalid)
Call super in BaseForm.__init__
| Reported by: | Owned by: | nobody | |
|---|---|---|---|
| Component: | Forms | Version: | 1.3 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Currently /django/forms/forms.py BaseForm.__init__ (as well as a fair number of other classes) does not call super().__init__. This makes it impossible to create form mixins.
Consider:
from django import forms
class FormMixin(object):
def __init__(self, *args, **kwargs):
super(FormMixin, self).__init__(*args, **kwargs)
self.my_flag = true
class MyForm(forms.Form, FormMixin):
field1 = forms.CharField()
class MyModelForm(forms.ModelForm, FormMixin):
class Meta(object):
model = SpamModel
Because of python's mro the init() in the mixin never gets called because BaseForm.__init__ does not call it.
Ideally, all classes in django that have an __init__() should also call super().__init__()
Change History (2)
comment:1 by , 14 years ago
| Component: | Uncategorized → Forms |
|---|
comment:2 by , 14 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
The suggested change would break very badly, since object.__init__ does not accept any parameters and you will get a TypeError.
Unfortunately, multiple inheritance is pretty badly broken in Python for __init__. See http://freshfoo.com/blog/object__init__takes_no_parameters
The preferred solution is to avoid implementing __init__ in your mixin class, and to avoid using super inside the __init__ of the class that inherits from object. If you do need to inherit two __init__ methods, use a subclass that overrides __init__ and explicitly calls each __init__, as per
http://www.artima.com/weblogs/viewpost.jsp?thread=281127
e.g.
class AwithB(A, B): def __init__(self, arg_for_A, arg_for_B): A.__init__(arg_for_A) B.__init__(arg_for_B)
Therefore, the current code is as good as its going to get.
I believe if you reorder the superclasses, adding the call to super() is not necessary. For example:
I would normally add a mixin in this order anyway since I normally have the mixin override the superclass instead of inserting a mixin to be called by the superclass.