Alistair Martin
Alistair Martin

Reputation: 155

Combining single-dispatch and protocols

I'm having some issues combining single-dispatch overloads with a protocol for structural typing based on having a specific attribute. I have constructed the following snippet to give an idea of what I'm attempting.

from typing_extensions import Protocol
from functools import singledispatch


class HasFoo(Protocol):
    foo: str


class FooBar:
    def __init__(self):
        self.foo = 'bar'


@singledispatch
def f(_) -> None:
    raise NotImplementedError


@f.register
def _(item: HasFoo) -> None:
    print(item.foo)


x = FooBar()
f(x)

The above raises the NotImplementedError instead of the print statement as desired. I've tried various modifications to the above with no success. Any help would be very appreciated.

Upvotes: 5

Views: 416

Answers (1)

Simon Hawe
Simon Hawe

Reputation: 4539

That apparently doesn't work. Single dispatch uses the MRO (Method resolution order) to find out if a given instance matches a registered type. However, the protocol is not part of the MRO, hence python will not find it. To make it part of the MRO you could inherit from it, but that is not what Protocols are meant to be used for (though I think it also doesn't cost anything).

Upvotes: 4

Related Questions