This makes me a little sad. So, a few observations:<p>- The use of metaclasses for (almost?) every feature in this library makes it prone to metaclass conflicts. What if I want to inherit from two classes that use two different features from the library?<p><pre><code>    &gt;&gt;&gt; class MetaOne(type):
    ...     pass
    ...
    &gt;&gt;&gt; class MetaTwo(type):
    ...     pass
    ...
    &gt;&gt;&gt; class One(metaclass=MetaOne):
    ...     pass
    ...
    &gt;&gt;&gt; class Two(metaclass=MetaTwo):
    ...     pass
    ...
    &gt;&gt;&gt; class Both(One, Two):
    ...     pass
    ...
    Traceback (most recent call last):
      File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
    TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
</code></pre>
- I&#x27;ve never had a problem with other programmers accidentally changing my &quot;constants&quot; (eg. THE_THINGS_IN_ALL_CAPS) and I&#x27;ve never had a problem with other programmers accidentally changing my &quot;private&quot; attributes (eg. _prepended_with_underscore). Naming conventions are good enough for those purposes, in my experience.<p>- And when they&#x27;re not, there&#x27;s __name_mangling, which is sufficient to avoid the need for a &#x27;final&#x27;. Compilers can make use of &#x27;final&#x27;, which is why final exists in Cython. I&#x27;m not sure the purpose in pure Python.<p>- There&#x27;s no need for the distinction between an Abstract class and and Interface. Python already supports multiple inheritance of abstract classes.