[Django] #28346: Misleading error message when validator cannot be serialized

3 views
Skip to first unread message

Django

unread,
Jun 29, 2017, 3:06:08 AM6/29/17
to django-...@googlegroups.com
#28346: Misleading error message when validator cannot be serialized
------------------------------------------+------------------------
Reporter: Peter Inglesby | Owner: nobody
Type: Uncategorized | Status: new
Component: Migrations | Version: 1.11
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
------------------------------------------+------------------------
I have a validator factory that looks like this:

{{{
def validate_max_words(max_words):
def validator(value):
num_words = len(value.split())
if num_words > max_words:
raise ValidationError(f'Field is too long: {num_words} words /
{max_words} limit')
return validator
}}}

and I would like to use it in a field definition like this:

{{{
description = models.TextField(validators=[validate_max_words(300)])
}}}

However, when running a migration to create the model in question, I get
the following error:

{{{
ValueError: Could not find function validator in myapp.validators.
Please note that due to Python 2 limitations, you cannot serialize unbound
method functions (e.g. a method declared and used in the same class body).
Please move the function into the main module body to use migrations.
For more information, see
https://docs.djangoproject.com/en/1.11/topics/migrations/#serializing-
values
}}}

The error message is misleading, in that it assumes that because the
validator cannot be serialized, it must be an unbound method. However,
this is not the case -- the validator is instead a function that's
returned by another function.

--
Ticket URL: <https://code.djangoproject.com/ticket/28346>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jun 29, 2017, 10:23:30 AM6/29/17
to django-...@googlegroups.com
#28346: Misleading error message when validator cannot be serialized
-------------------------------------+-------------------------------------

Reporter: Peter Inglesby | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Migrations | Version: 1.11
Severity: Normal | Resolution:

Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* type: Uncategorized => Cleanup/optimization


Comment:

That error message is gone in master because Python 2 support is removed.
The new error is something like "ValueError: Could not find function
validator in app.models." I'm not sure if it's possible to serialize this
case, if the error message could be improved, or if we can close this
ticket. What do you think?

--
Ticket URL: <https://code.djangoproject.com/ticket/28346#comment:1>

Django

unread,
Jun 29, 2017, 12:48:02 PM6/29/17
to django-...@googlegroups.com
#28346: Misleading error message when validator cannot be serialized
-------------------------------------+-------------------------------------

Reporter: Peter Inglesby | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: Migrations | Version: 1.11
Severity: Normal | Resolution: invalid

Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Peter Inglesby):

* status: new => closed
* resolution: => invalid


Comment:

Poking about at this some more, I think it is possible to serialize the
validator in my example, because the `validate_max_words(300)` returns a
function object that has a `__closure__` attribute which contains bindings
to the environment in which the function object was created.

I'm not sure though how reliable this would be for less simple examples,
and given how easy it is to work around, I think the new error message is
good enough.

--
Ticket URL: <https://code.djangoproject.com/ticket/28346#comment:2>

Reply all
Reply to author
Forward
0 new messages