[HN Gopher] Show HN: Rust-Like Traits in Python
       ___________________________________________________________________
        
       Show HN: Rust-Like Traits in Python
        
       Author : xrudelis
       Score  : 16 points
       Date   : 2021-11-21 20:03 UTC (2 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | xrudelis wrote:
       | This is an idea I had while thinking about how flexible Python
       | inheritance is. I decided to turn it into a weekend project, and
       | now it is my first open-source package. I hope someone finds it
       | useful!
        
       | miohtama wrote:
       | Something that fills the same need as traits have been available
       | for Python in the form of zope.component architecture for some
       | decades now
       | 
       | 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.
        
       | webmaven wrote:
       | This reminds me of Python interfaces, which were inspired by Zope
       | interfaces.
       | 
       | 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!
        
       | orf wrote:
       | How does this differ in practice from typing.Protocol?
        
       | _dain_ wrote:
       | I don't understand how this works:
       | https://github.com/xrudelis/pytrait/blob/master/examples/bas...
       | 
       | 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?
        
         | homarp wrote:
         | it's the naming convention that does it.
         | 
         | "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."
        
         | aldanor wrote:
         | Some pretty horrible string / 'registry' metaclass hackery:
         | https://github.com/xrudelis/pytrait/blob/master/pytrait/impl...
        
           | xrudelis wrote:
           | That's right. The reason for this is that it's a lot of
           | boilerplate if you were to require listing every relevant
           | Impl block as a superclass of your struct. I also, as a
           | bonus, like enforcing a consistent class naming style.
        
             | Diggsey wrote:
             | That's not a great reason to use strings to identify
             | classes though...
             | 
             | 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          ?
        
               | xrudelis wrote:
               | I think these are all equally good. The Impl's name
               | should never need to be referred to, so ultimately the
               | choice should be based on what's easiest to read.
               | 
               | 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.
        
               | aldanor wrote:
               | Correction: what's easiest to read to someone who hasn't
               | carefully read every single line of your library.
               | Verbosity is not always bad, if it yields clarity.
        
               | luoc wrote:
               | I'd go for the decorator approach for its explicitness.
               | It reads like plain English without having a deeper
               | understanding of the concepts. Also, it does not pollute
               | the implementors namespace. Even if one argues for the
               | naming convention solution, one has to admit that it
               | causes confusion for most people stumbling over it for
               | the first time.
        
       ___________________________________________________________________
       (page generated 2021-11-21 23:00 UTC)