PageRenderTime 91ms CodeModel.GetById 24ms app.highlight 62ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/test/test_py3kwarn.py

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