Package logilab :: Package common :: Module deprecation
[frames] | no frames]

Source Code for Module logilab.common.deprecation

  1  """Deprecation utilities. 
  2   
  3  :copyright: 2006-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 
  4  :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr 
  5  :license: General Public License version 2 - http://www.gnu.org/licenses 
  6  """ 
  7  __docformat__ = "restructuredtext en" 
  8   
  9  import sys 
 10  from warnings import warn 
11 12 -class class_deprecated(type):
13 """metaclass to print a warning on instantiation of a deprecated class""" 14
15 - def __call__(cls, *args, **kwargs):
16 msg = getattr(cls, "__deprecation_warning__", 17 "%s is deprecated" % cls.__name__) 18 warn(msg, DeprecationWarning, stacklevel=2) 19 return type.__call__(cls, *args, **kwargs)
20
21 22 -def class_renamed(old_name, new_class, message=None):
23 """automatically creates a class which fires a DeprecationWarning 24 when instantiated. 25 26 >>> Set = class_renamed('Set', set, 'Set is now replaced by set') 27 >>> s = Set() 28 sample.py:57: DeprecationWarning: Set is now replaced by set 29 s = Set() 30 >>> 31 """ 32 clsdict = {} 33 if message is None: 34 message = '%s is deprecated, use %s' % (old_name, new_class.__name__) 35 clsdict['__deprecation_warning__'] = message 36 try: 37 # new-style class 38 return class_deprecated(old_name, (new_class,), clsdict) 39 except (NameError, TypeError): 40 # old-style class 41 class DeprecatedClass(new_class): 42 """FIXME: There might be a better way to handle old/new-style class 43 """ 44 def __init__(self, *args, **kwargs): 45 warn(message, DeprecationWarning, stacklevel=2) 46 new_class.__init__(self, *args, **kwargs)
47 return DeprecatedClass 48
49 50 -def class_moved(new_class, old_name=None, message=None):
51 """nice wrapper around class_renamed when a class has been moved into 52 another module 53 """ 54 if old_name is None: 55 old_name = new_class.__name__ 56 if message is None: 57 message = 'class %s is now available as %s.%s' % ( 58 old_name, new_class.__module__, new_class.__name__) 59 return class_renamed(old_name, new_class, message)
60
61 -def deprecated(reason=None):
62 """Decorator that raises a DeprecationWarning to print a message 63 when the decorated function is called. 64 """ 65 def deprecated_decorator(func): 66 message = reason or 'this function is deprecated, use %s instead' 67 if '%s' in message: 68 message = message % func.func_name 69 def wrapped(*args, **kwargs): 70 warn(message, DeprecationWarning, stacklevel=2) 71 return func(*args, **kwargs)
72 return wrapped 73 return deprecated_decorator 74
75 @deprecated('replace deprecated_function(f,m) with deprecated(m)(f)') 76 -def deprecated_function(func, message=None):
77 return deprecated(message)(func)
78
79 -def moved(modpath, objname):
80 """use to tell that a callable has been moved to a new module. 81 82 It returns a callable wrapper, so that when its called a warning is printed 83 telling where the object can be found, import is done (and not before) and 84 the actual object is called. 85 86 NOTE: the usage is somewhat limited on classes since it will fail if the 87 wrapper is use in a class ancestors list, use the `class_moved` function 88 instead (which has no lazy import feature though). 89 """ 90 def callnew(*args, **kwargs): 91 from logilab.common.modutils import load_module_from_name 92 message = "object %s has been moved to module %s" % (objname, modpath) 93 warn(message, DeprecationWarning, stacklevel=2) 94 m = load_module_from_name(modpath) 95 return getattr(m, objname)(*args, **kwargs)
96 return callnew 97 98 obsolete = deprecated('obsolete is deprecated, use deprecated instead')(deprecated) 99