Completed
Push — master ( a4d2e6...350516 )
by De
01:10
created

RegexTests.test_indices_must_be_int()   A

Complexity

Conditions 2

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 14
rs 9.4285
cc 2
1
# -*- coding: utf-8
2
"""Unit tests for regexps from didyoumean_re.py."""
3
import unittest2
4
import didyoumean_re as re
5
import sys
6
7
NO_GROUP = ((), dict())
8
# Various technical flags to check more that meet the eyes in tests
9
# Flag used to check that a text only match the expected regexp and not
10
# the other to ensure we do not have ambiguous/double regexp matching.
11
CHECK_OTHERS_DONT_MATCH = True
12
# Flag to check that the regexp provided does correspond to a regexp
13
# listed in re.ALL_REGEXPS
14
CHECK_RE_LISTED = True
15
# Flag to check that the name used for the regexp in re.ALL_REGEXPS
16
# does match the naming convention
17
CHECK_RE_NAME = True
18
# Flag to check that the regex does match a few conventions such as:
19
# stars with ^, ends with $.
20
CHECK_RE_VALUE = True
21
22
23
class RegexTests(unittest2.TestCase):
24
    """Tests to check that error messages match the regexps."""
25
26
    def re_matches(self, text, regexp, results):
27
        """Check that text matches regexp and gives the right match groups.
28
29
        result is a tuple containing the expected return values for groups()
30
        and groupdict().
31
        """
32
        groups, named_groups = results
33
        self.assertRegexpMatches(text, regexp)   # does pretty printing
34
        match = re.match(regexp, text)
35
        self.assertTrue(match)
36
        self.assertEqual(groups, match.groups())
37
        self.assertEqual(named_groups, match.groupdict())
38
        self.check_more_about_re(text, regexp)
39
40
    def check_more_about_re(self, text, regexp):
41
        """Check various properties about the regexp.
42
43
        Properties checked are configurable via global constants. These
44
        properties are not stricly speaking required but they help to
45
        detect potential issues much more quickly.
46
        """
47
        if CHECK_RE_VALUE:
48
            self.assertTrue(regexp.startswith('^'))
49
            self.assertTrue(regexp.endswith('$'))
50
        found = False
51
        for other_name, other_re in re.ALL_REGEXPS.items():
52
            if other_re == regexp:
53
                found = True
54
                if CHECK_RE_NAME:
55
                    self.assertTrue(other_name.endswith('_RE'))
56
            elif CHECK_OTHERS_DONT_MATCH:
57
                details = "text '%s' matches %s (on top of %s)" % \
58
                        (text, other_name, regexp)
59
                self.assertNotRegexpMatches(text, other_re, details)
60
                no_match = re.match(other_re, text)
61
                self.assertEqual(no_match, None, details)
62
        if CHECK_RE_LISTED:
63
            self.assertTrue(found)
64
65
    def test_unbound_assignment(self):
66
        """Test VARREFBEFOREASSIGN_RE."""
67
        msgs = [
68
            # Python 2.6/2.7/3.2/3.3/3.4/3.5/PyPy/PyPy3
69
            "local variable 'some_var' referenced before assignment",
70
            "free variable 'some_var' referenced before assignment " \
71
            "in enclosing scope",
72
        ]
73
        groups = ('some_var',)
74
        named_groups = {'name': 'some_var'}
75
        results = (groups, named_groups)
76
        for msg in msgs:
77
            self.re_matches(msg, re.VARREFBEFOREASSIGN_RE, results)
78
79
    def test_name_not_defined(self):
80
        """Test NAMENOTDEFINED_RE."""
81
        msgs = [
82
            # Python 2.6/2.7/3.2/3.3/3.4/3.5/PyPy3
83
            "name 'some_name' is not defined",
84
            # Python 2.6/2.7/3.2/3.3/PyPy/PyPy3
85
            "global name 'some_name' is not defined",
86
        ]
87
        groups = ('some_name',)
88
        named_groups = {'name': 'some_name'}
89
        for msg in msgs:
90
            self.re_matches(msg, re.NAMENOTDEFINED_RE, (groups, named_groups))
91
92
    def test_attribute_error(self):
93
        """Test ATTRIBUTEERROR_RE."""
94
        group_msg = {
95
            ('some.class', 'attri'): [
96
                # Python 2.6/2.7/3.2/3.3/3.4/3.5/PyPy/PyPy3
97
                "'some.class' object has no attribute 'attri'",
98
            ],
99
            ('SomeClass', 'attri'): [
100
                # Python 2.6/2.7/PyPy
101
                "SomeClass instance has no attribute 'attri'",
102
                # Python 2.6/2.7
103
                "class SomeClass has no attribute 'attri'",
104
                # Python 3.2/3.3/3.4/3.5
105
                "type object 'SomeClass' has no attribute 'attri'",
106
            ],
107
        }
108
        for group, msgs in group_msg.items():
109
            for msg in msgs:
110
                self.re_matches(msg, re.ATTRIBUTEERROR_RE, (group, dict()))
111
112
    def test_module_attribute_error(self):
113
        """Test MODULEHASNOATTRIBUTE_RE."""
114
        # Python 3.5
115
        msg = "module 'some_module' has no attribute 'attri'"
116
        group = ('some_module', 'attri')
117
        self.re_matches(msg, re.MODULEHASNOATTRIBUTE_RE, (group, dict()))
118
119
    def test_cannot_import(self):
120
        """Test CANNOTIMPORT_RE."""
121
        msgs = [
122
            # Python 2.6/2.7/3.2/3.3
123
            "cannot import name pie",
124
            # Python 3.4/3.5/PyPy/PyPy3
125
            "cannot import name 'pie'",
126
        ]
127
        groups = ('pie',)
128
        for msg in msgs:
129
            self.re_matches(msg, re.CANNOTIMPORT_RE, (groups, dict()))
130
131
    def test_no_module_named(self):
132
        """Test NOMODULE_RE."""
133
        msgs = [
134
            # Python 2.6/2.7/3.2/PyPy/PyPy3
135
            "No module named fake_module",
136
            # Python 3.3/3.4/3.5
137
            "No module named 'fake_module'",
138
        ]
139
        groups = ('fake_module',)
140
        for msg in msgs:
141
            self.re_matches(msg, re.NOMODULE_RE, (groups, dict()))
142
143
    def test_index_out_of_range(self):
144
        """Test INDEXOUTOFRANGE_RE."""
145
        # Python 2.6/2.7/3.2/3.3/3.4/3.5/PyPy/PyPy3
146
        msg = "list index out of range"
147
        self.re_matches(msg, re.INDEXOUTOFRANGE_RE, NO_GROUP)
148
149
    def test_unsubscriptable(self):
150
        """Test UNSUBSCRIPTABLE_RE."""
151
        msgs = [
152
            # Python 2.6
153
            "'function' object is unsubscriptable",
154
            # Python 3.2/3.3/3.4/3.5/PyPy/PyPy3
155
            "'function' object is not subscriptable",
156
        ]
157
        groups = ('function',)
158
        for msg in msgs:
159
            self.re_matches(msg, re.UNSUBSCRIPTABLE_RE, (groups, dict()))
160
161
    def test_unexpected_kw_arg(self):
162
        """Test UNEXPECTED_KEYWORDARG_RE."""
163
        # Python 2.6/2.7/3.2/3.3/3.4/3.5/PyPy/PyPy3
164
        msgs = [
165
            ("some_func() got an unexpected keyword argument 'a'",
166
                ('some_func', 'a')),
167
            ("<lambda>() got an unexpected keyword argument 'a'",
168
                ('<lambda>', 'a')),
169
        ]
170
        for msg, groups in msgs:
171
            self.re_matches(msg, re.UNEXPECTED_KEYWORDARG_RE, (groups, dict()))
172
173
    def test_unexpected_kw_arg2(self):
174
        """Test UNEXPECTED_KEYWORDARG2_RE."""
175
        # Python 2.6/2.7/3.2/3.3/3.4/3.5
176
        msg = "'this_doesnt_exist' is an invalid " \
177
            "keyword argument for this function"
178
        groups = ('this_doesnt_exist', )
179
        self.re_matches(msg, re.UNEXPECTED_KEYWORDARG2_RE, (groups, dict()))
180
181
    def test_unexpected_kw_arg3(self):
182
        """Test UNEXPECTED_KEYWORDARG3_RE."""
183
        # PyPy/PyPy3
184
        msg = "invalid keyword arguments to print()"
185
        groups = ('print', )
186
        self.re_matches(msg, re.UNEXPECTED_KEYWORDARG3_RE, (groups, dict()))
187
188
    def test_zero_length_field(self):
189
        """Test ZERO_LEN_FIELD_RE."""
190
        # Python 2.6
191
        msg = "zero length field name in format"
192
        self.re_matches(msg, re.ZERO_LEN_FIELD_RE, NO_GROUP)
193
194
    def test_math_domain_error(self):
195
        """Test MATH_DOMAIN_ERROR_RE."""
196
        # Python 2.6/2.7/3.2/3.3/3.4/3.5/PyPy/PyPy3
197
        msg = "math domain error"
198
        self.re_matches(msg, re.MATH_DOMAIN_ERROR_RE, NO_GROUP)
199
200
    def test_too_many_values(self):
201
        """Test TOO_MANY_VALUES_UNPACK_RE."""
202
        msgs = [
203
            # Python 2.6/2.7
204
            "too many values to unpack",
205
            # Python 3.2/3.3/3.4/3.5/PyPy3
206
            "too many values to unpack (expected 3)",
207
        ]
208
        for msg in msgs:
209
            self.re_matches(msg, re.TOO_MANY_VALUES_UNPACK_RE, NO_GROUP)
210
211
    def test_unhashable_type(self):
212
        """Test UNHASHABLE_RE."""
213
        msgs = [
214
            # Python 2.6/2.7/3.2/3.3/3.4/3.5
215
            "unhashable type: 'list'",
216
            # PyPy/PyPy3
217
            "'list' objects are unhashable",
218
        ]
219
        groups = ('list',)
220
        for msg in msgs:
221
            self.re_matches(msg, re.UNHASHABLE_RE, (groups, dict()))
222
223
    def test_cannot_be_interpreted_as_integer(self):
224
        """Test CANNOT_BE_INTERPRETED_INT_RE."""
225
        msgs = {
226
            "'str' object cannot be interpreted as an integer": 'str',
227
            "'list' object cannot be interpreted as an integer": 'list',
228
        }
229
        for msg, typ in msgs.items():
230
            results = ((typ,), dict())
231
            self.re_matches(msg, re.CANNOT_BE_INTERPRETED_INT_RE, results)
232
233
    def test_int_expected_got(self):
234
        """Test INTEGER_EXPECTED_GOT_RE."""
235
        msgs = {
236
            "expected integer, got str object": 'str',
237
            "range() integer end argument expected, got list.": 'list',
238
            "range() integer start argument expected, got list.": 'list',
239
        }
240
        for msg, typ in msgs.items():
241
            results = ((typ,), dict())
242
            self.re_matches(msg, re.INTEGER_EXPECTED_GOT_RE, results)
243
244
    def test_indices_must_be_int(self):
245
        """Test INDICES_MUST_BE_INT_RE."""
246
        msgs = {
247
            # Python 2.6, 2.7, 3.2, 3.3, 3.4
248
            "list indices must be integers, not str": "str",
249
            "list indices must be integers or slices, not str": "str",
250
            # Python 3.5
251
            "tuple indices must be integers or slices, not str": "str",
252
            # PyPy
253
            "list index must be an integer, not str": "str",
254
        }
255
        for msg, typ in msgs.items():
256
            results = ((typ,), dict())
257
            self.re_matches(msg, re.INDICES_MUST_BE_INT_RE, results)
258
259
    def test_outside_function(self):
260
        """Test OUTSIDE_FUNCTION_RE."""
261
        msgs = [
262
            # Python 2.6/2.7/3.2/3.3/3.4/3.5/PyPy/PyPy3
263
            "'return' outside function",
264
            # PyPy/PyPy3
265
            "return outside function",
266
        ]
267
        groups = ('return',)
268
        for msg in msgs:
269
            self.re_matches(msg, re.OUTSIDE_FUNCTION_RE, (groups, dict()))
270
271
    def test_nb_positional_argument(self):
272
        """Test NB_ARG_RE."""
273
        msgs = [
274
            # Python 2.6/2.7/PyPy/PyPy3
275
            ("some_func() takes exactly 1 argument (2 given)",
276
                '1', '2'),
277
            ("some_func() takes exactly 3 arguments (1 given)",
278
                '3', '1'),
279
            ("some_func() takes no arguments (1 given)",
280
                'no', '1'),
281
            ("some_func() takes at least 2 non-keyword arguments (0 given)",
282
                '2', '0'),
283
            # Python 3.2
284
            ("some_func() takes exactly 1 positional argument (2 given)",
285
                '1', '2'),
286
            # Python 3.3/3.4/3.5
287
            ("some_func() takes 1 positional argument but 2 were given",
288
                '1', '2'),
289
            ("some_func() takes 0 positional arguments but 1 was given",
290
                '0', '1'),
291
            # PyPy adds suggestions sometimes:
292
            ("some_func() takes no arguments (1 given)"
293
             ". Did you forget 'self' in the function definition?",
294
                'no', '1'),
295
        ]
296
        for msg, exp, nb in msgs:
297
            groups = ('some_func', exp, nb)
298
            self.re_matches(msg, re.NB_ARG_RE, (groups, dict()))
299
300
    def test_missing_positional_arg(self):
301
        """Test MISSING_POS_ARG_RE."""
302
        msgs = [
303
            # Python 3.3/3.4/3.5
304
            "some_func() missing 2 required positional arguments: "
305
            "'much' and 'args'",
306
            "some_func() missing 1 required positional argument: "
307
            "'much'",
308
        ]
309
        groups = ('some_func',)
310
        for msg in msgs:
311
            self.re_matches(msg, re.MISSING_POS_ARG_RE, (groups, dict()))
312
313
    def test_need_more_values_to_unpack(self):
314
        """Test NEED_MORE_VALUES_RE."""
315
        msgs = [
316
            # Python 2.6/2.7/3.2/3.3/3.4/3.5(?)/PyPy3
317
            "need more than 2 values to unpack",
318
            # Python 3.5
319
            "not enough values to unpack (expected 3, got 2)",
320
        ]
321
        for msg in msgs:
322
            self.re_matches(msg, re.NEED_MORE_VALUES_RE, NO_GROUP)
323
324
    def test_missing_parentheses(self):
325
        """Test MISSING_PARENT_RE."""
326
        # Python 3.4/3.5
327
        msg = "Missing parentheses in call to 'exec'"
328
        groups = ('exec',)
329
        self.re_matches(msg, re.MISSING_PARENT_RE, (groups, dict()))
330
331
    def test_invalid_literal(self):
332
        """Test INVALID_LITERAL_RE."""
333
        # Python 2.6/2.7/3.2/3.3/3.4/3.5/PyPy/PyPy3
334
        msg = "invalid literal for int() with base 10: 'toto'"
335
        groups = ('int', 'toto')
336
        self.re_matches(msg, re.INVALID_LITERAL_RE, (groups, dict()))
337
338
    def test_invalid_syntax(self):
339
        """Test INVALID_SYNTAX_RE."""
340
        # Python 2.6/2.7/3.2/3.3/3.4/3.5/PyPy3
341
        msg = "invalid syntax"
342
        self.re_matches(msg, re.INVALID_SYNTAX_RE, NO_GROUP)
343
344
    def test_invalid_comp(self):
345
        """Test INVALID_COMP_RE."""
346
        # PyPy3
347
        msg = "invalid comparison"
348
        self.re_matches(msg, re.INVALID_COMP_RE, NO_GROUP)
349
350
    def test_expected_length(self):
351
        """Test EXPECTED_LENGTH_RE."""
352
        # PyPy
353
        msg = "expected length 3, got 2"
354
        groups = ('3', '2')
355
        self.re_matches(msg, re.EXPECTED_LENGTH_RE, (groups, dict()))
356
357
    def test_future_first(self):
358
        """Test FUTURE_FIRST_RE."""
359
        msgs = [
360
            # Python 2.6/2.7/3.2/3.3/3.4/3.5
361
            "from __future__ imports must occur at the beginning of the file",
362
            # PyPy/PyPy3
363
            "__future__ statements must appear at beginning of file",
364
        ]
365
        for msg in msgs:
366
            self.re_matches(msg, re.FUTURE_FIRST_RE, NO_GROUP)
367
368
    def test_future_feature_not_def(self):
369
        """Test FUTURE_FEATURE_NOT_DEF_RE."""
370
        # Python 2.6/2.7/3.2/3.3/3.4/3.5/PyPy/PyPy3
371
        msg = "future feature divisio is not defined"
372
        groups = ('divisio',)
373
        self.re_matches(msg, re.FUTURE_FEATURE_NOT_DEF_RE, (groups, dict()))
374
375
    def test_result_has_too_many_items(self):
376
        """Test RESULT_TOO_MANY_ITEMS_RE."""
377
        # Python 2.6
378
        msg = "range() result has too many items"
379
        groups = ('range',)
380
        self.re_matches(msg, re.RESULT_TOO_MANY_ITEMS_RE, (groups, dict()))
381
382
    def test_unqualified_exec(self):
383
        """Test UNQUALIFIED_EXEC_RE."""
384
        msgs = [
385
            # Python 2.6
386
            "unqualified exec is not allowed in function 'func_name' "
387
            "it is a nested function",
388
            # Python 2.7
389
            "unqualified exec is not allowed in function 'func_name' "
390
            "because it is a nested function",
391
            # Python 2.6
392
            "unqualified exec is not allowed in function 'func_name' "
393
            "it contains a nested function with free variables",
394
            # Python 2.7
395
            "unqualified exec is not allowed in function 'func_name' "
396
            "because it contains a nested function with free variables",
397
        ]
398
        for msg in msgs:
399
            self.re_matches(msg, re.UNQUALIFIED_EXEC_RE, NO_GROUP)
400
401
    def test_import_star(self):
402
        """Test IMPORTSTAR_RE."""
403
        msgs = [
404
            # Python 2.6
405
            "import * is not allowed in function 'func_name' because it "
406
            "is contains a nested function with free variables",
407
            # Python 2.7
408
            "import * is not allowed in function 'func_name' because it "
409
            "contains a nested function with free variables",
410
            # Python 2.6
411
            "import * is not allowed in function 'func_name' because it "
412
            "is is a nested function",
413
            # Python 2.7
414
            "import * is not allowed in function 'func_name' because it "
415
            "is a nested function",
416
            # Python 3
417
            "import * only allowed at module level"
418
        ]
419
        for msg in msgs:
420
            self.re_matches(msg, re.IMPORTSTAR_RE, NO_GROUP)
421
422
    def test_does_not_support(self):
423
        """Test OBJ_DOES_NOT_SUPPORT_RE."""
424
        msgs = [
425
            ("'range' object does not support item assignment",
426
                ("range", "item assignment")),
427
            ("'str' object doesn't support item deletion",
428
                ("str", "item deletion")),
429
            ("'set' object does not support indexing",
430
                ("set", "indexing")),
431
        ]
432
        for msg, groups in msgs:
433
            self.re_matches(msg, re.OBJ_DOES_NOT_SUPPORT_RE, (groups, dict()))
434
435
    def test_cant_convert(self):
436
        """Test CANT_CONVERT_RE."""
437
        msg = "Can't convert 'int' object to str implicitly"
438
        groups = ('int', 'str')
439
        self.re_matches(msg, re.CANT_CONVERT_RE, (groups, dict()))
440
441
    def test_must_be_type1_not_type2(self):
442
        """Test MUST_BE_TYPE1_NOT_TYPE2_RE."""
443
        msg = "must be str, not int"
444
        groups = ('str', 'int')
445
        self.re_matches(msg, re.MUST_BE_TYPE1_NOT_TYPE2_RE, (groups, dict()))
446
447
    def test_cannot_concat(self):
448
        """Test CANNOT_CONCAT_RE."""
449
        msg = "cannot concatenate 'str' and 'int' objects"
450
        groups = ('str', 'int')
451
        self.re_matches(msg, re.CANNOT_CONCAT_RE, (groups, dict()))
452
453
    def test_unsupported_operand(self):
454
        """Test UNSUPPORTED_OP_RE."""
455
        msg = "unsupported operand type(s) for +: 'int' and 'str'"
456
        groups = ('+', 'int', 'str')
457
        self.re_matches(msg, re.UNSUPPORTED_OP_RE, (groups, dict()))
458
459
    def test_bad_operand_unary(self):
460
        """Test BAD_OPERAND_UNARY_RE."""
461
        msgs = [
462
            ("bad operand type for unary ~: 'set'", ('~', 'set')),
463
            ("bad operand type for abs(): 'set'", ('abs()', 'set')),
464
            ("unsupported operand type for unary neg: 'Foobar'",
465
                ('neg', 'Foobar')),
466
        ]
467
        for msg, group in msgs:
468
            self.re_matches(msg, re.BAD_OPERAND_UNARY_RE, (group, dict()))
469
470
    def test_not_callable(self):
471
        """Test NOT_CALLABLE_RE."""
472
        msg = "'list' object is not callable"
473
        groups = ('list',)
474
        self.re_matches(msg, re.NOT_CALLABLE_RE, (groups, dict()))
475
476
    def test_descriptor_requires(self):
477
        """Test DESCRIPT_REQUIRES_TYPE_RE."""
478
        msg = "descriptor 'add' requires a 'set' object but received a 'int'"
479
        groups = ('add', 'set', 'int')
480
        self.re_matches(
481
            msg, re.DESCRIPT_REQUIRES_TYPE_RE, (groups, dict()))
482
483
    def test_argument_not_iterable(self):
484
        """Test ARG_NOT_ITERABLE_RE."""
485
        msgs = [
486
            # Python 2.6/2.7/3.2/3.3/3.4/3.5
487
            "argument of type 'type' is not iterable",
488
            # PyPy/PyPy3
489
            "'type' object is not iterable"
490
        ]
491
        groups = ('type',)
492
        for msg in msgs:
493
            self.re_matches(msg, re.ARG_NOT_ITERABLE_RE, (groups, dict()))
494
495
    def test_must_be_called_with_instance(self):
496
        """Test MUST_BE_CALLED_WITH_INST_RE."""
497
        msg = "unbound method add() must be called with set " \
498
              "instance as first argument (got int instance instead)"
499
        groups = ('add', 'set', 'int')
500
        self.re_matches(
501
            msg, re.MUST_BE_CALLED_WITH_INST_RE, (groups, dict()))
502
503
    def test_object_has_no(self):
504
        """Test OBJECT_HAS_NO_FUNC_RE."""
505
        msgs = {
506
            # Python 2.6/2.7/3.2/3.3/3.4/3.5
507
            'len': "object of type 'generator' has no len()",
508
            # PyPy/PyPy3
509
            'length': "'generator' has no length",
510
        }
511
        for name, msg in msgs.items():
512
            groups = ('generator', name)
513
            self.re_matches(msg, re.OBJECT_HAS_NO_FUNC_RE, (groups, dict()))
514
515
    def test_nobinding_nonlocal(self):
516
        """Test NO_BINDING_NONLOCAL_RE."""
517
        msg = "no binding for nonlocal 'foo' found"
518
        groups = ('foo',)
519
        self.re_matches(msg, re.NO_BINDING_NONLOCAL_RE, (groups, dict()))
520
521
    def test_nonlocal_at_module_level(self):
522
        """Test NONLOCAL_AT_MODULE_RE."""
523
        msg = "nonlocal declaration not allowed at module level"
524
        self.re_matches(msg, re.NONLOCAL_AT_MODULE_RE, NO_GROUP)
525
526
    def test_unexpected_eof(self):
527
        """Test UNEXPECTED_EOF_RE."""
528
        msg = "unexpected EOF while parsing"
529
        self.re_matches(msg, re.UNEXPECTED_EOF_RE, NO_GROUP)
530
531
    def test_nosuchfile(self):
532
        """Test NO_SUCH_FILE_RE."""
533
        msg = "No such file or directory"
534
        self.re_matches(msg, re.NO_SUCH_FILE_RE, NO_GROUP)
535
536
    def test_timedata_does_not_match_format(self):
537
        """Test TIME_DATA_DOES_NOT_MATCH_FORMAT_RE."""
538
        msg = "time data '%d %b %y' does not match format '30 Nov 00'"
539
        # 'time data "%d \'%b %y" does not match format \'30 Nov 00\''
540
        groups = ("'%d %b %y'", "'30 Nov 00'")
541
        named_groups = {'format': "'30 Nov 00'", 'timedata': "'%d %b %y'"}
542
        self.re_matches(msg,
543
                        re.TIME_DATA_DOES_NOT_MATCH_FORMAT_RE,
544
                        (groups, named_groups))
545
546
    def test_invalid_token(self):
547
        """Test INVALID_TOKEN_RE."""
548
        msg = 'invalid token'
549
        self.re_matches(msg, re.INVALID_TOKEN_RE, NO_GROUP)
550
551
    def test_exc_must_derive_from(self):
552
        """Test EXC_MUST_DERIVE_FROM_RE."""
553
        msgs = [
554
            # Python 2.7
555
            "exceptions must be old-style classes or derived from "
556
            "BaseException, not NoneType",
557
            # Python 3.3 / 3.4
558
            "exceptions must derive from BaseException",
559
        ]
560
        for msg in msgs:
561
            self.re_matches(msg, re.EXC_MUST_DERIVE_FROM_RE, NO_GROUP)
562
563
    def test_unorderable_types(self):
564
        """Test UNORDERABLE_TYPES_RE."""
565
        msgs = [
566
            # Python 3.2 to 3.5
567
            "unorderable types: str() > int()",
568
            "unorderable types: FoobarClass() <= int()",
569
            # PyPy
570
            "unorderable types: FoobarClass > FoobarClass",
571
        ]
572
        for msg in msgs:
573
            self.re_matches(msg, re.UNORDERABLE_TYPES_RE, NO_GROUP)
574
575
    def test_op_not_supported_between_instances(self):
576
        """Test OP_NOT_SUPP_BETWEEN_INSTANCES_RE."""
577
        msgs = [
578
            # Python 3.6
579
            "'<' not supported between instances of 'int' and 'NoneType'",
580
            "'>' not supported between instances of 'Foo' and 'Foo'",
581
        ]
582
        for msg in msgs:
583
            self.re_matches(msg, re.OP_NOT_SUPP_BETWEEN_INSTANCES_RE, NO_GROUP)
584
585
    def test_max_recursion_depth(self):
586
        """Test MAX_RECURSION_DEPTH_RE."""
587
        msg = 'maximum recursion depth exceeded'
588
        self.re_matches(msg, re.MAX_RECURSION_DEPTH_RE, NO_GROUP)
589
590
    def test_size_changed_during_iter(self):
591
        """Test SIZE_CHANGED_DURING_ITER_RE."""
592
        msgs = {
593
            "Set": "Set changed size during iteration",
594
            "dictionnary": "dictionnary changed size during iteration",
595
        }
596
        for name, msg in msgs.items():
597
            groups = (name, )
598
            self.re_matches(msg,
599
                            re.SIZE_CHANGED_DURING_ITER_RE,
600
                            (groups, dict()))
601
602
if __name__ == '__main__':
603
    print(sys.version_info)
604
    unittest2.main()
605