[Python-3000] iostack and Oh Oh

Josiah Carlson jcarlson at uci.edu
Sat Dec 9 10:53:33 CET 2006


"Steven Bethard" <steven.bethard at gmail.com> wrote:
> For the sake of DRY, I'd prefer to see::
> 
>     class MyMapping:
>         def mapping.__getitem__(self, key):
>             ...
>         def mapping.__len__(self):
>             ...

I'd prefer to see...

    class MyMapping:
        @implements(mapping)
        def __getitem__(self, key):
            ...
        
        @implements(mapping)
        def __len__(self):
            ...

Because then we don't need a new dotted name syntax proposal.  The
3-argument type call would need to learn how to handle methods with
@implements(interface) behavior defined, but other than that, I think it
would work as-is.


 - Josiah

P.S. Here's a 10 minute implementation of the above semantics that is
*almost* backwards compatible with Python 2.3 (except for the decorator
thing, which Python 2.3 has to do without).


_type = type

def make_interface(name, methods):
    return _type(name, (object,),
             dict([(nam, object()) for nam in methods]))

mapping = make_interface('mapping', mapping_methods)
sequence = make_interface('sequence', sequence_methods)
#...

_supports = {}

def supports(cls, interface):
    if interface in _supports:
        return cls in _supports[interface]
    return False

def implements(*interfaces):
    def foo(fcn):
        return implements_wrapper(fcn, interfaces)
    return foo

class implements_wrapper(object):
    __slots__ = ['fcn', 'interfaces']
    def __init__(self, fcn, interfaces):
        self.fcn = fcn
        self.interfaces = interfaces
    def __call__(self):
        return self.fcn, self.interfaces

def type(*args):
    if len(args) != 3:
        return _type(*args)
    name, bases, dct = args
    dct2 = {}
    for nam, obj in dct.items():
        if isinstance(obj, implements_wrapper):
            f, i = obj()
            dct2[nam] = i
            dct[nam] = f
    cls = _type(name, bases, dct)
    for nam, i in dct2.iteritems():
        for j in i:
            #default dict that produced sets would work well here
            _supports.setdefault(getattr(i, nam), {})[cls] = None
    return cls

__builtins__.type = type



More information about the Python-3000 mailing list