Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django error: got multiple values for keyword argument

Tags:

I get the following error when instantiating a Django form with a the constructor overriden:

__init__() got multiple values for keyword argument 'collection_type' 

The __init__() function (shown below) is exactly as written this but with # code replaced with my logic. Asside from that I am essentially overriding the form's (which is a ModelForm) constructor.

def __init__(self, collection_type, user=None, parent=None, *args, **kwargs):     # code     super(self.__class__, self).__init__(*args, **kwargs) 

The call that creates the error is shown here:

form = CreateCollectionForm(     request.POST,      collection_type=collection_type,      parent=parent,      user=request.user ) 

I cannot see any reason why the error is popping up.

EDIT: Here is the full code for the constructor

def __init__(self, collection_type, user=None, parent=None, *args, **kwargs):     self.collection_type = collection_type     if self.collection_type == 'library':         self.user = user     elif self.collection_type == 'bookshelf' or self.collection_type == 'series':         self.parent = parent     else:         raise AssertionError, 'collection_type must be "library", "bookshelf" or "series"'     super(self.__class__, self).__init__(*args, **kwargs) 

EDIT: Stacktrace

Environment:  Request Method: POST Request URL: http://localhost:8000/forms/create_bookshelf/hello Django Version: 1.1.1 Python Version: 2.6.1 Installed Applications: ['django.contrib.auth',  'django.contrib.contenttypes',  'django.contrib.sessions',  'django.contrib.sites',  'libraries',  'users',  'books',  'django.contrib.admin',  'googlehooks',  'registration'] Installed Middleware: ('django.middleware.common.CommonMiddleware',  'django.contrib.sessions.middleware.SessionMiddleware',  'django.contrib.auth.middleware.AuthenticationMiddleware')   Traceback: File "/Library/Python/2.6/site-packages/django/core/handlers/base.py" in get_response   92.                 response = callback(request, *callback_args, **callback_kwargs) File "/Library/Python/2.6/site-packages/django/contrib/auth/decorators.py" in __call__   78.             return self.view_func(request, *args, **kwargs) File "/Users/marcus/Sites/marcuswhybrow.net/autolib/libraries/forms.py" in     create_collection   13.           form = CreateCollectionForm(request.POST,     collection_type=collection_type, user=request.user)  Exception Type: TypeError at /forms/create_bookshelf/hello Exception Value: __init__() got multiple values for keyword argument 'collection_type' 
like image 650
Marcus Whybrow Avatar asked Dec 21 '09 18:12

Marcus Whybrow


2 Answers

You're passing the collection_type argument in as a keyword argument, because you specifically say collection_type=collection_type in your call to the form constructor. So Python includes it within the kwargs dictionary - but because you have also declared it as a positional argument in that function's definition, it attempts to pass it twice, hence the error.

However, what you're trying to do will never work. You can't have user=None, parent=None before the *args dictionary, as those are already kwargs, and args must always come before kwargs. The way to fix it is to drop the explicit definition of collection_type, user and parent, and extract them from kwargs within the function:

def __init__(self, *args, **kwargs):     collection_type = kwargs.pop('collection_type', None)     user = kwargs.pop('user', None)     parent = kwargs.pop('parent', None) 
like image 167
Daniel Roseman Avatar answered Oct 24 '22 18:10

Daniel Roseman


It's pretty simple: you pass request.POST and only afterward you put argument for collection_type. Onto what request.POST will be put? There is not place for that. Watch this:

In [8]: class A:    ...:     def __init__(self, a, *args):    ...:         print a, args    ...:             ...:           In [9]: A(None, a=None) --------------------------------------------------------------------------- TypeError                                 Traceback (most recent call last)  /home/gruszczy/Programy/logbuilder/<ipython console> in <module>()  TypeError: __init__() got multiple values for keyword argument 'a' 

Move request.POST somewhere else in the call, but remember, that named arguments come after the ones, that aren't.

like image 38
gruszczy Avatar answered Oct 24 '22 18:10

gruszczy