3 from types
import ClassType
, InstanceType
4 classtypes
= type, ClassType
7 """Create a simple generic function"""
11 def _by_class(*args
, **kw
):
12 cls
= args
[0].__class
__
13 for t
in type(cls
.__name
__, (cls
,object), {}).__mro
__:
14 f
= _gbt(t
, _sentinel
)
15 if f
is not _sentinel
:
18 return func(*args
, **kw
)
20 _by_type
= {object: func
, InstanceType
: _by_class
}
24 """Decorator to add a method that will be called for type `t`"""
25 if not isinstance(t
, classtypes
):
27 "%r is not a type or class" % (t
,)
30 if _by_type
.setdefault(t
,f
) is not f
:
32 "%r already has method for type %r" % (func
, t
)
46 """Decorator to add a method that will be called for object `o`"""
48 if _by_object
.setdefault(id(o
), (o
,f
))[1] is not f
:
50 "%r already has method for object %r" % (func
, o
)
56 def dispatch(*args
, **kw
):
57 f
= _gbo(id(args
[0]), _sentinel
)
59 for t
in type(args
[0]).__mro
__:
60 f
= _gbt(t
, _sentinel
)
61 if f
is not _sentinel
:
64 return func(*args
, **kw
)
66 return f
[1](*args
, **kw
)
68 dispatch
.__name
__ = func
.__name
__
69 dispatch
.__dict
__ = func
.__dict
__.copy()
70 dispatch
.__doc
__ = func
.__doc
__
71 dispatch
.__module
__ = func
.__module
__
73 dispatch
.when_type
= when_type
74 dispatch
.when_object
= when_object
75 dispatch
.default
= func
76 dispatch
.has_object
= lambda o
: id(o
) in _by_object
77 dispatch
.has_type
= lambda t
: t
in _by_type
85 return doctest
.DocFileSuite(
87 optionflags
=doctest
.ELLIPSIS|doctest
.REPORT_ONLY_FIRST_FAILURE
,