Show HN: Rust-Like Traits in Python
github.com
github.com
Choosing among competing interfaces overriding the MRO was a runtime configuration option, often using adapters to wrap other objects. This turns out to be handy when implementing a CMS extended with 3rd-party plugins that aren't written with each other in mind. Fun times!
https://zopecomponent.readthedocs.io/en/latest/narr.html
However in the end abstract base classes and class decorators take you a long way. zope.component power is only useful for complex frameworks like Plone CMS and Pyramid.
The "Sheep" class never inherits from "Animal" or "ImplAnimalForSheep", nor does its body reference them in any way, so how does it get the "talk" method?
Why not just give `Impls` a special attribute:
class ExampleImpl(Foo, metaclass=Impl):
target = Bar
Or do the entire thing via a decorator: @impl_for(Bar)
class ExampleImpl(Foo):
pass
?EDIT: actually, your examples wouldn't work as-is, since it would result in circular references (something Python isn't well-equipped to handle). Your target names would need to be strings instead of the actual class.
EDIT2: I have updated the code to allow for another syntax:
class AnyImplNameIWant(MyTrait, metaclass=Impl, target="MyStruct"):
...
It would certainly be nicer if `MyStruct` didn't need to be a string of course. I really think these options are mostly down to taste, so I'll just have to trust that this alternative reads sufficiently more nicely. @impl(Sheep, Animal)
class ImplAnimalForSheep:
...
or something?It probably needn't even be a separate class - just decorate the relevant methods (or the `Sheep` class itself) `@impl(Animal)` and check the necessary ones are implemented on instantiation.
"Impls have a strict naming convention, like ImplMyTraitForMyStruct. This is used to automate the list of implementations for MyStruct; you don't need to explicitly list any superclasses of MyStruct, just based on the Impl name it will inherit from all relevant Impls."
That's the role typing.Protocol plays, as well. Protocols are like ABCs, but using structural typing.