Opened 8 years ago
Closed 8 years ago
#27919 closed Bug (fixed)
Decide if attrs (and possibly others) are named or positional parameters in new widget rendering code
Reported by: | Claude Paroz | Owned by: | Tim Graham |
---|---|---|---|
Component: | Forms | Version: | 1.11 |
Severity: | Release blocker | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Discussed on IRC:
claudep: in the new form widget rendering code, we often have attrs=None in signatures, but then passed as positional argument in various calls claudep: I wonder if this is a good practice claudep: this can lead to some issues when overriding methods and useing *args, or **kwargs claudep: thoughts? MarkusH: claudep: I didn't look at the code, but from what you say I can imagine that leading to issues
A concrete example:
class CustomSelect(Select): def create_option(self, name, value, label, selected, index, attrs=None, **kwargs): if 'somestring' in label: if attrs is None: attrs = {} attrs['disabled'] = True return super().create_option(name, value, label, selected, index, attrs=attrs, **kwargs)
leads to
... File ".../django/forms/widgets.py", line 671, in get_context context = super(Select, self).get_context(name, value, attrs) File ".../django/forms/widgets.py", line 627, in get_context context['widget']['optgroups'] = self.optgroups(name, context['widget']['value'], attrs) File ".../django/forms/widgets.py", line 599, in optgroups attrs=attrs, TypeError: create_option() got multiple values for argument 'attrs'
Change History (15)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
Yes, I know the reason of the error. But when I read the method signature and see subindex=None, attrs=None
, I'm interpreting those as keyword arguments, hence my wrong subclass implementation.
comment:3 by , 8 years ago
Triage Stage: | Unreviewed → Accepted |
---|
It looks like the calling code in ChoiceWidget.optgroups()
should be self.create_option(..., subindex=subindex, ...)
rather than passing subindex
as a position argument. Would that solve the issue?
comment:4 by , 8 years ago
Yes, that was the question. I think this happens at several other places, with attrs
and/or subindex
. In my experience, it's better to always pass arguments with a default value as keyword arguments, but I didn't find yet any reference supporting that feeling.
comment:5 by , 8 years ago
My guess is the current code is the result of some refactoring along the way. As far as I saw, create_option()
is only called in that one spot, so presumably subindex
could be an arg
instead, if there isn't a use case for calling the method without it. I would say use your best judgment and clean things up as you see fit.
comment:6 by , 8 years ago
Claude, do you plan to propose a patch before Monday's release candidate? If not, I'll look at this.
comment:7 by , 8 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:8 by , 8 years ago
Has patch: | set |
---|
PR -- possibly more could be done but I think that PR covers the public APIs.
comment:9 by , 8 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
Thanks Tim, I'm sorry not being able to be more active at this stage of the 1.11 release.
comment:15 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Your method signature is missing the 6th positional argument
subindex
. Instead you haveattrs
as the 6th positional argument, so it receives both a positional argument (which should actually be thesubindex
argument) and a keyword argument.