Skip to content

Instantly share code, notes, and snippets.

@Tishka17
Created May 12, 2025 15:21
Show Gist options
  • Save Tishka17/4c2935b06aba743d81c161e75af1550b to your computer and use it in GitHub Desktop.
Save Tishka17/4c2935b06aba743d81c161e75af1550b to your computer and use it in GitHub Desktop.
class A:
def foo(self):
print("foo")
from cls import A
from trait import extend
@extend(A)
class B:
def bar(self):
print("extension method bar")
def bar(b):
b.bar() # ok
from cls import A
from ext import bar
a = A()
bar(a) # ok
a.bar() # error
import sys
from inspect import stack
def extend(cls1):
if not hasattr(cls1, "__extensions__"):
cls1.__extensions__ = {}
orig_getattribute = cls1.__getattribute__
def ext_getattr(self, name):
exts = type(self).__extensions__
module = stack(0)[1].filename
ext = exts.get(module)
if ext:
try:
return getattr(ext, name)
except AttributeError:
pass
return orig_getattribute(self, name)
cls1.__getattribute__ = ext_getattr
def patch(cls2):
module = sys.modules[cls2.__module__].__file__
cls1.__extensions__[module] = cls2()
return patch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment