Commits

Christophe de Vienne committed 500c438

Add arbitrary argument for dispatch and methods support

Comments (0)

Files changed (2)

     False
 
 
+Generic methods
+---------------
+
+::
+
+    >>> class Z(object):
+    ...     def __init__(self, prec):
+    ...         self.prec = prec
+    ...
+    ...     @generic
+    ...     def serialize(self, o):
+    ...         return str(o)
+    ...
+    ...     @serialize.when_type(float)
+    ...     def serialize_float(self, o):
+    ...         return '%%.%df' % self.prec % o
+
+    >>> Z(2).serialize(5)
+    '5'
+
+    >>> Z(2).serialize(5.0)
+    '5.00'
+
+    >>> Z(4).serialize(5.0)
+    '5.0000'
+
+
 Limitations
 -----------
 
+import inspect
+
 __all__ = ["generic"]
 try:
     from types import ClassType, InstanceType
     classtypes = type
     InstanceType = None
 
-def generic(func):
+def generic(func, argpos=None):
     """Create a simple generic function"""
 
+    if argpos is None:
+        if hasattr(func, 'argpos'):
+            argpos = func.argpos
+        else:
+            argnames = inspect.getargspec(func)[0]
+            if argnames and argnames[0] == 'self':
+                argpos = 1
+            else:
+                argpos = 0
+
     _sentinel = object()
 
     def _by_class(*args, **kw):
-        cls = args[0].__class__
+        cls = args[argpos].__class__
         for t in type(cls.__name__, (cls,object), {}).__mro__:
             f = _gbt(t, _sentinel)
             if f is not _sentinel:
 
 
     def dispatch(*args, **kw):
-        f = _gbo(id(args[0]), _sentinel)
+        f = _gbo(id(args[argpos]), _sentinel)
         if f is _sentinel:
-            for t in type(args[0]).__mro__:
+            for t in type(args[argpos]).__mro__:
                 f = _gbt(t, _sentinel)
                 if f is not _sentinel:
                     return f(*args, **kw)
     dispatch.default = func
     dispatch.has_object = lambda o: id(o) in _by_object
     dispatch.has_type   = lambda t: t in _by_type
+    dispatch.argpos = argpos
     return dispatch