Description
I love mypy and think it's a great addition to every Python developers toolkit. One thing I think could be a nice addition is lightweight interfaces such as exist in Go:
https://golang.org/ref/spec#Interface_types
For those unfamiliar with that language, the salient part (IMO) is that in Go you can declare an interface, and use it in place of a type declaration, and any object that implements all methods (with the right type signature) that make up the interface will be a valid value for arguments with that type declaration, so as an example:
from typing import Interface
class StringJoiner(Interface):
def join_two_strings(self, string1: str, string2: str) -> str:
"""Join two strings together."""
pass
class ImplementsStringJoiner(object):
"""Implicitly implements the interface."""
def join_two_strings(self, string1: str, string2: str) -> str:
"""Join two strings together."""
return string1 + string2
class DoesNotImplementStringJoiner(object):
"""Does not have the required method."""
pass
def some_function(joiner: StringJoiner, string1: str, string2: str) -> str:
return joiner.join_two_strings(string1, string2)
# this should be fine
some_function(ImplementsStringJoiner(), 'foo', 'bar')
# this should not
some_function(DoesNotImplementStringJoiner(), 'foo', 'bar')
What I like about these is that they really embody a static version of Python's ducktyping, where it matters what the object does, rather than what type it is, or what it inherits from.
Here is a very naive first stab, definitely not ready for a PR, (really just a proof of concept, no tests, likely some broken edge cases, and less than pretty code):
https://github.com/thisfred/mypy/compare/golang-style-interfaces?expand=1
If you think these are a good idea at all, I would love to hear feedback on what these interfaces could look like (a base class works, but they could also be class decorators,) and where in mypy the best place to implement them would be.