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
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)
- the same behaviour is with similar generic types -
list[str]
- without the migration being created/applied, validation works as expected
Hi michael, i will try to reproduce it, and see if i can give to you a suggestion of how to solve it, i will test if this is still happening on newer versions, in this case i will use the 5.2