PEP: Specialization Syntax

Bengt Richter bokr at oz.net
Mon Aug 8 20:14:25 EDT 2005


On Mon, 08 Aug 2005 16:18:50 -0400, Nicolas Fleury <nid_oizo at yahoo.com_removethe_> wrote:

>Bengt Richter wrote:
>> On Sun, 07 Aug 2005 21:41:33 -0400, Nicolas Fleury <nid_oizo at yahoo.com_removethe_> wrote:
>>>I mean should angle brackets <> like in C++, or another operator, be 
>>>used instead?
>> 
>> I am getting the feeling that your PEP is about a means to do something C++-like
>> in python, not necessarily to enhance python ;-) IOW, it seems like you
>> want the [<new syntax>] to do something like C++ <type_spec> in templates?
>
>Yes, exactly.  Actually Guido also mentionned pointy brackets:
>http://www.artima.com/weblogs/viewpost.jsp?thread=86641
>
>> (BTW, I have nothing against giving python new capabilities (quite the reverse),
>> but not by grafting limbs from other animals ;-)
>
>If I look at a very recent blog entry of Guido, it seems the idea is 
>still in the air:
>http://www.artima.com/weblogs/viewpost.jsp?thread=92662
>
>> Maybe you want hidden name-mangling of function defs according to arg types
>> and corresponding dispatching of calls? I am afraid I am still not clear
>> on the fundamental motivation for all this ;-)
>
>I wrote the PEP to see if was the only one that would benefit from 
>generic types *before* having optional static typing in the language.
>
>It seems I'm the only one;)
>
>According to blog entry 86641, Guido himself is prototyping with 
>__getitem__.  However, I cannot do the same, because the framework I use 
>is much more complete and keyword arguments are a must.
>

Here is a decorator object to set up function call dispatch according to type.
It only uses positional arguments, but could be fleshed out, I think.
Not tested beyond what you see ;-)

----< typedispatcher.py >-------------------------------------------------
# typedispatcher.py
"""
Provides a decorator to dispatch function
calls according to arg types and signature.
Example usage:
    foodisp = TypeDispatcher() # instance dedicated to foo variants
    @foodisp(a=int, b=str)
    def foo(a, b):
        assert type(a) is int and type(b) is str
        return (a,b)
    @foodisp(a=str, b=str)
    def foo(a, b):
        assert type(a) is str and type(b) is str
        return (a,b)
     
"""
class TypeDispatcher(object):
    def __init__(self):
        self.dispdict = {}
    def __call__(self, **kwtypes):
        self.kwtemp = kwtypes
        return self.dodeco
    def dodeco(self, f):
        if not hasattr(self, 'name'):
            self.name = f.func_name
        if f.func_name != self.name:
            raise ValueError('This TypeDispatcher instance decorates only functions named %r' % self.name)
        sig = tuple((self.kwtemp[argname] for argname in f.func_code.co_varnames[:f.func_code.co_argcount]))
        assert len(set([f.func_name]+list(f.func_name for f in self.dispdict.values())))
        self.dispdict[sig] = f
        return self.docall
    def docall(self, *args):
        sig = tuple(map(type, args))
        try: f = self.dispdict[sig]
        except KeyError:
            raise TypeError('no function %r with signature %r' % (self.name, sig))
        return f(*args)
        
def test():
    try:
        foodisp = TypeDispatcher()
        @foodisp(a=int, b=str)
        def foo(a, b):
            assert type(a) is int and type(b) is str
            return 'foo(int, str):', (a,b)
        @foodisp(a=str, b=str)
        def foo(a, b):
            assert type(a) is str and type(b) is str
            return 'foo(str, str):', (a,b)
        @foodisp()
        def foo():
            return 'foo()', ()
        print foo(123, 'hello')
        print foo('hi','there')
        print foo()
        print foo(456, 789)
    except Exception, e:
        print 'Exception %s: %s' % (e.__class__.__name__, e)
    try:
        @foodisp()
        def bar(): pass
    except Exception, e:
        print 'Exception %s: %s' % (e.__class__.__name__, e)


if __name__ == '__main__':
    test()
--------------------------------------------------------------------------

Result:

[17:12] C:\pywk\ut>py24 typedispatcher.py
('foo(int, str):', (123, 'hello'))
('foo(str, str):', ('hi', 'there'))
('foo()', ())
Exception TypeError: no function 'foo' with signature (<type 'int'>, <type 'int'>)
Exception ValueError: This TypeDispatcher instance decorates only functions named 'foo'


Regards,
Bengt Richter



More information about the Python-list mailing list