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
13 """metaclass to print a warning on instantiation of a deprecated class"""
14
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
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
38 return class_deprecated(old_name, (new_class,), clsdict)
39 except (NameError, TypeError):
40
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
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):
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