# Extension method helpers and proof of concept. import inspect MODULE_REGISTRY = set() METHOD_REGISTRY = {} def get_execution_scope(): frm = inspect.stack()[2] return inspect.getmodule(frm[0]) def extends(cls): def inner(func): METHOD_REGISTRY.setdefault(cls, set()).add(func) return func return inner def using(): MODULE_REGISTRY.add(get_execution_scope()) class MyObject: # Base class that supports extension methods. def __getattribute__(self, name): try: return super().__getattribute__(name) except AttributeError: mod = get_execution_scope() if mod in MODULE_REGISTRY: xmethods = METHOD_REGISTRY.get(type(self), set()) for func in xmethods: if func.__name__ == name: return func.__get__(self) raise class Demo(MyObject): pass @extends(Demo) def xmethod(self): return "called extension method"