Here's a quick and dirty proof of concept I knocked up in about 20 
minutes, demonstrating that no deep compiler magic is needed. It's just 
a small change to the way `object.__getattribute__` works.

I've emulated it with my own base class, since `object` can't be 
monkey-patched.

The proof of concept is probably buggy and incomplete. It isn't intended 
to be a final, polished production-ready implementation. It's not 
implementation-agnostic: it requires the ability to inspect the call 
stack. If you're using IronPython, this may not work.

You will notice I didn't need to touch getattr to have it work, let 
alone hack the interpreter to make it some sort of magical construct. It 
all works through `__getattribute__`.

The registration system is just the easiest thing that I could throw 
together. There are surely better designs.

Run A.py to see it in action.


-- 
Steve
# 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"
from extmethods import Demo

instance = Demo()
print('(Module A) has xmethod?', hasattr(instance, 'xmethod'))

import B
B.main()

print('(Module A) has xmethod?', hasattr(instance, 'xmethod'))
from extmethods import using, Demo

using()

def main():
    obj = Demo()
    print('(Module B) has xmethod?', hasattr(obj, 'xmethod'))
    print(getattr(obj, 'xmethod')())
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/GINVBO2BIJNPSTT65DQ37YQF2PFZQYST/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to