#36695: Model field validator with a generic parameter causes infinite recursion
when making migrations
-------------------------------+--------------------------------------
Reporter: Michal Dabski | Type: Bug
Status: new | Component: Migrations
Version: 4.2 | 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
-------------------------------+--------------------------------------
Minimal code to reproduce (in `models.py`) in `Django==4.2.25`
{{{
from django.utils.deconstruct import deconstructible
from django.db import models
@deconstructible
class SchemaValidator:
def __init__(self, expected_type: type):
pass
def __call__(self, *args, **kwargs):
pass
class TestModel(models.Model):
config: dict[str, float] =
models.JSONField(validators=[SchemaValidator(dict[str, float])])
}}}
This triggers an error when running makemigrations:
{{{
$ ./manage.py makemigrations
C:\Users\Michal\src\mat-cms\.venv\Lib\site-
packages\django_downloadview\__init__.py:4: UserWarning: pkg_resources is
deprecated as an API. See
https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources
package is slated for removal as early as 2025-11-30. Refrain from using
this package or pin to Setuptools<81.
import pkg_resources
Migrations for 'audit_builder':
meg_forms\audit_builder\migrations\0083_alter_testmodel_config.py
- Alter field config on testmodel
Traceback (most recent call last):
File "C:\Users\Michal\src\mat-cms\.venv\Lib\site-
packages\django\db\migrations\serializer.py", line 214, in serialize
item_string, item_imports = serializer_factory(item).serialize()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Michal\src\mat-cms\.venv\Lib\site-
packages\django\db\migrations\serializer.py", line 214, in serialize
item_string, item_imports = serializer_factory(item).serialize()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Michal\src\mat-cms\.venv\Lib\site-
packages\django\db\migrations\serializer.py", line 214, in serialize
item_string, item_imports = serializer_factory(item).serialize()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Previous line repeated 996 more times]
File "C:\Users\Michal\src\mat-cms\.venv\Lib\site-
packages\django\db\migrations\serializer.py", line 389, in
serializer_factory
if isinstance(value, type_):
^^^^^^^^^^^^^^^^^^^^^^^^
RecursionError: maximum recursion depth exceeded
}}}
Debugging locally shows that:
* removing generic parameters from the `dict` type passed to
`SchemaValidator` does not trigger the error
* The loop happens in
`django.db.migrations.serializer.IterableSerializer.serialize`, it keeps
recursively invoking `serializer_factory(item).serialize()` with
`item='*dict[str, float]'` (`GenericAlias`)
--
Ticket URL: <
https://code.djangoproject.com/ticket/36695>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.