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