Skip to content

Serializer does not respect Python's C3 MRO #7735

Closed
@iamahuman

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions