Salome HOME
Merge from V6_main 01/04/2013
[modules/kernel.git] / src / KERNEL_PY / kernel / deprecation.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License.
9 #
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 #
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #
21 """
22 This module provides several functions to indicate the deprecation of a
23 module, a method or a function.
24
25 Example::
26
27     from salome.kernel.deprecation import deprecated
28
29     @deprecated("Deprecated since version 6.3.0. Consider replacement with "
30                 "newFunction()")
31     def oldFunction():
32       ...
33
34 """
35
36 import sys
37 import warnings
38 import inspect
39 import os
40
41 from salome.kernel import termcolor
42
43 msg_seedoc = "See documentation for possible replacements."
44
45 def __deprecated_with_msg(func, msg):
46
47     def new_func(*args, **kwargs):
48         if len(inspect.stack()) > 1:
49             callingfunc = inspect.stack()[1][3]
50         else:
51             callingfunc = "CORBA middleware"
52         warnings.warn(
53             ("Call to deprecated function %(funcname)s of module " +
54              "%(modname)s (called from %(callingfunc)s).\n  %(msg)s") % {
55                 'funcname': func.__name__,
56                 'modname': func.__module__,
57                 'callingfunc': callingfunc,
58                 'msg': msg,
59             },
60             category = DeprecationWarning,
61             stacklevel = 2
62         )
63         return func(*args, **kwargs)
64     return new_func
65
66 def deprecated(msg = msg_seedoc):
67     """
68     This is a decorator which can be used to mark functions
69     as deprecated. It will result in a warning being emitted
70     when the function is used. The message in parameter will
71     be displayed and should indicate how this function can be
72     replaced. If the terminal can display colors, the warning
73     messages will appear in blue.
74     """
75     def make_dep(f):
76         if is_called_by_sphinx():
77             return f
78         else:
79             g = __deprecated_with_msg(f, msg)
80             g.__name__ = f.__name__
81             g.__doc__ = f.__doc__
82             g.__dict__.update(f.__dict__)
83             return g
84     return make_dep
85
86 def deprecated_module(msg = msg_seedoc):
87     """
88     This function can be used to mark a module as deprecated.
89     It must be called explicitly at the beginning of the deprecated
90     module. It will result in a warning being emitted. The message
91     in parameter will be displayed and should indicate how this
92     module can be replaced. If the terminal can display colors,
93     the warning messages will appear in blue.
94     """
95     if not is_called_by_sphinx():
96         warnings.warn(
97             "Importation of deprecated module %(modname)s.\n  %(msg)s" % {
98                 'modname': inspect.getmodulename(inspect.stack()[1][1]),
99                 'msg': msg,
100             },
101             category = DeprecationWarning,
102             stacklevel = 5
103         )
104
105 def is_called_by_sphinx():
106     """
107     Determine if the calling code is ultimately called by sphinx to generate
108     documentation. The result can be used to conditionally inhibit the
109     decorators or some Salome-related imports that fail when called outside
110     Salome.
111     """
112     calling_file = inspect.stack()[len(inspect.stack())-1][1]
113     basename = os.path.basename(calling_file)
114     return (basename == "sphinx-build")
115
116
117 def __show_colored_warning(message, category, filename,
118                            lineno, file = sys.stderr, line = None):
119     str = warnings.formatwarning(message, category, filename, lineno, line)
120     if category == DeprecationWarning and termcolor.canDisplayColor(file):
121         file.write(termcolor.makeColoredMessage(str, termcolor.BLUE))
122     else:
123         file.write(str)
124
125 # Enable warnings for deprecated functions and modules (in Python 2.7, they
126 # are disabled by default)
127 warnings.filterwarnings("always", "Call to *", DeprecationWarning)
128 warnings.filterwarnings("always", "Importation of *", DeprecationWarning)
129 warnings.showwarning = __show_colored_warning