Issue #5788: `datetime.timedelta` objects get a new `total_seconds()` method returning
[python.git] / Lib / test / test_py3kwarn.py
blobd754faa75e29aef48c04e8d47e1d4018fe0a7853
1 import unittest
2 import sys
3 from test.test_support import check_warnings, CleanImport, run_unittest
4 import warnings
6 from contextlib import nested
8 if not sys.py3kwarning:
9 raise unittest.SkipTest('%s must be run with the -3 flag' % __name__)
11 def reset_module_registry(module):
12 try:
13 registry = module.__warningregistry__
14 except AttributeError:
15 pass
16 else:
17 registry.clear()
19 class TestPy3KWarnings(unittest.TestCase):
21 def assertWarning(self, _, warning, expected_message):
22 self.assertEqual(str(warning.message), expected_message)
24 def assertNoWarning(self, _, recorder):
25 self.assertEqual(len(recorder.warnings), 0)
27 def test_backquote(self):
28 expected = 'backquote not supported in 3.x; use repr()'
29 with check_warnings() as w:
30 exec "`2`" in {}
31 self.assertWarning(None, w, expected)
33 def test_paren_arg_names(self):
34 expected = 'parenthesized argument names are invalid in 3.x'
35 def check(s):
36 exec s in {}
37 self.assertWarning(None, w, expected)
38 with check_warnings() as w:
39 check("def f((x)): pass")
40 check("def f((((x))), (y)): pass")
41 check("def f((x), (((y))), m=32): pass")
42 # Something like def f((a, (b))): pass will raise the tuple
43 # unpacking warning.
45 def test_forbidden_names(self):
46 # So we don't screw up our globals
47 def safe_exec(expr):
48 def f(**kwargs): pass
49 exec expr in {'f' : f}
51 tests = [("True", "assignment to True or False is forbidden in 3.x"),
52 ("False", "assignment to True or False is forbidden in 3.x"),
53 ("nonlocal", "nonlocal is a keyword in 3.x")]
54 with check_warnings() as w:
55 for keyword, expected in tests:
56 safe_exec("{0} = False".format(keyword))
57 self.assertWarning(None, w, expected)
58 w.reset()
59 try:
60 safe_exec("obj.{0} = True".format(keyword))
61 except NameError:
62 pass
63 self.assertWarning(None, w, expected)
64 w.reset()
65 safe_exec("def {0}(): pass".format(keyword))
66 self.assertWarning(None, w, expected)
67 w.reset()
68 safe_exec("class {0}: pass".format(keyword))
69 self.assertWarning(None, w, expected)
70 w.reset()
71 safe_exec("def f({0}=43): pass".format(keyword))
72 self.assertWarning(None, w, expected)
73 w.reset()
76 def test_type_inequality_comparisons(self):
77 expected = 'type inequality comparisons not supported in 3.x'
78 with check_warnings() as w:
79 self.assertWarning(int < str, w, expected)
80 w.reset()
81 self.assertWarning(type < object, w, expected)
83 def test_object_inequality_comparisons(self):
84 expected = 'comparing unequal types not supported in 3.x'
85 with check_warnings() as w:
86 self.assertWarning(str < [], w, expected)
87 w.reset()
88 self.assertWarning(object() < (1, 2), w, expected)
90 def test_dict_inequality_comparisons(self):
91 expected = 'dict inequality comparisons not supported in 3.x'
92 with check_warnings() as w:
93 self.assertWarning({} < {2:3}, w, expected)
94 w.reset()
95 self.assertWarning({} <= {}, w, expected)
96 w.reset()
97 self.assertWarning({} > {2:3}, w, expected)
98 w.reset()
99 self.assertWarning({2:3} >= {}, w, expected)
101 def test_cell_inequality_comparisons(self):
102 expected = 'cell comparisons not supported in 3.x'
103 def f(x):
104 def g():
105 return x
106 return g
107 cell0, = f(0).func_closure
108 cell1, = f(1).func_closure
109 with check_warnings() as w:
110 self.assertWarning(cell0 == cell1, w, expected)
111 w.reset()
112 self.assertWarning(cell0 < cell1, w, expected)
114 def test_code_inequality_comparisons(self):
115 expected = 'code inequality comparisons not supported in 3.x'
116 def f(x):
117 pass
118 def g(x):
119 pass
120 with check_warnings() as w:
121 self.assertWarning(f.func_code < g.func_code, w, expected)
122 w.reset()
123 self.assertWarning(f.func_code <= g.func_code, w, expected)
124 w.reset()
125 self.assertWarning(f.func_code >= g.func_code, w, expected)
126 w.reset()
127 self.assertWarning(f.func_code > g.func_code, w, expected)
129 def test_builtin_function_or_method_comparisons(self):
130 expected = ('builtin_function_or_method '
131 'order comparisons not supported in 3.x')
132 func = eval
133 meth = {}.get
134 with check_warnings() as w:
135 self.assertWarning(func < meth, w, expected)
136 w.reset()
137 self.assertWarning(func > meth, w, expected)
138 w.reset()
139 self.assertWarning(meth <= func, w, expected)
140 w.reset()
141 self.assertWarning(meth >= func, w, expected)
142 w.reset()
143 self.assertNoWarning(meth == func, w)
144 self.assertNoWarning(meth != func, w)
145 lam = lambda x: x
146 self.assertNoWarning(lam == func, w)
147 self.assertNoWarning(lam != func, w)
149 def test_frame_attributes(self):
150 template = "%s has been removed in 3.x"
151 f = sys._getframe(0)
152 for attr in ("f_exc_traceback", "f_exc_value", "f_exc_type"):
153 expected = template % attr
154 with check_warnings() as w:
155 self.assertWarning(getattr(f, attr), w, expected)
156 w.reset()
157 self.assertWarning(setattr(f, attr, None), w, expected)
159 def test_sort_cmp_arg(self):
160 expected = "the cmp argument is not supported in 3.x"
161 lst = range(5)
162 cmp = lambda x,y: -1
164 with check_warnings() as w:
165 self.assertWarning(lst.sort(cmp=cmp), w, expected)
166 w.reset()
167 self.assertWarning(sorted(lst, cmp=cmp), w, expected)
168 w.reset()
169 self.assertWarning(lst.sort(cmp), w, expected)
170 w.reset()
171 self.assertWarning(sorted(lst, cmp), w, expected)
173 def test_sys_exc_clear(self):
174 expected = 'sys.exc_clear() not supported in 3.x; use except clauses'
175 with check_warnings() as w:
176 self.assertWarning(sys.exc_clear(), w, expected)
178 def test_methods_members(self):
179 expected = '__members__ and __methods__ not supported in 3.x'
180 class C:
181 __methods__ = ['a']
182 __members__ = ['b']
183 c = C()
184 with check_warnings() as w:
185 self.assertWarning(dir(c), w, expected)
187 def test_softspace(self):
188 expected = 'file.softspace not supported in 3.x'
189 with file(__file__) as f:
190 with check_warnings() as w:
191 self.assertWarning(f.softspace, w, expected)
192 def set():
193 f.softspace = 0
194 with check_warnings() as w:
195 self.assertWarning(set(), w, expected)
197 def test_slice_methods(self):
198 class Spam(object):
199 def __getslice__(self, i, j): pass
200 def __setslice__(self, i, j, what): pass
201 def __delslice__(self, i, j): pass
202 class Egg:
203 def __getslice__(self, i, h): pass
204 def __setslice__(self, i, j, what): pass
205 def __delslice__(self, i, j): pass
207 expected = "in 3.x, __{0}slice__ has been removed; use __{0}item__"
209 for obj in (Spam(), Egg()):
210 with check_warnings() as w:
211 self.assertWarning(obj[1:2], w, expected.format('get'))
212 w.reset()
213 del obj[3:4]
214 self.assertWarning(None, w, expected.format('del'))
215 w.reset()
216 obj[4:5] = "eggs"
217 self.assertWarning(None, w, expected.format('set'))
219 def test_tuple_parameter_unpacking(self):
220 expected = "tuple parameter unpacking has been removed in 3.x"
221 with check_warnings() as w:
222 exec "def f((a, b)): pass"
223 self.assertWarning(None, w, expected)
225 def test_buffer(self):
226 expected = 'buffer() not supported in 3.x'
227 with check_warnings() as w:
228 self.assertWarning(buffer('a'), w, expected)
230 def test_file_xreadlines(self):
231 expected = ("f.xreadlines() not supported in 3.x, "
232 "try 'for line in f' instead")
233 with file(__file__) as f:
234 with check_warnings() as w:
235 self.assertWarning(f.xreadlines(), w, expected)
237 def test_hash_inheritance(self):
238 with check_warnings() as w:
239 # With object as the base class
240 class WarnOnlyCmp(object):
241 def __cmp__(self, other): pass
242 self.assertEqual(len(w.warnings), 1)
243 self.assertWarning(None, w,
244 "Overriding __cmp__ blocks inheritance of __hash__ in 3.x")
245 w.reset()
246 class WarnOnlyEq(object):
247 def __eq__(self, other): pass
248 self.assertEqual(len(w.warnings), 1)
249 self.assertWarning(None, w,
250 "Overriding __eq__ blocks inheritance of __hash__ in 3.x")
251 w.reset()
252 class WarnCmpAndEq(object):
253 def __cmp__(self, other): pass
254 def __eq__(self, other): pass
255 self.assertEqual(len(w.warnings), 2)
256 self.assertWarning(None, w.warnings[0],
257 "Overriding __cmp__ blocks inheritance of __hash__ in 3.x")
258 self.assertWarning(None, w,
259 "Overriding __eq__ blocks inheritance of __hash__ in 3.x")
260 w.reset()
261 class NoWarningOnlyHash(object):
262 def __hash__(self): pass
263 self.assertEqual(len(w.warnings), 0)
264 # With an intermediate class in the heirarchy
265 class DefinesAllThree(object):
266 def __cmp__(self, other): pass
267 def __eq__(self, other): pass
268 def __hash__(self): pass
269 class WarnOnlyCmp(DefinesAllThree):
270 def __cmp__(self, other): pass
271 self.assertEqual(len(w.warnings), 1)
272 self.assertWarning(None, w,
273 "Overriding __cmp__ blocks inheritance of __hash__ in 3.x")
274 w.reset()
275 class WarnOnlyEq(DefinesAllThree):
276 def __eq__(self, other): pass
277 self.assertEqual(len(w.warnings), 1)
278 self.assertWarning(None, w,
279 "Overriding __eq__ blocks inheritance of __hash__ in 3.x")
280 w.reset()
281 class WarnCmpAndEq(DefinesAllThree):
282 def __cmp__(self, other): pass
283 def __eq__(self, other): pass
284 self.assertEqual(len(w.warnings), 2)
285 self.assertWarning(None, w.warnings[0],
286 "Overriding __cmp__ blocks inheritance of __hash__ in 3.x")
287 self.assertWarning(None, w,
288 "Overriding __eq__ blocks inheritance of __hash__ in 3.x")
289 w.reset()
290 class NoWarningOnlyHash(DefinesAllThree):
291 def __hash__(self): pass
292 self.assertEqual(len(w.warnings), 0)
294 def test_operator(self):
295 from operator import isCallable, sequenceIncludes
297 callable_warn = ("operator.isCallable() is not supported in 3.x. "
298 "Use hasattr(obj, '__call__').")
299 seq_warn = ("operator.sequenceIncludes() is not supported "
300 "in 3.x. Use operator.contains().")
301 with check_warnings() as w:
302 self.assertWarning(isCallable(self), w, callable_warn)
303 w.reset()
304 self.assertWarning(sequenceIncludes(range(3), 2), w, seq_warn)
307 class TestStdlibRemovals(unittest.TestCase):
309 # test.testall not tested as it executes all unit tests as an
310 # import side-effect.
311 all_platforms = ('audiodev', 'imputil', 'mutex', 'user', 'new', 'rexec',
312 'Bastion', 'compiler', 'dircache', 'mimetools',
313 'fpformat', 'ihooks', 'mhlib', 'statvfs', 'htmllib',
314 'sgmllib', 'rfc822', 'sunaudio')
315 inclusive_platforms = {'irix' : ('pure', 'AL', 'al', 'CD', 'cd', 'cddb',
316 'cdplayer', 'CL', 'cl', 'DEVICE', 'GL',
317 'gl', 'ERRNO', 'FILE', 'FL', 'flp', 'fl',
318 'fm', 'GET', 'GLWS', 'imgfile', 'IN',
319 'IOCTL', 'jpeg', 'panel', 'panelparser',
320 'readcd', 'SV', 'torgb', 'WAIT'),
321 'darwin' : ('autoGIL', 'Carbon', 'OSATerminology',
322 'icglue', 'Nav', 'MacOS', 'aepack',
323 'aetools', 'aetypes', 'applesingle',
324 'appletrawmain', 'appletrunner',
325 'argvemulator', 'bgenlocations',
326 'EasyDialogs', 'macerrors', 'macostools',
327 'findertools', 'FrameWork', 'ic',
328 'gensuitemodule', 'icopen', 'macresource',
329 'MiniAEFrame', 'pimp', 'PixMapWrapper',
330 'terminalcommand', 'videoreader',
331 '_builtinSuites', 'CodeWarrior',
332 'Explorer', 'Finder', 'Netscape',
333 'StdSuites', 'SystemEvents', 'Terminal',
334 'cfmfile', 'bundlebuilder', 'buildtools',
335 'ColorPicker', 'Audio_mac'),
336 'sunos5' : ('sunaudiodev', 'SUNAUDIODEV'),
338 optional_modules = ('bsddb185', 'Canvas', 'dl', 'linuxaudiodev', 'imageop',
339 'sv', 'cPickle', 'bsddb', 'dbhash')
341 def check_removal(self, module_name, optional=False):
342 """Make sure the specified module, when imported, raises a
343 DeprecationWarning and specifies itself in the message."""
344 with nested(CleanImport(module_name), warnings.catch_warnings()):
345 # XXX: This is not quite enough for extension modules - those
346 # won't rerun their init code even with CleanImport.
347 # You can see this easily by running the whole test suite with -3
348 warnings.filterwarnings("error", ".+ removed",
349 DeprecationWarning, __name__)
350 try:
351 __import__(module_name, level=0)
352 except DeprecationWarning as exc:
353 self.assertTrue(module_name in exc.args[0],
354 "%s warning didn't contain module name"
355 % module_name)
356 except ImportError:
357 if not optional:
358 self.fail("Non-optional module {0} raised an "
359 "ImportError.".format(module_name))
360 else:
361 self.fail("DeprecationWarning not raised for {0}"
362 .format(module_name))
364 def test_platform_independent_removals(self):
365 # Make sure that the modules that are available on all platforms raise
366 # the proper DeprecationWarning.
367 for module_name in self.all_platforms:
368 self.check_removal(module_name)
370 def test_platform_specific_removals(self):
371 # Test the removal of platform-specific modules.
372 for module_name in self.inclusive_platforms.get(sys.platform, []):
373 self.check_removal(module_name, optional=True)
375 def test_optional_module_removals(self):
376 # Test the removal of modules that may or may not be built.
377 for module_name in self.optional_modules:
378 self.check_removal(module_name, optional=True)
380 def test_os_path_walk(self):
381 msg = "In 3.x, os.path.walk is removed in favor of os.walk."
382 def dumbo(where, names, args): pass
383 for path_mod in ("ntpath", "macpath", "os2emxpath", "posixpath"):
384 mod = __import__(path_mod)
385 reset_module_registry(mod)
386 with check_warnings() as w:
387 mod.walk("crashers", dumbo, None)
388 self.assertEquals(str(w.message), msg)
390 def test_reduce_move(self):
391 from operator import add
392 # reduce tests may have already triggered this warning
393 reset_module_registry(unittest)
394 with warnings.catch_warnings():
395 warnings.filterwarnings("error", "reduce")
396 self.assertRaises(DeprecationWarning, reduce, add, range(10))
398 def test_mutablestring_removal(self):
399 # UserString.MutableString has been removed in 3.0.
400 import UserString
401 # UserString tests may have already triggered this warning
402 reset_module_registry(UserString)
403 with warnings.catch_warnings():
404 warnings.filterwarnings("error", ".*MutableString",
405 DeprecationWarning)
406 self.assertRaises(DeprecationWarning, UserString.MutableString)
409 def test_main():
410 with check_warnings():
411 warnings.simplefilter("always")
412 run_unittest(TestPy3KWarnings,
413 TestStdlibRemovals)
415 if __name__ == '__main__':
416 test_main()