source: python/trunk/Lib/test/test_py3kwarn.py

Last change on this file was 391, checked in by dmik, 11 years ago

python: Merge vendor 2.7.6 to trunk.

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