Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

whisperity/Unter

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“ŸπŸ”ƒ Unter

PyPI Licence

A Python module of decorators to allow base classes to selectively enforce their primacy even in the face of derived classes overriding implementations.

Overview

The unter module provides a set of decorators that can be applied to the base classes and its methods in order to ensure that calls of a method overridden in a derived class nevertheless invoke the base class implementation instead.

Normal Python method resolution order resolves the most-overridden method first when a call is made, and the ability for base classes to provide a common frame around an implementation customisable by derived classes is only achievable through either the explicit use of super(), or via template functions.

With unter, the base class can break the normal method resolution order and enforce its own implementation to be called first, while leaving the derived class to visually appear as-if to override the base class method (instead of _*_impl-style methods).

Installation

pip install unter

Quick-start

Current, Pythonic way of doing things

class Base:
    def method(self):
        print("Base.method() called")
        self._method()  # Calls the derived class method
        print("Base.method() over!")

    def _method(self):
        print("Base._method() - not overridden")

class Derived(Base):
    def _method(self):
        print("Derived._method() - overridden")

    # Whoops, should never do this by accident, otherwise, the implementation
    # would break!
    # def method(self):
    #     ...


>>> Base().method()
Base.method() called
Base._method() - not overridden
Base.method() over!

>>> Derived().method()
Base.method() called
Derived._method() - overridden
Base.method() over!

Basic decoration and primacy

from unter import unter

@unter.enable
class Base:
    @unter.attorney
    def method(self) -> int:
        print("Base.method() called")
        i = 1 + unter().method()
        print("Base.method() over!", i)
        return i

class Derived:
    def method(self) -> int:
        print("Derived.method() called")
        i = 4
        print("Derived.method() over!", i)
        return i

>>> print(Derived().method())
Base.method() called
Derived.method() called
Derived.method() over! 4
Base.method() over! 5
5

Why?

unter is a highly specialised tool to invert the normal method resolution behaviour of class hierarchies. Specialised tools are things that one needs rarely, but when they are needed, they are needed badly.

About

πŸ“ŸπŸ”ƒ A Python module of decorators to allow base classes to selectively hijack and invert inheritance and overriding, enforcing the primacy of a base implementation even in the face of derived overriding classes

Topics

Resources

Stars

Watchers

Forks

Releases

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.