Base class looks like this (code comes from Django, but the question isn’t Django specific):
class BaseModelForm(BaseForm):
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
initial=None, error_class=ErrorList, label_suffix=':',
empty_permitted=False, instance=None):
class ModelForm(BaseModelForm):
__metaclass__ = ModelFormMetaclass
Derived class looks like this:
class MyForm(forms.ModelForm):
def __init__(self, data=None, files=None, *args, **kwargs):
super(EdocForm, self).__init__(data, files, *args, **kwargs)
self.Meta.model.get_others(data, files, kwargs.get('instance', None))
If the coder passes instance as a kwargs this is all fine and should work, but what if they don’t do that and pass it in args instead? What is a sane way to extract instance when dealing with *args and **kwargs? Admittedly in this case the chances of instance being in args is small, but if it was the 3rd argument instead of the 5th (not counting self).
If you insist on accepting
*args, one way to handle this situation if gettinginstancematters toMyForm, is to explicitly includeinstanceas a keyword argument toMyForm, add instance to kwargs, and then pass up kwargs.Note that, if someone put instance as the third positional argument, they would be making a very explicit error, since instance is the last argument to BaseModelForm.
However, a better way to handle this situation would be to specifically not allow additional positional arguments. E.g.:
That way,
MyFormcan only be called with up to 2 positional arguments. Any more and the Python interpreter will generate aTypeError: <func> takes exactly 2 arguments (# given).If you need to use the
instanceargument, you should explicitly include it in the keyword arguments toMyForm. Failing that, you at least should note it in the doc string to the function.If you’re subclassing BaseModelForm and it has a
self.instancevariable, you could access it directly via super. E.g.self.instance = super(EdocForm, self).instance. That way, you let the superclass handle whatever it needs to do with instance and grab the instance for yourself post-processing. (be careful about syntax with super…you need both the class and self)