Description
pyrefly reports bad-override errors for DRF's (Django REST Framework) ModelSerializer.Meta class pattern. This is a false positive - like marshmallow's Schema.Meta (see #2054, which was fixed), DRF's Meta is a configuration class pattern, not a true inheritance override.
Reproduction
from rest_framework import serializers
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=100)
class MySerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ["name"]
Requires django-stubs and djangorestframework-stubs installed (pyrefly's built-in Django support reads them directly, no mypy plugin involved).
Actual behavior
ERROR Class member `MySerializer.Meta` overrides parent class `ModelSerializer` in an inconsistent manner [bad-override]
|
| class Meta:
| ^^^^
|
`MySerializer.Meta` has type `type[MySerializer.Meta]`, which is not assignable to `type[ModelSerializer.Meta]`, the type of `ModelSerializer.Meta`
Expected behavior
No error - this is the single most common way to write a DRF ModelSerializer (every DRF tutorial and the official docs use exactly this pattern).
Why this is a false positive
Same root cause as #2054: DRF's own ModelSerializer.Meta inner class is not something a concrete serializer is meant to inherit from. Confirmed at runtime:
>>> from rest_framework import serializers
>>> hasattr(serializers.ModelSerializer, "Meta")
False
ModelSerializer.Meta only exists in djangorestframework-stubs' .pyi file - not in the real, running rest_framework package. Writing class Meta(serializers.ModelSerializer.Meta): to "properly" inherit therefore crashes at import time with AttributeError: type object 'ModelSerializer' has no attribute 'Meta' - it's not a safe workaround, just a way to trade a type error for a runtime error.
The stubs also declare a generic ModelSerializer[_MT] with Meta.model: ClassVar[type[_MT]], so even parameterizing the generic and annotating model: ClassVar[type[MyModel]] = MyModel explicitly on a non-inheriting Meta still fails the same check (tested on pyrefly 1.2.0).
Real-world impact
This affects effectively every DRF ModelSerializer in any typed Django+DRF codebase - i.e. every project that installs djangorestframework-stubs for pyrefly to get real ORM/serializer typing at all.
Workaround
Can suppress with bad-override = "ignore" in [tool.pyrefly.errors], but that hides real override bugs elsewhere in the codebase, which isn't an acceptable tradeoff for us.
Environment
- pyrefly version: 1.2.0
- djangorestframework-stubs version: 3.18.0
- django-stubs version: 6.1.0
- Python: 3.14
Related
Description
pyrefly reports
bad-overrideerrors for DRF's (Django REST Framework)ModelSerializer.Metaclass pattern. This is a false positive - like marshmallow'sSchema.Meta(see #2054, which was fixed), DRF'sMetais a configuration class pattern, not a true inheritance override.Reproduction
Requires
django-stubsanddjangorestframework-stubsinstalled (pyrefly's built-in Django support reads them directly, no mypy plugin involved).Actual behavior
Expected behavior
No error - this is the single most common way to write a DRF
ModelSerializer(every DRF tutorial and the official docs use exactly this pattern).Why this is a false positive
Same root cause as #2054: DRF's own
ModelSerializer.Metainner class is not something a concrete serializer is meant to inherit from. Confirmed at runtime:ModelSerializer.Metaonly exists indjangorestframework-stubs'.pyifile - not in the real, runningrest_frameworkpackage. Writingclass Meta(serializers.ModelSerializer.Meta):to "properly" inherit therefore crashes at import time withAttributeError: type object 'ModelSerializer' has no attribute 'Meta'- it's not a safe workaround, just a way to trade a type error for a runtime error.The stubs also declare a generic
ModelSerializer[_MT]withMeta.model: ClassVar[type[_MT]], so even parameterizing the generic and annotatingmodel: ClassVar[type[MyModel]] = MyModelexplicitly on a non-inheritingMetastill fails the same check (tested on pyrefly 1.2.0).Real-world impact
This affects effectively every DRF
ModelSerializerin any typed Django+DRF codebase - i.e. every project that installsdjangorestframework-stubsfor pyrefly to get real ORM/serializer typing at all.Workaround
Can suppress with
bad-override = "ignore"in[tool.pyrefly.errors], but that hides real override bugs elsewhere in the codebase, which isn't an acceptable tradeoff for us.Environment
Related
Schema.Meta, same root cause, already fixed for marshmallow specifically)