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

18 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2025-08-26 21:39 +0100

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:Developer: J Berendt 

15:Email: support@s3dev.uk 

16 

17:Comments: n/a 

18 

19:Example: 

20 

21 Ignore a single warning manually:: 

22 

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

24 >>> from utils4 import pywarnings 

25 

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

27 >>> pywarn.ignore_warnings() 

28 

29 >>> # Test. 

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

31 

32 >>> # Re-enable warnings. 

33 >>> pywarn.reset_warnings() 

34 

35 >>> # Test. 

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

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

38 warnings.warn('', FutureWarning) 

39 

40 

41 Ignore a list of warnings manually:: 

42 

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

44 >>> from utils4 import pywarnings 

45 

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

47 categories=['FutureWarning', 

48 'ResourceWarning', 

49 'UserWarning']) 

50 >>> pywarn.ignore_warnings() 

51 

52 >>> # Test. 

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

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

55 

56 >>> # Re-enable warnings. 

57 >>> pywarn.reset_warnings() 

58 

59 >>> # Test. 

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

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

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

63 warnings.warn('', w) 

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

65 warnings.warn('', w) 

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

67 warnings.warn('', w) 

68 

69 

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

71 file:: 

72 

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

74 >>> from utils4 import pywarnings 

75 

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

77 'key2': 'value2', 

78 'py_warnings': {'ignore': True, 

79 'categories': ['FutureWarning', 

80 'ResourceWarning', 

81 'UserWarning']}, 

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

83 

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

85 >>> pywarn.ignore_warnings() 

86 

87 >>> # Test. 

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

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

90 

91 >>> # Re-enable warnings. 

92 >>> pywarn.reset_warnings() 

93 

94 >>> # Test. 

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

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

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

98 warnings.warn('', w) 

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

100 warnings.warn('', w) 

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

102 warnings.warn('', w) 

103 

104""" 

105 

106import warnings 

107 

108 

109class PyWarnings: 

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

111 

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

113 warnings using your program's config file. 

114 

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

116 

117 {"py_warnings": {"ignore": True, 

118 "categories": ["PendingDeprecationWarning", 

119 "FutureWarning"]}} 

120 

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

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

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

124 

125 Args: 

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

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

128 needing to change your source code. 

129 

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

131 of categories. 

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

133 

134 {"py_warnings": {"ignore": true, 

135 "categories": ["PendingDeprecationWarning", 

136 "FutureWarning"]}} 

137 

138 :Required Arguments: 

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

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

141 

142 Note: 

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

144 of your program! 

145 

146 """ 

147 

148 _WARN_TYPES = {'byteswarning': BytesWarning, 

149 'deprecationwarning': DeprecationWarning, 

150 'futurewarning': FutureWarning, 

151 'importwarning': ImportWarning, 

152 'pendingdeprecationwarning': PendingDeprecationWarning, 

153 'resourcewarning': ResourceWarning, 

154 'runtimewarning': RuntimeWarning, 

155 'syntaxwarning': SyntaxWarning, 

156 'unicodewarning': UnicodeWarning, 

157 'userwarning': UserWarning, 

158 'warning': Warning} 

159 

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

161 """Class initialiser.""" 

162 if config: 

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

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

165 else: 

166 self._ignore = ignore 

167 self._categories = categories 

168 

169 def ignore_warnings(self): 

170 """Ignore Python warnings. 

171 

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

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

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

175 

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

177 your config file. 

178 

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

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

181 

182 :Reference: 

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

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

185 found `here`_. 

186 

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

188 

189 """ 

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

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

192 if self._ignore: 

193 for category in self._categories: 

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

195 

196 @staticmethod 

197 def reset_warnings(): 

198 """Turn Python warnings back on.""" 

199 warnings.resetwarnings()