pythonduck-typing

Why can't Python infer that my class follows the Sequence protocol?


I would expect that if I write a class that implements all methods needed for a Sequence as per https://docs.python.org/3.10/library/collections.abc.html, that Python would use duck-typing to know that an instance of it is a Sequence, but I find that is not the case:

from collections.abc import Sequence

class MySequence:
    def __getitem__(self, ix):
        pass
    
    def __iter__(self):
        pass
    
    def __len__(self):
        pass
    
    def __contains__(self, val):
        pass
    
    def __reversed__(self):
        pass
    
    def count(self, val):
        pass
    
    def index(self, val):
        pass

seq = MySequence()
print(isinstance(seq, Sequence))

This prints False instead of True. Why?


Solution

  • No duck-typing here. If you're not inheriting from the Sequence abc at all, then you'll need to register your class:

    Sequence.register(MySequence)
    

    From the docs point 3) concerning duck-typing:

    Some simple interfaces are directly recognizable by the presence of the required methods

    ...

    Complex interfaces do not support this last technique because an interface is more than just the presence of method names. Interfaces specify semantics and relationships between methods that cannot be inferred solely from the presence of specific method names. For example, knowing that a class supplies __getitem__, __len__, and __iter__ is insufficient for distinguishing a Sequence from a Mapping.