Opened 13 years ago
Closed 13 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 , 13 years ago
Component: | Uncategorized → Forms |
---|
comment:2 by , 13 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.