Coverage for /var/devmt/py/utils4_1.7.0/utils4/pywarnings.py: 100%

18 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-21 17:18 +0000

1#!/usr/bin/env python 

2# -*- coding: utf-8 -*- 

3""" 

4:Purpose: This module provides a simple wrapper around Python's built-in 

5 ``warnings`` library, and enables easy access to ignore a single 

6 or set of Python warnings. 

7 

8 While this module can be used to ignore a single warning, the true 

9 purpose of this module is to enable 'passive' warning control by 

10 having the ability to use a ``dict`` from your app's config file 

11 to control the display (or non-display) of warnings. Refer to the 

12 use cases below for an example. 

13 

14:Platform: Linux/Windows | Python 3.7+ 

15:Developer: J Berendt 

16:Email: support@s3dev.uk 

17 

18:Comments: n/a 

19 

20:Example: 

21 

22 Ignore a single warning manually:: 

23 

24 >>> import warnings # Imported for test demo only. 

25 >>> from utils4 import pywarnings 

26 

27 >>> pywarn = pywarnings.PyWarnings(ignore=True, categories='FutureWarning') 

28 >>> pywarn.ignore_warnings() 

29 

30 >>> # Test. 

31 >>> warnings.warn('', FutureWarning) 

32 

33 >>> # Re-enable warnings. 

34 >>> pywarn.reset_warnings() 

35 

36 >>> # Test. 

37 >>> warnings.warn('', FutureWarning) 

38 /tmp/ipykernel_48184/477226589.py:1: FutureWarning: 

39 warnings.warn('', FutureWarning) 

40 

41 

42 Ignore a list of warnings manually:: 

43 

44 >>> import warnings # Imported for test demo only. 

45 >>> from utils4 import pywarnings 

46 

47 >>> pywarn = pywarnings.PyWarnings(ignore=True, 

48 categories=['FutureWarning', 

49 'ResourceWarning', 

50 'UserWarning']) 

51 >>> pywarn.ignore_warnings() 

52 

53 >>> # Test. 

54 >>> for w in [FutureWarning, ResourceWarning, UserWarning]: 

55 >>> warnings.warn('', w) 

56 

57 >>> # Re-enable warnings. 

58 >>> pywarn.reset_warnings() 

59 

60 >>> # Test. 

61 >>> for w in [FutureWarning, ResourceWarning, UserWarning]: 

62 >>> warnings.warn('', w) 

63 /tmp/ipykernel_48184/3608596380.py:2: FutureWarning: 

64 warnings.warn('', w) 

65 /tmp/ipykernel_48184/3608596380.py:2: ResourceWarning: 

66 warnings.warn('', w) 

67 /tmp/ipykernel_48184/3608596380.py:2: UserWarning: 

68 warnings.warn('', w) 

69 

70 

71 Ignore a list of warnings manually using a ``dict`` from your app's config 

72 file:: 

73 

74 >>> import warnings # Imported for test demo only. 

75 >>> from utils4 import pywarnings 

76 

77 >>> config = {'key1': 'value1', 

78 'key2': 'value2', 

79 'py_warnings': {'ignore': True, 

80 'categories': ['FutureWarning', 

81 'ResourceWarning', 

82 'UserWarning']}, 

83 'keyN': ['value10', 'value11', 'value12']} 

84 

85 >>> pywarn = pywarnings.PyWarnings(config=config) 

86 >>> pywarn.ignore_warnings() 

87 

88 >>> # Test. 

89 >>> for w in [FutureWarning, ResourceWarning, UserWarning]: 

90 >>> warnings.warn('', w) 

91 

92 >>> # Re-enable warnings. 

93 >>> pywarn.reset_warnings() 

94 

95 >>> # Test. 

96 >>> for w in [FutureWarning, ResourceWarning, UserWarning]: 

97 >>> warnings.warn('', w) 

98 /tmp/ipykernel_48184/3608596380.py:2: FutureWarning: 

99 warnings.warn('', w) 

100 /tmp/ipykernel_48184/3608596380.py:2: ResourceWarning: 

101 warnings.warn('', w) 

102 /tmp/ipykernel_48184/3608596380.py:2: UserWarning: 

103 warnings.warn('', w) 

104 

105""" 

106 

107import warnings 

108 

109 

110class PyWarnings: 

111 """A simple wrapper around Python's built-in ``warnings`` library. 

112 

113 This class provides easy access to ignore a single, or set of Python 

114 warnings using your program's config file. 

115 

116 An example of your ``py_warnings`` config file key is shown below:: 

117 

118 {"py_warnings": {"ignore": True, 

119 "categories": ["PendingDeprecationWarning", 

120 "FutureWarning"]}} 

121 

122 - The ``ignore`` key toggles if the listed warnings are disabled. 

123 - The ``categories`` key is a list of Python warnings you wish 

124 to disable. This list **is not** case sensitive. 

125 

126 Args: 

127 ignore (bool): ``True`` will cause warnings to be ignored. This 

128 argument enables the ignoring/not ignoring of warnings, without 

129 needing to change your source code. 

130 

131 categories (Union[str, list]): A single category to ignore, or a list 

132 of categories. 

133 config (dict): A dictionary *containing* the following:: 

134 

135 {"py_warnings": {"ignore": true, 

136 "categories": ["PendingDeprecationWarning", 

137 "FutureWarning"]}} 

138 

139 :Required Arguments: 

140 Either the (``ignore`` *and* ``categories``) arguments must be 

141 provided, *or* the ``config`` argument on its own. 

142 

143 Note: 

144 Remember to call the :meth:`~reset_warnings` method at the end 

145 of your program! 

146 

147 """ 

148 

149 _WARN_TYPES = {'byteswarning': BytesWarning, 

150 'deprecationwarning': DeprecationWarning, 

151 'futurewarning': FutureWarning, 

152 'importwarning': ImportWarning, 

153 'pendingdeprecationwarning': PendingDeprecationWarning, 

154 'resourcewarning': ResourceWarning, 

155 'runtimewarning': RuntimeWarning, 

156 'syntaxwarning': SyntaxWarning, 

157 'unicodewarning': UnicodeWarning, 

158 'userwarning': UserWarning, 

159 'warning': Warning} 

160 

161 def __init__(self, ignore=None, categories=None, config=None): 

162 """Class initialiser.""" 

163 if config: 

164 self._ignore = config['py_warnings']['ignore'] 

165 self._categories = config['py_warnings']['categories'] 

166 else: 

167 self._ignore = ignore 

168 self._categories = categories 

169 

170 def ignore_warnings(self): 

171 """Ignore Python warnings. 

172 

173 This method is designed to ignore a single, or set of Python warnings. 

174 Remember, the **warnings must be reset at the end of your program**, 

175 as this is **not** done automatically. 

176 

177 These actions are controlled via the ``py_warnings`` key in 

178 your config file. 

179 

180 - ``ignore``: Boolean flag to ignore the warnings 

181 - ``categories``: A list of warning type(s) to ignore 

182 

183 :Reference: 

184 The list of warnings in the :attr:`_WARN_TYPES` class dictionary 

185 was taken from the Python ``warnings`` documentation, which can be 

186 found `here`_. 

187 

188 .. _here: https://docs.python.org/3.5/library/warnings.html#warning-categories 

189 

190 """ 

191 if not isinstance(self._categories, list): 

192 self._categories = [self._categories] # Ensure categories is a list. 

193 if self._ignore: 

194 for category in self._categories: 

195 warnings.simplefilter('ignore', self._WARN_TYPES[category.lower()]) 

196 

197 @staticmethod 

198 def reset_warnings(): 

199 """Turn Python warnings back on.""" 

200 warnings.resetwarnings()