1# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org) 2# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php 3 4class classinstancemethod(object): 5 """ 6 Acts like a class method when called from a class, like an 7 instance method when called by an instance. The method should 8 take two arguments, 'self' and 'cls'; one of these will be None 9 depending on how the method was called. 10 """ 11 12 def __init__(self, func): 13 self.func = func 14 self.__doc__ = func.__doc__ 15 16 def __get__(self, obj, type=None): 17 return _methodwrapper(self.func, obj=obj, type=type) 18 19class _methodwrapper(object): 20 21 def __init__(self, func, obj, type): 22 self.func = func 23 self.obj = obj 24 self.type = type 25 26 def __call__(self, *args, **kw): 27 assert 'self' not in kw and 'cls' not in kw, ( 28 "You cannot use 'self' or 'cls' arguments to a " 29 "classinstancemethod") 30 return self.func(*((self.obj, self.type) + args), **kw) 31 32 def __repr__(self): 33 if self.obj is None: 34 return ('<bound class method %s.%s>' 35 % (self.type.__name__, self.func.func_name)) 36 else: 37 return ('<bound method %s.%s of %r>' 38 % (self.type.__name__, self.func.func_name, self.obj)) 39