-
Notifications
You must be signed in to change notification settings - Fork 125
Python 3.14: RuntimeError: dictionary changed size during iteration during JsonModel class creation (schema_for_fields iterates cls.__dict__) #763
Description
Summary
On Python 3.14, redis-om-python can crash at import/startup time when constructing a JsonModel, raising:
RuntimeError: dictionary changed size during iteration
This occurs during schema generation (__init_subclass__ → redisearch_schema → schema_for_fields) while iterating directly over the live class namespace (cls.__dict__). The code inside the loop mutates FieldInfo objects, but does not change the class dict size; the size change appears to be coming from concurrent class construction/mutation (likely Pydantic model construction still injecting attributes into the class namespace while redis-om iterates it).
I appreciate that you aren't claiming Python 3.14 compatability at the present time, so this was discovered during my attempts to review my app's third-party dependencies for Python 3.14 compatability.
Environment
- Python: 3.14
- redis-om-python: 0.3.5
- Pydantic: 2.12.5
- Django: 5.2.10 app importing a
JsonModelat startup (error happens at import time) - This fails both on AWS Elastic Beanstalk and also locally on MacOS
Stack trace (trimmed)
File ".../redis_cloud/models.py", line 9, in <module>
class ShortInterest(JsonModel):
File ".../redis_om/model/model.py", line 1916, in __init_subclass__
cls.redisearch_schema()
File ".../redis_om/model/model.py", line 1985, in redisearch_schema
schema_parts = [schema_prefix] + cls.schema_for_fields()
File ".../redis_om/model/model.py", line 1995, in schema_for_fields
for name, field in cls.__dict__.items():
RuntimeError: dictionary changed size during iteration
Code path / failing loop
The failure happens iterating the live cls.__dict__ during model construction:
for name, field in cls.__dict__.items():
if isinstance(field, FieldInfo):
if not field.annotation:
field.annotation = cls.__annotations__.get(name)
fields[name] = fieldThe field.annotation = ... assignment mutates the FieldInfo object, but should not add/remove keys on cls.__dict__, so it should not cause a “changed size during iteration” error. The class namespace appears to be modified externally during this phase (likely Pydantic injecting attributes during construction).
I note that in the current version in the repo, this code has moved to aredis_om/model/model.py, but that failing for loop is identical.
Reproduction outline
- Define a
JsonModelin a Django app - Import the module at startup
__init_subclass__triggers schema generation- Python 3.14 raises
RuntimeError: dictionary changed size during iterationwhen iteratingcls.__dict__