﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
31155	Named groups in choices are not properly validated in case of non str typed values.	sakkada	Mariusz Felisiak	"In case of using typed choices and string value to store it (in my case it is multiple values stored in char field as JSON) it is possible to catch error while run `makemigrations` (`_check_choices` error):

{{{
main.MultiValueFieldModel.multi_value_field_integer_with_grouped_choices: (fields.E005) 'choices' must be an iterable containing (actual value, human readable name) tuples.
}}}

Looking deeper into the django code, we see actual error message: `'int' object is not iterable` and it happens in this block of code (https://github.com/django/django/blob/aa6c620249bc8c2a6245c8d7b928b05e7e5e78fc/django/db/models/fields/__init__.py#L271-L275):

{{{
if self.max_length is not None and group_choices:
    choice_max_length = max(
        choice_max_length,
        *(len(value) for value, _ in group_choices if isinstance(value, str)),
    )
}}}

If we have CharField (any other with max_length defined) and grouped choices with non str typed values like:
{{{
choices=(
    ('one', ((1, 'One',), (11, 'Eleven',),),),
    ('two', ((2, 'Two',), (22, 'Twenty two',),),),
)
}}}
we will have the situation, when `max` function receives only one integer value (`choice_max_length`), because `(len(value) for value, _ in group_choices if isinstance(value, str))` will return empty generator, and that is why error `'int' object is not iterable` raises (`max` function waits iterable if there is only one argument).

Code block:
{{{
choice_max_length = max(
    choice_max_length,
    *(len(value) for value, _ in group_choices if isinstance(value, str)),
)
}}}
in this case works like:
{{{
choice_max_length = max(
    choice_max_length,
    *[],
)
}}}
which is incorrect.

The simples **solution** is to add one additional argument to `max` function, which will be usefull only in this partucular situation:
{{{
choice_max_length = max(
    choice_max_length, 0,
    *(len(value) for value, _ in group_choices if isinstance(value, str)),
)
}}}
"	Bug	closed	Database layer (models, ORM)	3.0	Release blocker	fixed	choices	pope1ni	Ready for checkin	1	0	0	0	0	0
