-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Feature proposal: Golang style interfaces #497
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is definitely a good idea and I've been thinking about something like this for a long time. There's already So your example could be written like this: from typing import Protocol
class StringJoiner(Protocol):
def join_two_strings(self, string1: str, string2: str) -> str:
"""Join two strings together."""
pass
... # The rest would be identical This could be implemented in a few phases. In the first phase, we wouldn't have generic protocols (such as |
Some ideas about a basic implementation:
|
Awesome, I will start digging into Protocols, and will probably have a lot On Sat, Nov 8, 2014 at 5:22 PM, Jukka Lehtosalo [email protected]
|
I recently did a project in Go and fell in love with its implicit interfaces. They're the greatest idea in OOP in recent history. @thisfred really nailed it when he said,
This is where Python's
To work properly, it requires subclassing: >>> import abc
>>> class Foo(metaclass=abc.ABCMeta):
... @abc.abstractmethod
... def do_something():
... return NotImplemented
...
>>> class Bar(Foo):
... pass
...
>>> class Baz(Foo):
... def do_something():
... return True
...
>>> bar = Bar()
Traceback (most recent call last):
File "<ipython-input-24-482989d4cfb5>", line 1, in <module>
bar = Bar()
TypeError: Can't instantiate abstract class Bar with abstract methods do_something
>>> baz = Baz()
>>> Alternatively, one can use the
Riffing on the example above: >>> import abc
>>> class Foo(metaclass=abc.ABCMeta):
... @abc.abstractmethod
... def do_something():
... return NotImplemented
...
>>> class Bar:
... pass
...
>>> Foo.register(Bar)
<class '__main__.Bar'>
>>> bar = Bar()
>>> bar.do_something()
Traceback (most recent call last):
File "<ipython-input-29-2015a90099fc>", line 1, in <module>
bar.do_something()
AttributeError: 'Bar' object has no attribute 'do_something' I'm curious if there's been any more discussion in this project on the idea of implicit interfaces. Issue #552 indicates maybe it's become even more difficult. |
This is a duplicate of python/typing#11. |
@gvanrossum Apologies, thanks for pointing me to the full discussion. This issue was a top hit for me for Go interfaces and Python. |
Just to be explicit, mypy currently supports structural subtyping through |
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:
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.
The text was updated successfully, but these errors were encountered: