I guess it depends on whether you consider duck typing to be "passes the static type checker" or "it works the same".
I guess it depends on whether you consider duck typing to be "passes the static type checker" or "it works the same".
Also this:
"Because Animal is a Protocol, any class that defines feed() becomes an Animal"
is slightly incorrect.
By default, protocols are only relevant for static type analysis, but you _can_ enable runtime instance checking using the @runtime_checkable decorator.
(So you can do "if isinstance(foo, Animal):...", but AFAIK this decorator comes with a performance penalty)
Whether it makes sense to use that is a different question, but it is possible :)
See https://docs.python.org/3/library/typing.html#typing.runtime...
it looks rather gross to me, and more dangerous than useful. why bother with a half check that can only see if the methods/attributes are present, but that can't guarantee they do what you need? better to not offer such a check at all, I should think.
but I'm not a fan of a great number of things python has been doing over the last some years.
if you were going to do such a thing (perhaps to allow type-safe callbacks from untyped code), I would think a wrapper would be the proper method, that checks the incoming parameters and the outgoing return value, raising an error if those are of the wrong sorts, and possibly further wrapping if something was declared to fit a protocol.
Shhhh! You're spoiling how it's the most interesting language the author knows in terms of inheritance.