Skip to content

Serializer does not respect Python's C3 MRO #7735

Description

@iamahuman

Checklist

Steps to reproduce

from rest_framework import serializers

# dummy fields for demonstration
class AllProductsField(serializers.Field): pass
class SupportedProductsField(serializers.Field): pass

class CommonSerializer(serializers.Serializer):
    product = AllProductsField()

class CustomerAccess(CommonSerializer):
    def validate_product(self, value):
        return do_something(value)

class TicketSerializer(CommonSerializer):
    product = SupportedProductsField()

class CustomerTicketSerializer(CustomerAccess, TicketSerializer):
    pass

print('[' + ' > '.join(x.__name__ for x in CustomerTicketSerializer.mro()[:4]) + ']')
print(str(CustomerTicketSerializer()))

Expected behavior

[CustomerTicketSerializer > CustomerAccess > TicketSerializer > CommonSerializer]
CustomerTicketSerializer():
    product = SupportedProductsField()

Actual behavior

[CustomerTicketSerializer > CustomerAccess > TicketSerializer > CommonSerializer]
CustomerTicketSerializer():
    product = AllProductsField()

Remarks

For compatibility I think this behavior shall be kept for a while, but not respecting Python MRO may turn out to be astonishing for some users and even lead to potential security problems (e.g. choice-limiting queryset not properly overridden).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions