blob: ef2d1daaf9420dc670cd07ffb4a2fae7e5cad5c3 [file] [log] [blame]
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001import enum
Ethan Furman5875d742013-10-21 20:45:55 -07002import inspect
3import pydoc
Ethan Furman6b3d64a2013-06-14 16:55:46 -07004import unittest
Antoine Pitroua6a4dc82017-09-07 18:56:24 +02005import threading
Ethan Furman6b3d64a2013-06-14 16:55:46 -07006from collections import OrderedDict
Ethan Furmanc16595e2016-09-10 23:36:59 -07007from enum import Enum, IntEnum, EnumMeta, Flag, IntFlag, unique, auto
Ethan Furman5875d742013-10-21 20:45:55 -07008from io import StringIO
Ethan Furman2ddb39a2014-02-06 17:28:50 -08009from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL
Martin Panter19e69c52015-11-14 12:46:42 +000010from test import support
Ethan Furmana4b1bb42018-01-22 07:56:37 -080011from datetime import timedelta
Ethan Furman28cf6632017-01-24 12:12:06 -080012
Ethan Furmana4b1bb42018-01-22 07:56:37 -080013try:
14 import threading
15except ImportError:
16 threading = None
Ethan Furman6b3d64a2013-06-14 16:55:46 -070017
18# for pickle tests
19try:
20 class Stooges(Enum):
21 LARRY = 1
22 CURLY = 2
23 MOE = 3
24except Exception as exc:
25 Stooges = exc
26
27try:
28 class IntStooges(int, Enum):
29 LARRY = 1
30 CURLY = 2
31 MOE = 3
32except Exception as exc:
33 IntStooges = exc
34
35try:
36 class FloatStooges(float, Enum):
37 LARRY = 1.39
38 CURLY = 2.72
39 MOE = 3.142596
40except Exception as exc:
41 FloatStooges = exc
42
Ethan Furman65a5a472016-09-01 23:55:19 -070043try:
44 class FlagStooges(Flag):
45 LARRY = 1
46 CURLY = 2
47 MOE = 3
48except Exception as exc:
49 FlagStooges = exc
50
Ethan Furman6b3d64a2013-06-14 16:55:46 -070051# for pickle test and subclass tests
52try:
53 class StrEnum(str, Enum):
54 'accepts only string values'
55 class Name(StrEnum):
56 BDFL = 'Guido van Rossum'
57 FLUFL = 'Barry Warsaw'
58except Exception as exc:
59 Name = exc
60
61try:
62 Question = Enum('Question', 'who what when where why', module=__name__)
63except Exception as exc:
64 Question = exc
65
66try:
67 Answer = Enum('Answer', 'him this then there because')
68except Exception as exc:
69 Answer = exc
70
Ethan Furmanca1b7942014-02-08 11:36:27 -080071try:
72 Theory = Enum('Theory', 'rule law supposition', qualname='spanish_inquisition')
73except Exception as exc:
74 Theory = exc
75
Ethan Furman6b3d64a2013-06-14 16:55:46 -070076# for doctests
77try:
78 class Fruit(Enum):
Ethan Furman23bb6f42016-11-21 09:22:05 -080079 TOMATO = 1
80 BANANA = 2
81 CHERRY = 3
Ethan Furman6b3d64a2013-06-14 16:55:46 -070082except Exception:
83 pass
84
Serhiy Storchakae50e7802015-03-31 16:56:49 +030085def test_pickle_dump_load(assertion, source, target=None):
Ethan Furman2ddb39a2014-02-06 17:28:50 -080086 if target is None:
87 target = source
Serhiy Storchakae50e7802015-03-31 16:56:49 +030088 for protocol in range(HIGHEST_PROTOCOL + 1):
Ethan Furman2ddb39a2014-02-06 17:28:50 -080089 assertion(loads(dumps(source, protocol=protocol)), target)
90
Serhiy Storchakae50e7802015-03-31 16:56:49 +030091def test_pickle_exception(assertion, exception, obj):
92 for protocol in range(HIGHEST_PROTOCOL + 1):
Ethan Furman2ddb39a2014-02-06 17:28:50 -080093 with assertion(exception):
94 dumps(obj, protocol=protocol)
Ethan Furman648f8602013-10-06 17:19:54 -070095
96class TestHelpers(unittest.TestCase):
97 # _is_descriptor, _is_sunder, _is_dunder
98
99 def test_is_descriptor(self):
100 class foo:
101 pass
102 for attr in ('__get__','__set__','__delete__'):
103 obj = foo()
104 self.assertFalse(enum._is_descriptor(obj))
105 setattr(obj, attr, 1)
106 self.assertTrue(enum._is_descriptor(obj))
107
108 def test_is_sunder(self):
109 for s in ('_a_', '_aa_'):
110 self.assertTrue(enum._is_sunder(s))
111
112 for s in ('a', 'a_', '_a', '__a', 'a__', '__a__', '_a__', '__a_', '_',
113 '__', '___', '____', '_____',):
114 self.assertFalse(enum._is_sunder(s))
115
116 def test_is_dunder(self):
117 for s in ('__a__', '__aa__'):
118 self.assertTrue(enum._is_dunder(s))
119 for s in ('a', 'a_', '_a', '__a', 'a__', '_a_', '_a__', '__a_', '_',
120 '__', '___', '____', '_____',):
121 self.assertFalse(enum._is_dunder(s))
122
Ethan Furmanc16595e2016-09-10 23:36:59 -0700123# tests
Ethan Furman648f8602013-10-06 17:19:54 -0700124
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700125class TestEnum(unittest.TestCase):
Ethan Furmanca1b7942014-02-08 11:36:27 -0800126
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700127 def setUp(self):
128 class Season(Enum):
129 SPRING = 1
130 SUMMER = 2
131 AUTUMN = 3
132 WINTER = 4
133 self.Season = Season
134
Ethan Furmanec15a822013-08-31 19:17:41 -0700135 class Konstants(float, Enum):
136 E = 2.7182818
137 PI = 3.1415926
138 TAU = 2 * PI
139 self.Konstants = Konstants
140
141 class Grades(IntEnum):
142 A = 5
143 B = 4
144 C = 3
145 D = 2
146 F = 0
147 self.Grades = Grades
148
149 class Directional(str, Enum):
150 EAST = 'east'
151 WEST = 'west'
152 NORTH = 'north'
153 SOUTH = 'south'
154 self.Directional = Directional
155
156 from datetime import date
157 class Holiday(date, Enum):
158 NEW_YEAR = 2013, 1, 1
159 IDES_OF_MARCH = 2013, 3, 15
160 self.Holiday = Holiday
161
Ethan Furman388a3922013-08-12 06:51:41 -0700162 def test_dir_on_class(self):
163 Season = self.Season
164 self.assertEqual(
165 set(dir(Season)),
Ethan Furmanc850f342013-09-15 16:59:35 -0700166 set(['__class__', '__doc__', '__members__', '__module__',
Ethan Furman388a3922013-08-12 06:51:41 -0700167 'SPRING', 'SUMMER', 'AUTUMN', 'WINTER']),
168 )
169
170 def test_dir_on_item(self):
171 Season = self.Season
172 self.assertEqual(
173 set(dir(Season.WINTER)),
Ethan Furmanc850f342013-09-15 16:59:35 -0700174 set(['__class__', '__doc__', '__module__', 'name', 'value']),
Ethan Furman388a3922013-08-12 06:51:41 -0700175 )
176
Ethan Furmanc850f342013-09-15 16:59:35 -0700177 def test_dir_with_added_behavior(self):
178 class Test(Enum):
179 this = 'that'
180 these = 'those'
181 def wowser(self):
182 return ("Wowser! I'm %s!" % self.name)
183 self.assertEqual(
184 set(dir(Test)),
185 set(['__class__', '__doc__', '__members__', '__module__', 'this', 'these']),
186 )
187 self.assertEqual(
188 set(dir(Test.this)),
189 set(['__class__', '__doc__', '__module__', 'name', 'value', 'wowser']),
190 )
191
Ethan Furman0ae550b2014-10-14 08:58:32 -0700192 def test_dir_on_sub_with_behavior_on_super(self):
193 # see issue22506
194 class SuperEnum(Enum):
195 def invisible(self):
196 return "did you see me?"
197 class SubEnum(SuperEnum):
198 sample = 5
199 self.assertEqual(
200 set(dir(SubEnum.sample)),
201 set(['__class__', '__doc__', '__module__', 'name', 'value', 'invisible']),
202 )
203
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700204 def test_enum_in_enum_out(self):
205 Season = self.Season
206 self.assertIs(Season(Season.WINTER), Season.WINTER)
207
208 def test_enum_value(self):
209 Season = self.Season
210 self.assertEqual(Season.SPRING.value, 1)
211
212 def test_intenum_value(self):
213 self.assertEqual(IntStooges.CURLY.value, 2)
214
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700215 def test_enum(self):
216 Season = self.Season
217 lst = list(Season)
218 self.assertEqual(len(lst), len(Season))
219 self.assertEqual(len(Season), 4, Season)
220 self.assertEqual(
221 [Season.SPRING, Season.SUMMER, Season.AUTUMN, Season.WINTER], lst)
222
223 for i, season in enumerate('SPRING SUMMER AUTUMN WINTER'.split(), 1):
224 e = Season(i)
225 self.assertEqual(e, getattr(Season, season))
226 self.assertEqual(e.value, i)
227 self.assertNotEqual(e, i)
228 self.assertEqual(e.name, season)
229 self.assertIn(e, Season)
230 self.assertIs(type(e), Season)
231 self.assertIsInstance(e, Season)
232 self.assertEqual(str(e), 'Season.' + season)
233 self.assertEqual(
234 repr(e),
235 '<Season.{0}: {1}>'.format(season, i),
236 )
237
238 def test_value_name(self):
239 Season = self.Season
240 self.assertEqual(Season.SPRING.name, 'SPRING')
241 self.assertEqual(Season.SPRING.value, 1)
242 with self.assertRaises(AttributeError):
243 Season.SPRING.name = 'invierno'
244 with self.assertRaises(AttributeError):
245 Season.SPRING.value = 2
246
Ethan Furmanf203f2d2013-09-06 07:16:48 -0700247 def test_changing_member(self):
248 Season = self.Season
249 with self.assertRaises(AttributeError):
250 Season.WINTER = 'really cold'
251
Ethan Furman64a99722013-09-22 16:18:19 -0700252 def test_attribute_deletion(self):
253 class Season(Enum):
254 SPRING = 1
255 SUMMER = 2
256 AUTUMN = 3
257 WINTER = 4
258
259 def spam(cls):
260 pass
261
262 self.assertTrue(hasattr(Season, 'spam'))
263 del Season.spam
264 self.assertFalse(hasattr(Season, 'spam'))
265
266 with self.assertRaises(AttributeError):
267 del Season.SPRING
268 with self.assertRaises(AttributeError):
269 del Season.DRY
270 with self.assertRaises(AttributeError):
271 del Season.SPRING.name
272
Ethan Furman5de67b12016-04-13 23:52:09 -0700273 def test_bool_of_class(self):
274 class Empty(Enum):
275 pass
276 self.assertTrue(bool(Empty))
277
278 def test_bool_of_member(self):
279 class Count(Enum):
280 zero = 0
281 one = 1
282 two = 2
283 for member in Count:
284 self.assertTrue(bool(member))
285
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700286 def test_invalid_names(self):
287 with self.assertRaises(ValueError):
288 class Wrong(Enum):
289 mro = 9
290 with self.assertRaises(ValueError):
291 class Wrong(Enum):
292 _create_= 11
293 with self.assertRaises(ValueError):
294 class Wrong(Enum):
295 _get_mixins_ = 9
296 with self.assertRaises(ValueError):
297 class Wrong(Enum):
298 _find_new_ = 1
299 with self.assertRaises(ValueError):
300 class Wrong(Enum):
301 _any_name_ = 9
302
Ethan Furman6db1fd52015-09-17 21:49:12 -0700303 def test_bool(self):
Ethan Furman60255b62016-01-15 15:01:33 -0800304 # plain Enum members are always True
Ethan Furman6db1fd52015-09-17 21:49:12 -0700305 class Logic(Enum):
306 true = True
307 false = False
308 self.assertTrue(Logic.true)
Ethan Furman60255b62016-01-15 15:01:33 -0800309 self.assertTrue(Logic.false)
310 # unless overridden
311 class RealLogic(Enum):
312 true = True
313 false = False
314 def __bool__(self):
315 return bool(self._value_)
316 self.assertTrue(RealLogic.true)
317 self.assertFalse(RealLogic.false)
318 # mixed Enums depend on mixed-in type
319 class IntLogic(int, Enum):
320 true = 1
321 false = 0
322 self.assertTrue(IntLogic.true)
323 self.assertFalse(IntLogic.false)
Ethan Furman6db1fd52015-09-17 21:49:12 -0700324
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700325 def test_contains(self):
326 Season = self.Season
327 self.assertIn(Season.AUTUMN, Season)
Ethan Furman37151762018-04-11 18:56:25 -0700328 with self.assertWarns(DeprecationWarning):
329 self.assertNotIn(3, Season)
330 with self.assertWarns(DeprecationWarning):
331 self.assertNotIn('AUTUMN', Season)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700332
333 val = Season(3)
334 self.assertIn(val, Season)
335
336 class OtherEnum(Enum):
337 one = 1; two = 2
338 self.assertNotIn(OtherEnum.two, Season)
339
Ethan Furman37151762018-04-11 18:56:25 -0700340 def test_member_contains(self):
341 self.assertRaises(TypeError, lambda: 'test' in self.Season.AUTUMN)
342 self.assertRaises(TypeError, lambda: 3 in self.Season.AUTUMN)
343 self.assertRaises(TypeError, lambda: 'AUTUMN' in self.Season.AUTUMN)
344
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700345 def test_comparisons(self):
346 Season = self.Season
347 with self.assertRaises(TypeError):
348 Season.SPRING < Season.WINTER
349 with self.assertRaises(TypeError):
350 Season.SPRING > 4
351
352 self.assertNotEqual(Season.SPRING, 1)
353
354 class Part(Enum):
355 SPRING = 1
356 CLIP = 2
357 BARREL = 3
358
359 self.assertNotEqual(Season.SPRING, Part.SPRING)
360 with self.assertRaises(TypeError):
361 Season.SPRING < Part.CLIP
362
363 def test_enum_duplicates(self):
364 class Season(Enum):
365 SPRING = 1
366 SUMMER = 2
367 AUTUMN = FALL = 3
368 WINTER = 4
369 ANOTHER_SPRING = 1
370 lst = list(Season)
371 self.assertEqual(
372 lst,
373 [Season.SPRING, Season.SUMMER,
374 Season.AUTUMN, Season.WINTER,
375 ])
376 self.assertIs(Season.FALL, Season.AUTUMN)
377 self.assertEqual(Season.FALL.value, 3)
378 self.assertEqual(Season.AUTUMN.value, 3)
379 self.assertIs(Season(3), Season.AUTUMN)
380 self.assertIs(Season(1), Season.SPRING)
381 self.assertEqual(Season.FALL.name, 'AUTUMN')
382 self.assertEqual(
383 [k for k,v in Season.__members__.items() if v.name != k],
384 ['FALL', 'ANOTHER_SPRING'],
385 )
386
Ethan Furman101e0742013-09-15 12:34:36 -0700387 def test_duplicate_name(self):
388 with self.assertRaises(TypeError):
389 class Color(Enum):
390 red = 1
391 green = 2
392 blue = 3
393 red = 4
394
395 with self.assertRaises(TypeError):
396 class Color(Enum):
397 red = 1
398 green = 2
399 blue = 3
400 def red(self):
401 return 'red'
402
403 with self.assertRaises(TypeError):
404 class Color(Enum):
405 @property
406 def red(self):
407 return 'redder'
408 red = 1
409 green = 2
410 blue = 3
411
412
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700413 def test_enum_with_value_name(self):
414 class Huh(Enum):
415 name = 1
416 value = 2
417 self.assertEqual(
418 list(Huh),
419 [Huh.name, Huh.value],
420 )
421 self.assertIs(type(Huh.name), Huh)
422 self.assertEqual(Huh.name.name, 'name')
423 self.assertEqual(Huh.name.value, 1)
Ethan Furmanec15a822013-08-31 19:17:41 -0700424
425 def test_format_enum(self):
426 Season = self.Season
427 self.assertEqual('{}'.format(Season.SPRING),
428 '{}'.format(str(Season.SPRING)))
429 self.assertEqual( '{:}'.format(Season.SPRING),
430 '{:}'.format(str(Season.SPRING)))
431 self.assertEqual('{:20}'.format(Season.SPRING),
432 '{:20}'.format(str(Season.SPRING)))
433 self.assertEqual('{:^20}'.format(Season.SPRING),
434 '{:^20}'.format(str(Season.SPRING)))
435 self.assertEqual('{:>20}'.format(Season.SPRING),
436 '{:>20}'.format(str(Season.SPRING)))
437 self.assertEqual('{:<20}'.format(Season.SPRING),
438 '{:<20}'.format(str(Season.SPRING)))
439
440 def test_format_enum_custom(self):
441 class TestFloat(float, Enum):
442 one = 1.0
443 two = 2.0
444 def __format__(self, spec):
445 return 'TestFloat success!'
446 self.assertEqual('{}'.format(TestFloat.one), 'TestFloat success!')
447
448 def assertFormatIsValue(self, spec, member):
449 self.assertEqual(spec.format(member), spec.format(member.value))
450
451 def test_format_enum_date(self):
452 Holiday = self.Holiday
453 self.assertFormatIsValue('{}', Holiday.IDES_OF_MARCH)
454 self.assertFormatIsValue('{:}', Holiday.IDES_OF_MARCH)
455 self.assertFormatIsValue('{:20}', Holiday.IDES_OF_MARCH)
456 self.assertFormatIsValue('{:^20}', Holiday.IDES_OF_MARCH)
457 self.assertFormatIsValue('{:>20}', Holiday.IDES_OF_MARCH)
458 self.assertFormatIsValue('{:<20}', Holiday.IDES_OF_MARCH)
459 self.assertFormatIsValue('{:%Y %m}', Holiday.IDES_OF_MARCH)
460 self.assertFormatIsValue('{:%Y %m %M:00}', Holiday.IDES_OF_MARCH)
461
462 def test_format_enum_float(self):
463 Konstants = self.Konstants
464 self.assertFormatIsValue('{}', Konstants.TAU)
465 self.assertFormatIsValue('{:}', Konstants.TAU)
466 self.assertFormatIsValue('{:20}', Konstants.TAU)
467 self.assertFormatIsValue('{:^20}', Konstants.TAU)
468 self.assertFormatIsValue('{:>20}', Konstants.TAU)
469 self.assertFormatIsValue('{:<20}', Konstants.TAU)
470 self.assertFormatIsValue('{:n}', Konstants.TAU)
471 self.assertFormatIsValue('{:5.2}', Konstants.TAU)
472 self.assertFormatIsValue('{:f}', Konstants.TAU)
473
474 def test_format_enum_int(self):
475 Grades = self.Grades
476 self.assertFormatIsValue('{}', Grades.C)
477 self.assertFormatIsValue('{:}', Grades.C)
478 self.assertFormatIsValue('{:20}', Grades.C)
479 self.assertFormatIsValue('{:^20}', Grades.C)
480 self.assertFormatIsValue('{:>20}', Grades.C)
481 self.assertFormatIsValue('{:<20}', Grades.C)
482 self.assertFormatIsValue('{:+}', Grades.C)
483 self.assertFormatIsValue('{:08X}', Grades.C)
484 self.assertFormatIsValue('{:b}', Grades.C)
485
486 def test_format_enum_str(self):
487 Directional = self.Directional
488 self.assertFormatIsValue('{}', Directional.WEST)
489 self.assertFormatIsValue('{:}', Directional.WEST)
490 self.assertFormatIsValue('{:20}', Directional.WEST)
491 self.assertFormatIsValue('{:^20}', Directional.WEST)
492 self.assertFormatIsValue('{:>20}', Directional.WEST)
493 self.assertFormatIsValue('{:<20}', Directional.WEST)
494
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700495 def test_hash(self):
496 Season = self.Season
497 dates = {}
498 dates[Season.WINTER] = '1225'
499 dates[Season.SPRING] = '0315'
500 dates[Season.SUMMER] = '0704'
501 dates[Season.AUTUMN] = '1031'
502 self.assertEqual(dates[Season.AUTUMN], '1031')
503
504 def test_intenum_from_scratch(self):
505 class phy(int, Enum):
506 pi = 3
507 tau = 2 * pi
508 self.assertTrue(phy.pi < phy.tau)
509
510 def test_intenum_inherited(self):
511 class IntEnum(int, Enum):
512 pass
513 class phy(IntEnum):
514 pi = 3
515 tau = 2 * pi
516 self.assertTrue(phy.pi < phy.tau)
517
518 def test_floatenum_from_scratch(self):
519 class phy(float, Enum):
Ethan Furmanec15a822013-08-31 19:17:41 -0700520 pi = 3.1415926
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700521 tau = 2 * pi
522 self.assertTrue(phy.pi < phy.tau)
523
524 def test_floatenum_inherited(self):
525 class FloatEnum(float, Enum):
526 pass
527 class phy(FloatEnum):
Ethan Furmanec15a822013-08-31 19:17:41 -0700528 pi = 3.1415926
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700529 tau = 2 * pi
530 self.assertTrue(phy.pi < phy.tau)
531
532 def test_strenum_from_scratch(self):
533 class phy(str, Enum):
534 pi = 'Pi'
535 tau = 'Tau'
536 self.assertTrue(phy.pi < phy.tau)
537
538 def test_strenum_inherited(self):
539 class StrEnum(str, Enum):
540 pass
541 class phy(StrEnum):
542 pi = 'Pi'
543 tau = 'Tau'
544 self.assertTrue(phy.pi < phy.tau)
545
546
547 def test_intenum(self):
548 class WeekDay(IntEnum):
549 SUNDAY = 1
550 MONDAY = 2
551 TUESDAY = 3
552 WEDNESDAY = 4
553 THURSDAY = 5
554 FRIDAY = 6
555 SATURDAY = 7
556
557 self.assertEqual(['a', 'b', 'c'][WeekDay.MONDAY], 'c')
558 self.assertEqual([i for i in range(WeekDay.TUESDAY)], [0, 1, 2])
559
560 lst = list(WeekDay)
561 self.assertEqual(len(lst), len(WeekDay))
562 self.assertEqual(len(WeekDay), 7)
563 target = 'SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY'
564 target = target.split()
565 for i, weekday in enumerate(target, 1):
566 e = WeekDay(i)
567 self.assertEqual(e, i)
568 self.assertEqual(int(e), i)
569 self.assertEqual(e.name, weekday)
570 self.assertIn(e, WeekDay)
571 self.assertEqual(lst.index(e)+1, i)
572 self.assertTrue(0 < e < 8)
573 self.assertIs(type(e), WeekDay)
574 self.assertIsInstance(e, int)
575 self.assertIsInstance(e, Enum)
576
577 def test_intenum_duplicates(self):
578 class WeekDay(IntEnum):
579 SUNDAY = 1
580 MONDAY = 2
581 TUESDAY = TEUSDAY = 3
582 WEDNESDAY = 4
583 THURSDAY = 5
584 FRIDAY = 6
585 SATURDAY = 7
586 self.assertIs(WeekDay.TEUSDAY, WeekDay.TUESDAY)
587 self.assertEqual(WeekDay(3).name, 'TUESDAY')
588 self.assertEqual([k for k,v in WeekDay.__members__.items()
589 if v.name != k], ['TEUSDAY', ])
590
Serhiy Storchakaea36c942016-05-12 10:37:58 +0300591 def test_intenum_from_bytes(self):
592 self.assertIs(IntStooges.from_bytes(b'\x00\x03', 'big'), IntStooges.MOE)
593 with self.assertRaises(ValueError):
594 IntStooges.from_bytes(b'\x00\x05', 'big')
595
596 def test_floatenum_fromhex(self):
597 h = float.hex(FloatStooges.MOE.value)
598 self.assertIs(FloatStooges.fromhex(h), FloatStooges.MOE)
599 h = float.hex(FloatStooges.MOE.value + 0.01)
600 with self.assertRaises(ValueError):
601 FloatStooges.fromhex(h)
602
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700603 def test_pickle_enum(self):
604 if isinstance(Stooges, Exception):
605 raise Stooges
Ethan Furman2ddb39a2014-02-06 17:28:50 -0800606 test_pickle_dump_load(self.assertIs, Stooges.CURLY)
607 test_pickle_dump_load(self.assertIs, Stooges)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700608
609 def test_pickle_int(self):
610 if isinstance(IntStooges, Exception):
611 raise IntStooges
Ethan Furman2ddb39a2014-02-06 17:28:50 -0800612 test_pickle_dump_load(self.assertIs, IntStooges.CURLY)
613 test_pickle_dump_load(self.assertIs, IntStooges)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700614
615 def test_pickle_float(self):
616 if isinstance(FloatStooges, Exception):
617 raise FloatStooges
Ethan Furman2ddb39a2014-02-06 17:28:50 -0800618 test_pickle_dump_load(self.assertIs, FloatStooges.CURLY)
619 test_pickle_dump_load(self.assertIs, FloatStooges)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700620
621 def test_pickle_enum_function(self):
622 if isinstance(Answer, Exception):
623 raise Answer
Ethan Furman2ddb39a2014-02-06 17:28:50 -0800624 test_pickle_dump_load(self.assertIs, Answer.him)
625 test_pickle_dump_load(self.assertIs, Answer)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700626
627 def test_pickle_enum_function_with_module(self):
628 if isinstance(Question, Exception):
629 raise Question
Ethan Furman2ddb39a2014-02-06 17:28:50 -0800630 test_pickle_dump_load(self.assertIs, Question.who)
631 test_pickle_dump_load(self.assertIs, Question)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700632
Ethan Furmanca1b7942014-02-08 11:36:27 -0800633 def test_enum_function_with_qualname(self):
634 if isinstance(Theory, Exception):
635 raise Theory
636 self.assertEqual(Theory.__qualname__, 'spanish_inquisition')
637
638 def test_class_nested_enum_and_pickle_protocol_four(self):
639 # would normally just have this directly in the class namespace
640 class NestedEnum(Enum):
641 twigs = 'common'
642 shiny = 'rare'
643
644 self.__class__.NestedEnum = NestedEnum
645 self.NestedEnum.__qualname__ = '%s.NestedEnum' % self.__class__.__name__
Serhiy Storchakae50e7802015-03-31 16:56:49 +0300646 test_pickle_dump_load(self.assertIs, self.NestedEnum.twigs)
Ethan Furmanca1b7942014-02-08 11:36:27 -0800647
Ethan Furman24e837f2015-03-18 17:27:57 -0700648 def test_pickle_by_name(self):
649 class ReplaceGlobalInt(IntEnum):
650 ONE = 1
651 TWO = 2
652 ReplaceGlobalInt.__reduce_ex__ = enum._reduce_ex_by_name
653 for proto in range(HIGHEST_PROTOCOL):
654 self.assertEqual(ReplaceGlobalInt.TWO.__reduce_ex__(proto), 'TWO')
655
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700656 def test_exploding_pickle(self):
Ethan Furmanca1b7942014-02-08 11:36:27 -0800657 BadPickle = Enum(
658 'BadPickle', 'dill sweet bread-n-butter', module=__name__)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700659 globals()['BadPickle'] = BadPickle
Ethan Furmanca1b7942014-02-08 11:36:27 -0800660 # now break BadPickle to test exception raising
661 enum._make_class_unpicklable(BadPickle)
Ethan Furman2ddb39a2014-02-06 17:28:50 -0800662 test_pickle_exception(self.assertRaises, TypeError, BadPickle.dill)
663 test_pickle_exception(self.assertRaises, PicklingError, BadPickle)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700664
665 def test_string_enum(self):
666 class SkillLevel(str, Enum):
667 master = 'what is the sound of one hand clapping?'
668 journeyman = 'why did the chicken cross the road?'
669 apprentice = 'knock, knock!'
670 self.assertEqual(SkillLevel.apprentice, 'knock, knock!')
671
672 def test_getattr_getitem(self):
673 class Period(Enum):
674 morning = 1
675 noon = 2
676 evening = 3
677 night = 4
678 self.assertIs(Period(2), Period.noon)
679 self.assertIs(getattr(Period, 'night'), Period.night)
680 self.assertIs(Period['morning'], Period.morning)
681
682 def test_getattr_dunder(self):
683 Season = self.Season
684 self.assertTrue(getattr(Season, '__eq__'))
685
686 def test_iteration_order(self):
687 class Season(Enum):
688 SUMMER = 2
689 WINTER = 4
690 AUTUMN = 3
691 SPRING = 1
692 self.assertEqual(
693 list(Season),
694 [Season.SUMMER, Season.WINTER, Season.AUTUMN, Season.SPRING],
695 )
696
Ethan Furman2131a4a2013-09-14 18:11:24 -0700697 def test_reversed_iteration_order(self):
698 self.assertEqual(
699 list(reversed(self.Season)),
700 [self.Season.WINTER, self.Season.AUTUMN, self.Season.SUMMER,
701 self.Season.SPRING]
702 )
703
Martin Pantereb995702016-07-28 01:11:04 +0000704 def test_programmatic_function_string(self):
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700705 SummerMonth = Enum('SummerMonth', 'june july august')
706 lst = list(SummerMonth)
707 self.assertEqual(len(lst), len(SummerMonth))
708 self.assertEqual(len(SummerMonth), 3, SummerMonth)
709 self.assertEqual(
710 [SummerMonth.june, SummerMonth.july, SummerMonth.august],
711 lst,
712 )
713 for i, month in enumerate('june july august'.split(), 1):
714 e = SummerMonth(i)
715 self.assertEqual(int(e.value), i)
716 self.assertNotEqual(e, i)
717 self.assertEqual(e.name, month)
718 self.assertIn(e, SummerMonth)
719 self.assertIs(type(e), SummerMonth)
720
Martin Pantereb995702016-07-28 01:11:04 +0000721 def test_programmatic_function_string_with_start(self):
Ethan Furmand9925a12014-09-16 20:35:55 -0700722 SummerMonth = Enum('SummerMonth', 'june july august', start=10)
723 lst = list(SummerMonth)
724 self.assertEqual(len(lst), len(SummerMonth))
725 self.assertEqual(len(SummerMonth), 3, SummerMonth)
726 self.assertEqual(
727 [SummerMonth.june, SummerMonth.july, SummerMonth.august],
728 lst,
729 )
730 for i, month in enumerate('june july august'.split(), 10):
731 e = SummerMonth(i)
732 self.assertEqual(int(e.value), i)
733 self.assertNotEqual(e, i)
734 self.assertEqual(e.name, month)
735 self.assertIn(e, SummerMonth)
736 self.assertIs(type(e), SummerMonth)
737
Martin Pantereb995702016-07-28 01:11:04 +0000738 def test_programmatic_function_string_list(self):
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700739 SummerMonth = Enum('SummerMonth', ['june', 'july', 'august'])
740 lst = list(SummerMonth)
741 self.assertEqual(len(lst), len(SummerMonth))
742 self.assertEqual(len(SummerMonth), 3, SummerMonth)
743 self.assertEqual(
744 [SummerMonth.june, SummerMonth.july, SummerMonth.august],
745 lst,
746 )
747 for i, month in enumerate('june july august'.split(), 1):
748 e = SummerMonth(i)
749 self.assertEqual(int(e.value), i)
750 self.assertNotEqual(e, i)
751 self.assertEqual(e.name, month)
752 self.assertIn(e, SummerMonth)
753 self.assertIs(type(e), SummerMonth)
754
Martin Pantereb995702016-07-28 01:11:04 +0000755 def test_programmatic_function_string_list_with_start(self):
Ethan Furmand9925a12014-09-16 20:35:55 -0700756 SummerMonth = Enum('SummerMonth', ['june', 'july', 'august'], start=20)
757 lst = list(SummerMonth)
758 self.assertEqual(len(lst), len(SummerMonth))
759 self.assertEqual(len(SummerMonth), 3, SummerMonth)
760 self.assertEqual(
761 [SummerMonth.june, SummerMonth.july, SummerMonth.august],
762 lst,
763 )
764 for i, month in enumerate('june july august'.split(), 20):
765 e = SummerMonth(i)
766 self.assertEqual(int(e.value), i)
767 self.assertNotEqual(e, i)
768 self.assertEqual(e.name, month)
769 self.assertIn(e, SummerMonth)
770 self.assertIs(type(e), SummerMonth)
771
Martin Pantereb995702016-07-28 01:11:04 +0000772 def test_programmatic_function_iterable(self):
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700773 SummerMonth = Enum(
774 'SummerMonth',
775 (('june', 1), ('july', 2), ('august', 3))
776 )
777 lst = list(SummerMonth)
778 self.assertEqual(len(lst), len(SummerMonth))
779 self.assertEqual(len(SummerMonth), 3, SummerMonth)
780 self.assertEqual(
781 [SummerMonth.june, SummerMonth.july, SummerMonth.august],
782 lst,
783 )
784 for i, month in enumerate('june july august'.split(), 1):
785 e = SummerMonth(i)
786 self.assertEqual(int(e.value), i)
787 self.assertNotEqual(e, i)
788 self.assertEqual(e.name, month)
789 self.assertIn(e, SummerMonth)
790 self.assertIs(type(e), SummerMonth)
791
Martin Pantereb995702016-07-28 01:11:04 +0000792 def test_programmatic_function_from_dict(self):
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700793 SummerMonth = Enum(
794 'SummerMonth',
795 OrderedDict((('june', 1), ('july', 2), ('august', 3)))
796 )
797 lst = list(SummerMonth)
798 self.assertEqual(len(lst), len(SummerMonth))
799 self.assertEqual(len(SummerMonth), 3, SummerMonth)
800 self.assertEqual(
801 [SummerMonth.june, SummerMonth.july, SummerMonth.august],
802 lst,
803 )
804 for i, month in enumerate('june july august'.split(), 1):
805 e = SummerMonth(i)
806 self.assertEqual(int(e.value), i)
807 self.assertNotEqual(e, i)
808 self.assertEqual(e.name, month)
809 self.assertIn(e, SummerMonth)
810 self.assertIs(type(e), SummerMonth)
811
Martin Pantereb995702016-07-28 01:11:04 +0000812 def test_programmatic_function_type(self):
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700813 SummerMonth = Enum('SummerMonth', 'june july august', type=int)
814 lst = list(SummerMonth)
815 self.assertEqual(len(lst), len(SummerMonth))
816 self.assertEqual(len(SummerMonth), 3, SummerMonth)
817 self.assertEqual(
818 [SummerMonth.june, SummerMonth.july, SummerMonth.august],
819 lst,
820 )
821 for i, month in enumerate('june july august'.split(), 1):
822 e = SummerMonth(i)
823 self.assertEqual(e, i)
824 self.assertEqual(e.name, month)
825 self.assertIn(e, SummerMonth)
826 self.assertIs(type(e), SummerMonth)
827
Martin Pantereb995702016-07-28 01:11:04 +0000828 def test_programmatic_function_type_with_start(self):
Ethan Furmand9925a12014-09-16 20:35:55 -0700829 SummerMonth = Enum('SummerMonth', 'june july august', type=int, start=30)
830 lst = list(SummerMonth)
831 self.assertEqual(len(lst), len(SummerMonth))
832 self.assertEqual(len(SummerMonth), 3, SummerMonth)
833 self.assertEqual(
834 [SummerMonth.june, SummerMonth.july, SummerMonth.august],
835 lst,
836 )
837 for i, month in enumerate('june july august'.split(), 30):
838 e = SummerMonth(i)
839 self.assertEqual(e, i)
840 self.assertEqual(e.name, month)
841 self.assertIn(e, SummerMonth)
842 self.assertIs(type(e), SummerMonth)
843
Martin Pantereb995702016-07-28 01:11:04 +0000844 def test_programmatic_function_type_from_subclass(self):
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700845 SummerMonth = IntEnum('SummerMonth', 'june july august')
846 lst = list(SummerMonth)
847 self.assertEqual(len(lst), len(SummerMonth))
848 self.assertEqual(len(SummerMonth), 3, SummerMonth)
849 self.assertEqual(
850 [SummerMonth.june, SummerMonth.july, SummerMonth.august],
851 lst,
852 )
853 for i, month in enumerate('june july august'.split(), 1):
854 e = SummerMonth(i)
855 self.assertEqual(e, i)
856 self.assertEqual(e.name, month)
857 self.assertIn(e, SummerMonth)
858 self.assertIs(type(e), SummerMonth)
859
Martin Pantereb995702016-07-28 01:11:04 +0000860 def test_programmatic_function_type_from_subclass_with_start(self):
Ethan Furmand9925a12014-09-16 20:35:55 -0700861 SummerMonth = IntEnum('SummerMonth', 'june july august', start=40)
862 lst = list(SummerMonth)
863 self.assertEqual(len(lst), len(SummerMonth))
864 self.assertEqual(len(SummerMonth), 3, SummerMonth)
865 self.assertEqual(
866 [SummerMonth.june, SummerMonth.july, SummerMonth.august],
867 lst,
868 )
869 for i, month in enumerate('june july august'.split(), 40):
870 e = SummerMonth(i)
871 self.assertEqual(e, i)
872 self.assertEqual(e.name, month)
873 self.assertIn(e, SummerMonth)
874 self.assertIs(type(e), SummerMonth)
875
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700876 def test_subclassing(self):
877 if isinstance(Name, Exception):
878 raise Name
879 self.assertEqual(Name.BDFL, 'Guido van Rossum')
880 self.assertTrue(Name.BDFL, Name('Guido van Rossum'))
881 self.assertIs(Name.BDFL, getattr(Name, 'BDFL'))
Ethan Furman2ddb39a2014-02-06 17:28:50 -0800882 test_pickle_dump_load(self.assertIs, Name.BDFL)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700883
884 def test_extending(self):
885 class Color(Enum):
886 red = 1
887 green = 2
888 blue = 3
889 with self.assertRaises(TypeError):
890 class MoreColor(Color):
891 cyan = 4
892 magenta = 5
893 yellow = 6
894
895 def test_exclude_methods(self):
896 class whatever(Enum):
897 this = 'that'
898 these = 'those'
899 def really(self):
900 return 'no, not %s' % self.value
901 self.assertIsNot(type(whatever.really), whatever)
902 self.assertEqual(whatever.this.really(), 'no, not that')
903
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700904 def test_wrong_inheritance_order(self):
905 with self.assertRaises(TypeError):
906 class Wrong(Enum, str):
907 NotHere = 'error before this point'
908
909 def test_intenum_transitivity(self):
910 class number(IntEnum):
911 one = 1
912 two = 2
913 three = 3
914 class numero(IntEnum):
915 uno = 1
916 dos = 2
917 tres = 3
918 self.assertEqual(number.one, numero.uno)
919 self.assertEqual(number.two, numero.dos)
920 self.assertEqual(number.three, numero.tres)
921
922 def test_wrong_enum_in_call(self):
923 class Monochrome(Enum):
924 black = 0
925 white = 1
926 class Gender(Enum):
927 male = 0
928 female = 1
929 self.assertRaises(ValueError, Monochrome, Gender.male)
930
931 def test_wrong_enum_in_mixed_call(self):
932 class Monochrome(IntEnum):
933 black = 0
934 white = 1
935 class Gender(Enum):
936 male = 0
937 female = 1
938 self.assertRaises(ValueError, Monochrome, Gender.male)
939
940 def test_mixed_enum_in_call_1(self):
941 class Monochrome(IntEnum):
942 black = 0
943 white = 1
944 class Gender(IntEnum):
945 male = 0
946 female = 1
947 self.assertIs(Monochrome(Gender.female), Monochrome.white)
948
949 def test_mixed_enum_in_call_2(self):
950 class Monochrome(Enum):
951 black = 0
952 white = 1
953 class Gender(IntEnum):
954 male = 0
955 female = 1
956 self.assertIs(Monochrome(Gender.male), Monochrome.black)
957
958 def test_flufl_enum(self):
959 class Fluflnum(Enum):
960 def __int__(self):
961 return int(self.value)
962 class MailManOptions(Fluflnum):
963 option1 = 1
964 option2 = 2
965 option3 = 3
966 self.assertEqual(int(MailManOptions.option1), 1)
967
Ethan Furman5e5a8232013-08-04 08:42:23 -0700968 def test_introspection(self):
969 class Number(IntEnum):
970 one = 100
971 two = 200
972 self.assertIs(Number.one._member_type_, int)
973 self.assertIs(Number._member_type_, int)
974 class String(str, Enum):
975 yarn = 'soft'
976 rope = 'rough'
977 wire = 'hard'
978 self.assertIs(String.yarn._member_type_, str)
979 self.assertIs(String._member_type_, str)
980 class Plain(Enum):
981 vanilla = 'white'
982 one = 1
983 self.assertIs(Plain.vanilla._member_type_, object)
984 self.assertIs(Plain._member_type_, object)
985
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700986 def test_no_such_enum_member(self):
987 class Color(Enum):
988 red = 1
989 green = 2
990 blue = 3
991 with self.assertRaises(ValueError):
992 Color(4)
993 with self.assertRaises(KeyError):
994 Color['chartreuse']
995
996 def test_new_repr(self):
997 class Color(Enum):
998 red = 1
999 green = 2
1000 blue = 3
1001 def __repr__(self):
1002 return "don't you just love shades of %s?" % self.name
1003 self.assertEqual(
1004 repr(Color.blue),
1005 "don't you just love shades of blue?",
1006 )
1007
1008 def test_inherited_repr(self):
1009 class MyEnum(Enum):
1010 def __repr__(self):
1011 return "My name is %s." % self.name
1012 class MyIntEnum(int, MyEnum):
1013 this = 1
1014 that = 2
1015 theother = 3
1016 self.assertEqual(repr(MyIntEnum.that), "My name is that.")
1017
1018 def test_multiple_mixin_mro(self):
1019 class auto_enum(type(Enum)):
1020 def __new__(metacls, cls, bases, classdict):
1021 temp = type(classdict)()
1022 names = set(classdict._member_names)
1023 i = 0
1024 for k in classdict._member_names:
1025 v = classdict[k]
1026 if v is Ellipsis:
1027 v = i
1028 else:
1029 i = v
1030 i += 1
1031 temp[k] = v
1032 for k, v in classdict.items():
1033 if k not in names:
1034 temp[k] = v
1035 return super(auto_enum, metacls).__new__(
1036 metacls, cls, bases, temp)
1037
1038 class AutoNumberedEnum(Enum, metaclass=auto_enum):
1039 pass
1040
1041 class AutoIntEnum(IntEnum, metaclass=auto_enum):
1042 pass
1043
1044 class TestAutoNumber(AutoNumberedEnum):
1045 a = ...
1046 b = 3
1047 c = ...
1048
1049 class TestAutoInt(AutoIntEnum):
1050 a = ...
1051 b = 3
1052 c = ...
1053
1054 def test_subclasses_with_getnewargs(self):
1055 class NamedInt(int):
Ethan Furman2ddb39a2014-02-06 17:28:50 -08001056 __qualname__ = 'NamedInt' # needed for pickle protocol 4
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001057 def __new__(cls, *args):
1058 _args = args
1059 name, *args = args
1060 if len(args) == 0:
1061 raise TypeError("name and value must be specified")
1062 self = int.__new__(cls, *args)
1063 self._intname = name
1064 self._args = _args
1065 return self
1066 def __getnewargs__(self):
1067 return self._args
1068 @property
1069 def __name__(self):
1070 return self._intname
1071 def __repr__(self):
1072 # repr() is updated to include the name and type info
1073 return "{}({!r}, {})".format(type(self).__name__,
1074 self.__name__,
1075 int.__repr__(self))
1076 def __str__(self):
1077 # str() is unchanged, even if it relies on the repr() fallback
1078 base = int
1079 base_str = base.__str__
1080 if base_str.__objclass__ is object:
1081 return base.__repr__(self)
1082 return base_str(self)
1083 # for simplicity, we only define one operator that
1084 # propagates expressions
1085 def __add__(self, other):
1086 temp = int(self) + int( other)
1087 if isinstance(self, NamedInt) and isinstance(other, NamedInt):
1088 return NamedInt(
1089 '({0} + {1})'.format(self.__name__, other.__name__),
1090 temp )
1091 else:
1092 return temp
1093
1094 class NEI(NamedInt, Enum):
Ethan Furman2ddb39a2014-02-06 17:28:50 -08001095 __qualname__ = 'NEI' # needed for pickle protocol 4
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001096 x = ('the-x', 1)
1097 y = ('the-y', 2)
1098
Ethan Furman2aa27322013-07-19 19:35:56 -07001099
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001100 self.assertIs(NEI.__new__, Enum.__new__)
1101 self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
1102 globals()['NamedInt'] = NamedInt
1103 globals()['NEI'] = NEI
1104 NI5 = NamedInt('test', 5)
1105 self.assertEqual(NI5, 5)
Ethan Furman2ddb39a2014-02-06 17:28:50 -08001106 test_pickle_dump_load(self.assertEqual, NI5, 5)
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001107 self.assertEqual(NEI.y.value, 2)
Ethan Furman2ddb39a2014-02-06 17:28:50 -08001108 test_pickle_dump_load(self.assertIs, NEI.y)
Ethan Furmandc870522014-02-18 12:37:12 -08001109 test_pickle_dump_load(self.assertIs, NEI)
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001110
Ethan Furmanca1b7942014-02-08 11:36:27 -08001111 def test_subclasses_with_getnewargs_ex(self):
1112 class NamedInt(int):
1113 __qualname__ = 'NamedInt' # needed for pickle protocol 4
1114 def __new__(cls, *args):
1115 _args = args
1116 name, *args = args
1117 if len(args) == 0:
1118 raise TypeError("name and value must be specified")
1119 self = int.__new__(cls, *args)
1120 self._intname = name
1121 self._args = _args
1122 return self
1123 def __getnewargs_ex__(self):
1124 return self._args, {}
1125 @property
1126 def __name__(self):
1127 return self._intname
1128 def __repr__(self):
1129 # repr() is updated to include the name and type info
1130 return "{}({!r}, {})".format(type(self).__name__,
1131 self.__name__,
1132 int.__repr__(self))
1133 def __str__(self):
1134 # str() is unchanged, even if it relies on the repr() fallback
1135 base = int
1136 base_str = base.__str__
1137 if base_str.__objclass__ is object:
1138 return base.__repr__(self)
1139 return base_str(self)
1140 # for simplicity, we only define one operator that
1141 # propagates expressions
1142 def __add__(self, other):
1143 temp = int(self) + int( other)
1144 if isinstance(self, NamedInt) and isinstance(other, NamedInt):
1145 return NamedInt(
1146 '({0} + {1})'.format(self.__name__, other.__name__),
1147 temp )
1148 else:
1149 return temp
1150
1151 class NEI(NamedInt, Enum):
1152 __qualname__ = 'NEI' # needed for pickle protocol 4
1153 x = ('the-x', 1)
1154 y = ('the-y', 2)
1155
1156
1157 self.assertIs(NEI.__new__, Enum.__new__)
1158 self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
1159 globals()['NamedInt'] = NamedInt
1160 globals()['NEI'] = NEI
1161 NI5 = NamedInt('test', 5)
1162 self.assertEqual(NI5, 5)
Serhiy Storchakae50e7802015-03-31 16:56:49 +03001163 test_pickle_dump_load(self.assertEqual, NI5, 5)
Ethan Furmanca1b7942014-02-08 11:36:27 -08001164 self.assertEqual(NEI.y.value, 2)
Serhiy Storchakae50e7802015-03-31 16:56:49 +03001165 test_pickle_dump_load(self.assertIs, NEI.y)
Ethan Furmandc870522014-02-18 12:37:12 -08001166 test_pickle_dump_load(self.assertIs, NEI)
Ethan Furmanca1b7942014-02-08 11:36:27 -08001167
1168 def test_subclasses_with_reduce(self):
1169 class NamedInt(int):
1170 __qualname__ = 'NamedInt' # needed for pickle protocol 4
1171 def __new__(cls, *args):
1172 _args = args
1173 name, *args = args
1174 if len(args) == 0:
1175 raise TypeError("name and value must be specified")
1176 self = int.__new__(cls, *args)
1177 self._intname = name
1178 self._args = _args
1179 return self
1180 def __reduce__(self):
1181 return self.__class__, self._args
1182 @property
1183 def __name__(self):
1184 return self._intname
1185 def __repr__(self):
1186 # repr() is updated to include the name and type info
1187 return "{}({!r}, {})".format(type(self).__name__,
1188 self.__name__,
1189 int.__repr__(self))
1190 def __str__(self):
1191 # str() is unchanged, even if it relies on the repr() fallback
1192 base = int
1193 base_str = base.__str__
1194 if base_str.__objclass__ is object:
1195 return base.__repr__(self)
1196 return base_str(self)
1197 # for simplicity, we only define one operator that
1198 # propagates expressions
1199 def __add__(self, other):
1200 temp = int(self) + int( other)
1201 if isinstance(self, NamedInt) and isinstance(other, NamedInt):
1202 return NamedInt(
1203 '({0} + {1})'.format(self.__name__, other.__name__),
1204 temp )
1205 else:
1206 return temp
1207
1208 class NEI(NamedInt, Enum):
1209 __qualname__ = 'NEI' # needed for pickle protocol 4
1210 x = ('the-x', 1)
1211 y = ('the-y', 2)
1212
1213
1214 self.assertIs(NEI.__new__, Enum.__new__)
1215 self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
1216 globals()['NamedInt'] = NamedInt
1217 globals()['NEI'] = NEI
1218 NI5 = NamedInt('test', 5)
1219 self.assertEqual(NI5, 5)
1220 test_pickle_dump_load(self.assertEqual, NI5, 5)
1221 self.assertEqual(NEI.y.value, 2)
1222 test_pickle_dump_load(self.assertIs, NEI.y)
Ethan Furmandc870522014-02-18 12:37:12 -08001223 test_pickle_dump_load(self.assertIs, NEI)
Ethan Furmanca1b7942014-02-08 11:36:27 -08001224
1225 def test_subclasses_with_reduce_ex(self):
1226 class NamedInt(int):
1227 __qualname__ = 'NamedInt' # needed for pickle protocol 4
1228 def __new__(cls, *args):
1229 _args = args
1230 name, *args = args
1231 if len(args) == 0:
1232 raise TypeError("name and value must be specified")
1233 self = int.__new__(cls, *args)
1234 self._intname = name
1235 self._args = _args
1236 return self
1237 def __reduce_ex__(self, proto):
1238 return self.__class__, self._args
1239 @property
1240 def __name__(self):
1241 return self._intname
1242 def __repr__(self):
1243 # repr() is updated to include the name and type info
1244 return "{}({!r}, {})".format(type(self).__name__,
1245 self.__name__,
1246 int.__repr__(self))
1247 def __str__(self):
1248 # str() is unchanged, even if it relies on the repr() fallback
1249 base = int
1250 base_str = base.__str__
1251 if base_str.__objclass__ is object:
1252 return base.__repr__(self)
1253 return base_str(self)
1254 # for simplicity, we only define one operator that
1255 # propagates expressions
1256 def __add__(self, other):
1257 temp = int(self) + int( other)
1258 if isinstance(self, NamedInt) and isinstance(other, NamedInt):
1259 return NamedInt(
1260 '({0} + {1})'.format(self.__name__, other.__name__),
1261 temp )
1262 else:
1263 return temp
1264
1265 class NEI(NamedInt, Enum):
1266 __qualname__ = 'NEI' # needed for pickle protocol 4
1267 x = ('the-x', 1)
1268 y = ('the-y', 2)
1269
1270
1271 self.assertIs(NEI.__new__, Enum.__new__)
1272 self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
1273 globals()['NamedInt'] = NamedInt
1274 globals()['NEI'] = NEI
1275 NI5 = NamedInt('test', 5)
1276 self.assertEqual(NI5, 5)
1277 test_pickle_dump_load(self.assertEqual, NI5, 5)
1278 self.assertEqual(NEI.y.value, 2)
1279 test_pickle_dump_load(self.assertIs, NEI.y)
Ethan Furmandc870522014-02-18 12:37:12 -08001280 test_pickle_dump_load(self.assertIs, NEI)
Ethan Furmanca1b7942014-02-08 11:36:27 -08001281
Ethan Furmandc870522014-02-18 12:37:12 -08001282 def test_subclasses_without_direct_pickle_support(self):
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001283 class NamedInt(int):
Ethan Furman2ddb39a2014-02-06 17:28:50 -08001284 __qualname__ = 'NamedInt'
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001285 def __new__(cls, *args):
1286 _args = args
1287 name, *args = args
1288 if len(args) == 0:
1289 raise TypeError("name and value must be specified")
1290 self = int.__new__(cls, *args)
1291 self._intname = name
1292 self._args = _args
1293 return self
1294 @property
1295 def __name__(self):
1296 return self._intname
1297 def __repr__(self):
1298 # repr() is updated to include the name and type info
1299 return "{}({!r}, {})".format(type(self).__name__,
1300 self.__name__,
1301 int.__repr__(self))
1302 def __str__(self):
1303 # str() is unchanged, even if it relies on the repr() fallback
1304 base = int
1305 base_str = base.__str__
1306 if base_str.__objclass__ is object:
1307 return base.__repr__(self)
1308 return base_str(self)
1309 # for simplicity, we only define one operator that
1310 # propagates expressions
1311 def __add__(self, other):
1312 temp = int(self) + int( other)
1313 if isinstance(self, NamedInt) and isinstance(other, NamedInt):
1314 return NamedInt(
1315 '({0} + {1})'.format(self.__name__, other.__name__),
1316 temp )
1317 else:
1318 return temp
1319
1320 class NEI(NamedInt, Enum):
Ethan Furman2ddb39a2014-02-06 17:28:50 -08001321 __qualname__ = 'NEI'
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001322 x = ('the-x', 1)
1323 y = ('the-y', 2)
1324
1325 self.assertIs(NEI.__new__, Enum.__new__)
1326 self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
1327 globals()['NamedInt'] = NamedInt
1328 globals()['NEI'] = NEI
1329 NI5 = NamedInt('test', 5)
1330 self.assertEqual(NI5, 5)
1331 self.assertEqual(NEI.y.value, 2)
Ethan Furman2ddb39a2014-02-06 17:28:50 -08001332 test_pickle_exception(self.assertRaises, TypeError, NEI.x)
1333 test_pickle_exception(self.assertRaises, PicklingError, NEI)
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001334
Ethan Furmandc870522014-02-18 12:37:12 -08001335 def test_subclasses_without_direct_pickle_support_using_name(self):
1336 class NamedInt(int):
1337 __qualname__ = 'NamedInt'
1338 def __new__(cls, *args):
1339 _args = args
1340 name, *args = args
1341 if len(args) == 0:
1342 raise TypeError("name and value must be specified")
1343 self = int.__new__(cls, *args)
1344 self._intname = name
1345 self._args = _args
1346 return self
1347 @property
1348 def __name__(self):
1349 return self._intname
1350 def __repr__(self):
1351 # repr() is updated to include the name and type info
1352 return "{}({!r}, {})".format(type(self).__name__,
1353 self.__name__,
1354 int.__repr__(self))
1355 def __str__(self):
1356 # str() is unchanged, even if it relies on the repr() fallback
1357 base = int
1358 base_str = base.__str__
1359 if base_str.__objclass__ is object:
1360 return base.__repr__(self)
1361 return base_str(self)
1362 # for simplicity, we only define one operator that
1363 # propagates expressions
1364 def __add__(self, other):
1365 temp = int(self) + int( other)
1366 if isinstance(self, NamedInt) and isinstance(other, NamedInt):
1367 return NamedInt(
1368 '({0} + {1})'.format(self.__name__, other.__name__),
1369 temp )
1370 else:
1371 return temp
1372
1373 class NEI(NamedInt, Enum):
1374 __qualname__ = 'NEI'
1375 x = ('the-x', 1)
1376 y = ('the-y', 2)
1377 def __reduce_ex__(self, proto):
1378 return getattr, (self.__class__, self._name_)
1379
1380 self.assertIs(NEI.__new__, Enum.__new__)
1381 self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
1382 globals()['NamedInt'] = NamedInt
1383 globals()['NEI'] = NEI
1384 NI5 = NamedInt('test', 5)
1385 self.assertEqual(NI5, 5)
1386 self.assertEqual(NEI.y.value, 2)
1387 test_pickle_dump_load(self.assertIs, NEI.y)
1388 test_pickle_dump_load(self.assertIs, NEI)
1389
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001390 def test_tuple_subclass(self):
1391 class SomeTuple(tuple, Enum):
Ethan Furman2ddb39a2014-02-06 17:28:50 -08001392 __qualname__ = 'SomeTuple' # needed for pickle protocol 4
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001393 first = (1, 'for the money')
1394 second = (2, 'for the show')
1395 third = (3, 'for the music')
1396 self.assertIs(type(SomeTuple.first), SomeTuple)
1397 self.assertIsInstance(SomeTuple.second, tuple)
1398 self.assertEqual(SomeTuple.third, (3, 'for the music'))
1399 globals()['SomeTuple'] = SomeTuple
Ethan Furman2ddb39a2014-02-06 17:28:50 -08001400 test_pickle_dump_load(self.assertIs, SomeTuple.first)
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001401
1402 def test_duplicate_values_give_unique_enum_items(self):
1403 class AutoNumber(Enum):
1404 first = ()
1405 second = ()
1406 third = ()
1407 def __new__(cls):
1408 value = len(cls.__members__) + 1
1409 obj = object.__new__(cls)
Ethan Furman520ad572013-07-19 19:47:21 -07001410 obj._value_ = value
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001411 return obj
1412 def __int__(self):
Ethan Furman520ad572013-07-19 19:47:21 -07001413 return int(self._value_)
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001414 self.assertEqual(
1415 list(AutoNumber),
1416 [AutoNumber.first, AutoNumber.second, AutoNumber.third],
1417 )
1418 self.assertEqual(int(AutoNumber.second), 2)
Ethan Furman2aa27322013-07-19 19:35:56 -07001419 self.assertEqual(AutoNumber.third.value, 3)
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001420 self.assertIs(AutoNumber(1), AutoNumber.first)
1421
1422 def test_inherited_new_from_enhanced_enum(self):
1423 class AutoNumber(Enum):
1424 def __new__(cls):
1425 value = len(cls.__members__) + 1
1426 obj = object.__new__(cls)
Ethan Furman520ad572013-07-19 19:47:21 -07001427 obj._value_ = value
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001428 return obj
1429 def __int__(self):
Ethan Furman520ad572013-07-19 19:47:21 -07001430 return int(self._value_)
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001431 class Color(AutoNumber):
1432 red = ()
1433 green = ()
1434 blue = ()
1435 self.assertEqual(list(Color), [Color.red, Color.green, Color.blue])
1436 self.assertEqual(list(map(int, Color)), [1, 2, 3])
1437
1438 def test_inherited_new_from_mixed_enum(self):
1439 class AutoNumber(IntEnum):
1440 def __new__(cls):
1441 value = len(cls.__members__) + 1
1442 obj = int.__new__(cls, value)
Ethan Furman520ad572013-07-19 19:47:21 -07001443 obj._value_ = value
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001444 return obj
1445 class Color(AutoNumber):
1446 red = ()
1447 green = ()
1448 blue = ()
1449 self.assertEqual(list(Color), [Color.red, Color.green, Color.blue])
1450 self.assertEqual(list(map(int, Color)), [1, 2, 3])
1451
Ethan Furmanbe3c2fe2013-11-13 14:25:45 -08001452 def test_equality(self):
1453 class AlwaysEqual:
1454 def __eq__(self, other):
1455 return True
1456 class OrdinaryEnum(Enum):
1457 a = 1
1458 self.assertEqual(AlwaysEqual(), OrdinaryEnum.a)
1459 self.assertEqual(OrdinaryEnum.a, AlwaysEqual())
1460
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001461 def test_ordered_mixin(self):
1462 class OrderedEnum(Enum):
1463 def __ge__(self, other):
1464 if self.__class__ is other.__class__:
Ethan Furman520ad572013-07-19 19:47:21 -07001465 return self._value_ >= other._value_
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001466 return NotImplemented
1467 def __gt__(self, other):
1468 if self.__class__ is other.__class__:
Ethan Furman520ad572013-07-19 19:47:21 -07001469 return self._value_ > other._value_
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001470 return NotImplemented
1471 def __le__(self, other):
1472 if self.__class__ is other.__class__:
Ethan Furman520ad572013-07-19 19:47:21 -07001473 return self._value_ <= other._value_
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001474 return NotImplemented
1475 def __lt__(self, other):
1476 if self.__class__ is other.__class__:
Ethan Furman520ad572013-07-19 19:47:21 -07001477 return self._value_ < other._value_
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001478 return NotImplemented
1479 class Grade(OrderedEnum):
1480 A = 5
1481 B = 4
1482 C = 3
1483 D = 2
1484 F = 1
1485 self.assertGreater(Grade.A, Grade.B)
1486 self.assertLessEqual(Grade.F, Grade.C)
1487 self.assertLess(Grade.D, Grade.A)
1488 self.assertGreaterEqual(Grade.B, Grade.B)
Ethan Furmanbe3c2fe2013-11-13 14:25:45 -08001489 self.assertEqual(Grade.B, Grade.B)
1490 self.assertNotEqual(Grade.C, Grade.D)
Ethan Furman520ad572013-07-19 19:47:21 -07001491
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001492 def test_extending2(self):
1493 class Shade(Enum):
1494 def shade(self):
1495 print(self.name)
1496 class Color(Shade):
1497 red = 1
1498 green = 2
1499 blue = 3
1500 with self.assertRaises(TypeError):
1501 class MoreColor(Color):
1502 cyan = 4
1503 magenta = 5
1504 yellow = 6
1505
1506 def test_extending3(self):
1507 class Shade(Enum):
1508 def shade(self):
1509 return self.name
1510 class Color(Shade):
1511 def hex(self):
1512 return '%s hexlified!' % self.value
1513 class MoreColor(Color):
1514 cyan = 4
1515 magenta = 5
1516 yellow = 6
1517 self.assertEqual(MoreColor.magenta.hex(), '5 hexlified!')
1518
1519
1520 def test_no_duplicates(self):
1521 class UniqueEnum(Enum):
1522 def __init__(self, *args):
1523 cls = self.__class__
1524 if any(self.value == e.value for e in cls):
1525 a = self.name
1526 e = cls(self.value).name
1527 raise ValueError(
1528 "aliases not allowed in UniqueEnum: %r --> %r"
1529 % (a, e)
1530 )
1531 class Color(UniqueEnum):
1532 red = 1
1533 green = 2
1534 blue = 3
1535 with self.assertRaises(ValueError):
1536 class Color(UniqueEnum):
1537 red = 1
1538 green = 2
1539 blue = 3
1540 grene = 2
1541
1542 def test_init(self):
1543 class Planet(Enum):
1544 MERCURY = (3.303e+23, 2.4397e6)
1545 VENUS = (4.869e+24, 6.0518e6)
1546 EARTH = (5.976e+24, 6.37814e6)
1547 MARS = (6.421e+23, 3.3972e6)
1548 JUPITER = (1.9e+27, 7.1492e7)
1549 SATURN = (5.688e+26, 6.0268e7)
1550 URANUS = (8.686e+25, 2.5559e7)
1551 NEPTUNE = (1.024e+26, 2.4746e7)
1552 def __init__(self, mass, radius):
1553 self.mass = mass # in kilograms
1554 self.radius = radius # in meters
1555 @property
1556 def surface_gravity(self):
1557 # universal gravitational constant (m3 kg-1 s-2)
1558 G = 6.67300E-11
1559 return G * self.mass / (self.radius * self.radius)
1560 self.assertEqual(round(Planet.EARTH.surface_gravity, 2), 9.80)
1561 self.assertEqual(Planet.EARTH.value, (5.976e+24, 6.37814e6))
1562
Ethan Furmana4b1bb42018-01-22 07:56:37 -08001563 def test_ignore(self):
1564 class Period(timedelta, Enum):
1565 '''
1566 different lengths of time
1567 '''
1568 def __new__(cls, value, period):
1569 obj = timedelta.__new__(cls, value)
1570 obj._value_ = value
1571 obj.period = period
1572 return obj
1573 _ignore_ = 'Period i'
1574 Period = vars()
1575 for i in range(13):
1576 Period['month_%d' % i] = i*30, 'month'
1577 for i in range(53):
1578 Period['week_%d' % i] = i*7, 'week'
1579 for i in range(32):
1580 Period['day_%d' % i] = i, 'day'
1581 OneDay = day_1
1582 OneWeek = week_1
1583 OneMonth = month_1
1584 self.assertFalse(hasattr(Period, '_ignore_'))
1585 self.assertFalse(hasattr(Period, 'Period'))
1586 self.assertFalse(hasattr(Period, 'i'))
1587 self.assertTrue(isinstance(Period.day_1, timedelta))
1588 self.assertTrue(Period.month_1 is Period.day_30)
1589 self.assertTrue(Period.week_4 is Period.day_28)
1590
Ethan Furman2aa27322013-07-19 19:35:56 -07001591 def test_nonhash_value(self):
1592 class AutoNumberInAList(Enum):
1593 def __new__(cls):
1594 value = [len(cls.__members__) + 1]
1595 obj = object.__new__(cls)
Ethan Furman520ad572013-07-19 19:47:21 -07001596 obj._value_ = value
Ethan Furman2aa27322013-07-19 19:35:56 -07001597 return obj
1598 class ColorInAList(AutoNumberInAList):
1599 red = ()
1600 green = ()
1601 blue = ()
1602 self.assertEqual(list(ColorInAList), [ColorInAList.red, ColorInAList.green, ColorInAList.blue])
Ethan Furman1a162882013-10-16 19:09:31 -07001603 for enum, value in zip(ColorInAList, range(3)):
1604 value += 1
1605 self.assertEqual(enum.value, [value])
1606 self.assertIs(ColorInAList([value]), enum)
Ethan Furman2aa27322013-07-19 19:35:56 -07001607
Ethan Furmanb41803e2013-07-25 13:50:45 -07001608 def test_conflicting_types_resolved_in_new(self):
1609 class LabelledIntEnum(int, Enum):
1610 def __new__(cls, *args):
1611 value, label = args
1612 obj = int.__new__(cls, value)
1613 obj.label = label
1614 obj._value_ = value
1615 return obj
1616
1617 class LabelledList(LabelledIntEnum):
1618 unprocessed = (1, "Unprocessed")
1619 payment_complete = (2, "Payment Complete")
1620
1621 self.assertEqual(list(LabelledList), [LabelledList.unprocessed, LabelledList.payment_complete])
1622 self.assertEqual(LabelledList.unprocessed, 1)
1623 self.assertEqual(LabelledList(1), LabelledList.unprocessed)
Ethan Furman2aa27322013-07-19 19:35:56 -07001624
Ethan Furmanc16595e2016-09-10 23:36:59 -07001625 def test_auto_number(self):
1626 class Color(Enum):
1627 red = auto()
1628 blue = auto()
1629 green = auto()
1630
1631 self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
1632 self.assertEqual(Color.red.value, 1)
1633 self.assertEqual(Color.blue.value, 2)
1634 self.assertEqual(Color.green.value, 3)
1635
1636 def test_auto_name(self):
1637 class Color(Enum):
1638 def _generate_next_value_(name, start, count, last):
1639 return name
1640 red = auto()
1641 blue = auto()
1642 green = auto()
1643
1644 self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
1645 self.assertEqual(Color.red.value, 'red')
1646 self.assertEqual(Color.blue.value, 'blue')
1647 self.assertEqual(Color.green.value, 'green')
1648
1649 def test_auto_name_inherit(self):
1650 class AutoNameEnum(Enum):
1651 def _generate_next_value_(name, start, count, last):
1652 return name
1653 class Color(AutoNameEnum):
1654 red = auto()
1655 blue = auto()
1656 green = auto()
1657
1658 self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
1659 self.assertEqual(Color.red.value, 'red')
1660 self.assertEqual(Color.blue.value, 'blue')
1661 self.assertEqual(Color.green.value, 'green')
1662
1663 def test_auto_garbage(self):
1664 class Color(Enum):
1665 red = 'red'
1666 blue = auto()
1667 self.assertEqual(Color.blue.value, 1)
1668
1669 def test_auto_garbage_corrected(self):
1670 class Color(Enum):
1671 red = 'red'
1672 blue = 2
1673 green = auto()
1674
1675 self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
1676 self.assertEqual(Color.red.value, 'red')
1677 self.assertEqual(Color.blue.value, 2)
1678 self.assertEqual(Color.green.value, 3)
1679
Ethan Furman3515dcc2016-09-18 13:15:41 -07001680 def test_duplicate_auto(self):
1681 class Dupes(Enum):
1682 first = primero = auto()
1683 second = auto()
1684 third = auto()
1685 self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes))
1686
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001687
Ethan Furmane8e61272016-08-20 07:19:31 -07001688class TestOrder(unittest.TestCase):
1689
1690 def test_same_members(self):
1691 class Color(Enum):
1692 _order_ = 'red green blue'
1693 red = 1
1694 green = 2
1695 blue = 3
1696
1697 def test_same_members_with_aliases(self):
1698 class Color(Enum):
1699 _order_ = 'red green blue'
1700 red = 1
1701 green = 2
1702 blue = 3
1703 verde = green
1704
1705 def test_same_members_wrong_order(self):
1706 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
1707 class Color(Enum):
1708 _order_ = 'red green blue'
1709 red = 1
1710 blue = 3
1711 green = 2
1712
1713 def test_order_has_extra_members(self):
1714 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
1715 class Color(Enum):
1716 _order_ = 'red green blue purple'
1717 red = 1
1718 green = 2
1719 blue = 3
1720
1721 def test_order_has_extra_members_with_aliases(self):
1722 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
1723 class Color(Enum):
1724 _order_ = 'red green blue purple'
1725 red = 1
1726 green = 2
1727 blue = 3
1728 verde = green
1729
1730 def test_enum_has_extra_members(self):
1731 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
1732 class Color(Enum):
1733 _order_ = 'red green blue'
1734 red = 1
1735 green = 2
1736 blue = 3
1737 purple = 4
1738
1739 def test_enum_has_extra_members_with_aliases(self):
1740 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
1741 class Color(Enum):
1742 _order_ = 'red green blue'
1743 red = 1
1744 green = 2
1745 blue = 3
1746 purple = 4
1747 verde = green
1748
1749
Ethan Furman65a5a472016-09-01 23:55:19 -07001750class TestFlag(unittest.TestCase):
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001751 """Tests of the Flags."""
1752
Ethan Furman65a5a472016-09-01 23:55:19 -07001753 class Perm(Flag):
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001754 R, W, X = 4, 2, 1
1755
Ethan Furman37151762018-04-11 18:56:25 -07001756 class Color(Flag):
1757 BLACK = 0
1758 RED = 1
1759 GREEN = 2
1760 BLUE = 4
1761 PURPLE = RED|BLUE
1762
Ethan Furman65a5a472016-09-01 23:55:19 -07001763 class Open(Flag):
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001764 RO = 0
1765 WO = 1
1766 RW = 2
1767 AC = 3
1768 CE = 1<<19
1769
1770 def test_str(self):
1771 Perm = self.Perm
1772 self.assertEqual(str(Perm.R), 'Perm.R')
1773 self.assertEqual(str(Perm.W), 'Perm.W')
1774 self.assertEqual(str(Perm.X), 'Perm.X')
1775 self.assertEqual(str(Perm.R | Perm.W), 'Perm.R|W')
1776 self.assertEqual(str(Perm.R | Perm.W | Perm.X), 'Perm.R|W|X')
1777 self.assertEqual(str(Perm(0)), 'Perm.0')
1778 self.assertEqual(str(~Perm.R), 'Perm.W|X')
1779 self.assertEqual(str(~Perm.W), 'Perm.R|X')
1780 self.assertEqual(str(~Perm.X), 'Perm.R|W')
1781 self.assertEqual(str(~(Perm.R | Perm.W)), 'Perm.X')
1782 self.assertEqual(str(~(Perm.R | Perm.W | Perm.X)), 'Perm.0')
1783 self.assertEqual(str(Perm(~0)), 'Perm.R|W|X')
1784
1785 Open = self.Open
1786 self.assertEqual(str(Open.RO), 'Open.RO')
1787 self.assertEqual(str(Open.WO), 'Open.WO')
1788 self.assertEqual(str(Open.AC), 'Open.AC')
1789 self.assertEqual(str(Open.RO | Open.CE), 'Open.CE')
1790 self.assertEqual(str(Open.WO | Open.CE), 'Open.CE|WO')
Ethan Furman3515dcc2016-09-18 13:15:41 -07001791 self.assertEqual(str(~Open.RO), 'Open.CE|AC|RW|WO')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001792 self.assertEqual(str(~Open.WO), 'Open.CE|RW')
1793 self.assertEqual(str(~Open.AC), 'Open.CE')
1794 self.assertEqual(str(~(Open.RO | Open.CE)), 'Open.AC')
1795 self.assertEqual(str(~(Open.WO | Open.CE)), 'Open.RW')
1796
1797 def test_repr(self):
1798 Perm = self.Perm
1799 self.assertEqual(repr(Perm.R), '<Perm.R: 4>')
1800 self.assertEqual(repr(Perm.W), '<Perm.W: 2>')
1801 self.assertEqual(repr(Perm.X), '<Perm.X: 1>')
1802 self.assertEqual(repr(Perm.R | Perm.W), '<Perm.R|W: 6>')
1803 self.assertEqual(repr(Perm.R | Perm.W | Perm.X), '<Perm.R|W|X: 7>')
Ethan Furman27682d22016-09-04 11:39:01 -07001804 self.assertEqual(repr(Perm(0)), '<Perm.0: 0>')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001805 self.assertEqual(repr(~Perm.R), '<Perm.W|X: 3>')
1806 self.assertEqual(repr(~Perm.W), '<Perm.R|X: 5>')
1807 self.assertEqual(repr(~Perm.X), '<Perm.R|W: 6>')
1808 self.assertEqual(repr(~(Perm.R | Perm.W)), '<Perm.X: 1>')
Ethan Furman27682d22016-09-04 11:39:01 -07001809 self.assertEqual(repr(~(Perm.R | Perm.W | Perm.X)), '<Perm.0: 0>')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001810 self.assertEqual(repr(Perm(~0)), '<Perm.R|W|X: 7>')
1811
1812 Open = self.Open
1813 self.assertEqual(repr(Open.RO), '<Open.RO: 0>')
1814 self.assertEqual(repr(Open.WO), '<Open.WO: 1>')
1815 self.assertEqual(repr(Open.AC), '<Open.AC: 3>')
1816 self.assertEqual(repr(Open.RO | Open.CE), '<Open.CE: 524288>')
1817 self.assertEqual(repr(Open.WO | Open.CE), '<Open.CE|WO: 524289>')
Ethan Furman3515dcc2016-09-18 13:15:41 -07001818 self.assertEqual(repr(~Open.RO), '<Open.CE|AC|RW|WO: 524291>')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001819 self.assertEqual(repr(~Open.WO), '<Open.CE|RW: 524290>')
1820 self.assertEqual(repr(~Open.AC), '<Open.CE: 524288>')
1821 self.assertEqual(repr(~(Open.RO | Open.CE)), '<Open.AC: 3>')
1822 self.assertEqual(repr(~(Open.WO | Open.CE)), '<Open.RW: 2>')
1823
1824 def test_or(self):
1825 Perm = self.Perm
1826 for i in Perm:
1827 for j in Perm:
1828 self.assertEqual((i | j), Perm(i.value | j.value))
1829 self.assertEqual((i | j).value, i.value | j.value)
1830 self.assertIs(type(i | j), Perm)
1831 for i in Perm:
1832 self.assertIs(i | i, i)
1833 Open = self.Open
1834 self.assertIs(Open.RO | Open.CE, Open.CE)
1835
1836 def test_and(self):
1837 Perm = self.Perm
1838 RW = Perm.R | Perm.W
1839 RX = Perm.R | Perm.X
1840 WX = Perm.W | Perm.X
1841 RWX = Perm.R | Perm.W | Perm.X
1842 values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
1843 for i in values:
1844 for j in values:
1845 self.assertEqual((i & j).value, i.value & j.value)
1846 self.assertIs(type(i & j), Perm)
1847 for i in Perm:
1848 self.assertIs(i & i, i)
1849 self.assertIs(i & RWX, i)
1850 self.assertIs(RWX & i, i)
1851 Open = self.Open
1852 self.assertIs(Open.RO & Open.CE, Open.RO)
1853
1854 def test_xor(self):
1855 Perm = self.Perm
1856 for i in Perm:
1857 for j in Perm:
1858 self.assertEqual((i ^ j).value, i.value ^ j.value)
1859 self.assertIs(type(i ^ j), Perm)
1860 for i in Perm:
1861 self.assertIs(i ^ Perm(0), i)
1862 self.assertIs(Perm(0) ^ i, i)
1863 Open = self.Open
1864 self.assertIs(Open.RO ^ Open.CE, Open.CE)
1865 self.assertIs(Open.CE ^ Open.CE, Open.RO)
1866
1867 def test_invert(self):
1868 Perm = self.Perm
1869 RW = Perm.R | Perm.W
1870 RX = Perm.R | Perm.X
1871 WX = Perm.W | Perm.X
1872 RWX = Perm.R | Perm.W | Perm.X
1873 values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
1874 for i in values:
1875 self.assertIs(type(~i), Perm)
1876 self.assertEqual(~~i, i)
1877 for i in Perm:
1878 self.assertIs(~~i, i)
1879 Open = self.Open
1880 self.assertIs(Open.WO & ~Open.WO, Open.RO)
1881 self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE)
1882
Ethan Furman25d94bb2016-09-02 16:32:32 -07001883 def test_bool(self):
1884 Perm = self.Perm
1885 for f in Perm:
1886 self.assertTrue(f)
1887 Open = self.Open
1888 for f in Open:
1889 self.assertEqual(bool(f.value), bool(f))
1890
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001891 def test_programatic_function_string(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07001892 Perm = Flag('Perm', 'R W X')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001893 lst = list(Perm)
1894 self.assertEqual(len(lst), len(Perm))
1895 self.assertEqual(len(Perm), 3, Perm)
1896 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
1897 for i, n in enumerate('R W X'.split()):
1898 v = 1<<i
1899 e = Perm(v)
1900 self.assertEqual(e.value, v)
1901 self.assertEqual(type(e.value), int)
1902 self.assertEqual(e.name, n)
1903 self.assertIn(e, Perm)
1904 self.assertIs(type(e), Perm)
1905
1906 def test_programatic_function_string_with_start(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07001907 Perm = Flag('Perm', 'R W X', start=8)
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001908 lst = list(Perm)
1909 self.assertEqual(len(lst), len(Perm))
1910 self.assertEqual(len(Perm), 3, Perm)
1911 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
1912 for i, n in enumerate('R W X'.split()):
1913 v = 8<<i
1914 e = Perm(v)
1915 self.assertEqual(e.value, v)
1916 self.assertEqual(type(e.value), int)
1917 self.assertEqual(e.name, n)
1918 self.assertIn(e, Perm)
1919 self.assertIs(type(e), Perm)
1920
1921 def test_programatic_function_string_list(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07001922 Perm = Flag('Perm', ['R', 'W', 'X'])
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001923 lst = list(Perm)
1924 self.assertEqual(len(lst), len(Perm))
1925 self.assertEqual(len(Perm), 3, Perm)
1926 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
1927 for i, n in enumerate('R W X'.split()):
1928 v = 1<<i
1929 e = Perm(v)
1930 self.assertEqual(e.value, v)
1931 self.assertEqual(type(e.value), int)
1932 self.assertEqual(e.name, n)
1933 self.assertIn(e, Perm)
1934 self.assertIs(type(e), Perm)
1935
1936 def test_programatic_function_iterable(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07001937 Perm = Flag('Perm', (('R', 2), ('W', 8), ('X', 32)))
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001938 lst = list(Perm)
1939 self.assertEqual(len(lst), len(Perm))
1940 self.assertEqual(len(Perm), 3, Perm)
1941 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
1942 for i, n in enumerate('R W X'.split()):
1943 v = 1<<(2*i+1)
1944 e = Perm(v)
1945 self.assertEqual(e.value, v)
1946 self.assertEqual(type(e.value), int)
1947 self.assertEqual(e.name, n)
1948 self.assertIn(e, Perm)
1949 self.assertIs(type(e), Perm)
1950
1951 def test_programatic_function_from_dict(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07001952 Perm = Flag('Perm', OrderedDict((('R', 2), ('W', 8), ('X', 32))))
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001953 lst = list(Perm)
1954 self.assertEqual(len(lst), len(Perm))
1955 self.assertEqual(len(Perm), 3, Perm)
1956 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
1957 for i, n in enumerate('R W X'.split()):
1958 v = 1<<(2*i+1)
1959 e = Perm(v)
1960 self.assertEqual(e.value, v)
1961 self.assertEqual(type(e.value), int)
1962 self.assertEqual(e.name, n)
1963 self.assertIn(e, Perm)
1964 self.assertIs(type(e), Perm)
1965
Ethan Furman65a5a472016-09-01 23:55:19 -07001966 def test_pickle(self):
1967 if isinstance(FlagStooges, Exception):
1968 raise FlagStooges
1969 test_pickle_dump_load(self.assertIs, FlagStooges.CURLY|FlagStooges.MOE)
1970 test_pickle_dump_load(self.assertIs, FlagStooges)
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001971
Ethan Furman37151762018-04-11 18:56:25 -07001972 def test_contains(self):
1973 Open = self.Open
1974 Color = self.Color
1975 self.assertFalse(Color.BLACK in Open)
1976 self.assertFalse(Open.RO in Color)
1977 with self.assertWarns(DeprecationWarning):
1978 self.assertFalse('BLACK' in Color)
1979 with self.assertWarns(DeprecationWarning):
1980 self.assertFalse('RO' in Open)
1981 with self.assertWarns(DeprecationWarning):
1982 self.assertFalse(1 in Color)
1983 with self.assertWarns(DeprecationWarning):
1984 self.assertFalse(1 in Open)
1985
1986 def test_member_contains(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07001987 Perm = self.Perm
1988 R, W, X = Perm
1989 RW = R | W
1990 RX = R | X
1991 WX = W | X
1992 RWX = R | W | X
1993 self.assertTrue(R in RW)
1994 self.assertTrue(R in RX)
1995 self.assertTrue(R in RWX)
1996 self.assertTrue(W in RW)
1997 self.assertTrue(W in WX)
1998 self.assertTrue(W in RWX)
1999 self.assertTrue(X in RX)
2000 self.assertTrue(X in WX)
2001 self.assertTrue(X in RWX)
2002 self.assertFalse(R in WX)
2003 self.assertFalse(W in RX)
2004 self.assertFalse(X in RW)
2005
Ethan Furmanc16595e2016-09-10 23:36:59 -07002006 def test_auto_number(self):
2007 class Color(Flag):
2008 red = auto()
2009 blue = auto()
2010 green = auto()
2011
2012 self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
2013 self.assertEqual(Color.red.value, 1)
2014 self.assertEqual(Color.blue.value, 2)
2015 self.assertEqual(Color.green.value, 4)
2016
2017 def test_auto_number_garbage(self):
2018 with self.assertRaisesRegex(TypeError, 'Invalid Flag value: .not an int.'):
2019 class Color(Flag):
2020 red = 'not an int'
2021 blue = auto()
2022
Ethan Furman3515dcc2016-09-18 13:15:41 -07002023 def test_cascading_failure(self):
2024 class Bizarre(Flag):
2025 c = 3
2026 d = 4
2027 f = 6
2028 # Bizarre.c | Bizarre.d
2029 self.assertRaisesRegex(ValueError, "5 is not a valid Bizarre", Bizarre, 5)
2030 self.assertRaisesRegex(ValueError, "5 is not a valid Bizarre", Bizarre, 5)
2031 self.assertRaisesRegex(ValueError, "2 is not a valid Bizarre", Bizarre, 2)
2032 self.assertRaisesRegex(ValueError, "2 is not a valid Bizarre", Bizarre, 2)
2033 self.assertRaisesRegex(ValueError, "1 is not a valid Bizarre", Bizarre, 1)
2034 self.assertRaisesRegex(ValueError, "1 is not a valid Bizarre", Bizarre, 1)
2035
2036 def test_duplicate_auto(self):
2037 class Dupes(Enum):
2038 first = primero = auto()
2039 second = auto()
2040 third = auto()
2041 self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes))
2042
2043 def test_bizarre(self):
2044 class Bizarre(Flag):
2045 b = 3
2046 c = 4
2047 d = 6
2048 self.assertEqual(repr(Bizarre(7)), '<Bizarre.d|c|b: 7>')
2049
Ethan Furman28cf6632017-01-24 12:12:06 -08002050 @support.reap_threads
2051 def test_unique_composite(self):
2052 # override __eq__ to be identity only
2053 class TestFlag(Flag):
2054 one = auto()
2055 two = auto()
2056 three = auto()
2057 four = auto()
2058 five = auto()
2059 six = auto()
2060 seven = auto()
2061 eight = auto()
2062 def __eq__(self, other):
2063 return self is other
2064 def __hash__(self):
2065 return hash(self._value_)
2066 # have multiple threads competing to complete the composite members
2067 seen = set()
2068 failed = False
2069 def cycle_enum():
2070 nonlocal failed
2071 try:
2072 for i in range(256):
2073 seen.add(TestFlag(i))
2074 except Exception:
2075 failed = True
2076 threads = [
2077 threading.Thread(target=cycle_enum)
2078 for _ in range(8)
2079 ]
2080 with support.start_threads(threads):
2081 pass
2082 # check that only 248 members were created
2083 self.assertFalse(
2084 failed,
2085 'at least one thread failed while creating composite members')
2086 self.assertEqual(256, len(seen), 'too many composite members created')
2087
Ethan Furmanc16595e2016-09-10 23:36:59 -07002088
Ethan Furman65a5a472016-09-01 23:55:19 -07002089class TestIntFlag(unittest.TestCase):
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002090 """Tests of the IntFlags."""
2091
Ethan Furman65a5a472016-09-01 23:55:19 -07002092 class Perm(IntFlag):
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002093 X = 1 << 0
2094 W = 1 << 1
2095 R = 1 << 2
2096
Ethan Furman37151762018-04-11 18:56:25 -07002097 class Color(IntFlag):
2098 BLACK = 0
2099 RED = 1
2100 GREEN = 2
2101 BLUE = 4
2102 PURPLE = RED|BLUE
2103
Ethan Furman65a5a472016-09-01 23:55:19 -07002104 class Open(IntFlag):
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002105 RO = 0
2106 WO = 1
2107 RW = 2
2108 AC = 3
2109 CE = 1<<19
2110
Ethan Furman3515dcc2016-09-18 13:15:41 -07002111 def test_type(self):
2112 Perm = self.Perm
2113 Open = self.Open
2114 for f in Perm:
2115 self.assertTrue(isinstance(f, Perm))
2116 self.assertEqual(f, f.value)
2117 self.assertTrue(isinstance(Perm.W | Perm.X, Perm))
2118 self.assertEqual(Perm.W | Perm.X, 3)
2119 for f in Open:
2120 self.assertTrue(isinstance(f, Open))
2121 self.assertEqual(f, f.value)
2122 self.assertTrue(isinstance(Open.WO | Open.RW, Open))
2123 self.assertEqual(Open.WO | Open.RW, 3)
2124
2125
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002126 def test_str(self):
2127 Perm = self.Perm
2128 self.assertEqual(str(Perm.R), 'Perm.R')
2129 self.assertEqual(str(Perm.W), 'Perm.W')
2130 self.assertEqual(str(Perm.X), 'Perm.X')
2131 self.assertEqual(str(Perm.R | Perm.W), 'Perm.R|W')
2132 self.assertEqual(str(Perm.R | Perm.W | Perm.X), 'Perm.R|W|X')
2133 self.assertEqual(str(Perm.R | 8), 'Perm.8|R')
2134 self.assertEqual(str(Perm(0)), 'Perm.0')
2135 self.assertEqual(str(Perm(8)), 'Perm.8')
Ethan Furman3515dcc2016-09-18 13:15:41 -07002136 self.assertEqual(str(~Perm.R), 'Perm.W|X')
2137 self.assertEqual(str(~Perm.W), 'Perm.R|X')
2138 self.assertEqual(str(~Perm.X), 'Perm.R|W')
2139 self.assertEqual(str(~(Perm.R | Perm.W)), 'Perm.X')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002140 self.assertEqual(str(~(Perm.R | Perm.W | Perm.X)), 'Perm.-8')
Ethan Furman3515dcc2016-09-18 13:15:41 -07002141 self.assertEqual(str(~(Perm.R | 8)), 'Perm.W|X')
2142 self.assertEqual(str(Perm(~0)), 'Perm.R|W|X')
2143 self.assertEqual(str(Perm(~8)), 'Perm.R|W|X')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002144
2145 Open = self.Open
2146 self.assertEqual(str(Open.RO), 'Open.RO')
2147 self.assertEqual(str(Open.WO), 'Open.WO')
2148 self.assertEqual(str(Open.AC), 'Open.AC')
2149 self.assertEqual(str(Open.RO | Open.CE), 'Open.CE')
2150 self.assertEqual(str(Open.WO | Open.CE), 'Open.CE|WO')
2151 self.assertEqual(str(Open(4)), 'Open.4')
Ethan Furman3515dcc2016-09-18 13:15:41 -07002152 self.assertEqual(str(~Open.RO), 'Open.CE|AC|RW|WO')
2153 self.assertEqual(str(~Open.WO), 'Open.CE|RW')
2154 self.assertEqual(str(~Open.AC), 'Open.CE')
2155 self.assertEqual(str(~(Open.RO | Open.CE)), 'Open.AC|RW|WO')
2156 self.assertEqual(str(~(Open.WO | Open.CE)), 'Open.RW')
2157 self.assertEqual(str(Open(~4)), 'Open.CE|AC|RW|WO')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002158
2159 def test_repr(self):
2160 Perm = self.Perm
2161 self.assertEqual(repr(Perm.R), '<Perm.R: 4>')
2162 self.assertEqual(repr(Perm.W), '<Perm.W: 2>')
2163 self.assertEqual(repr(Perm.X), '<Perm.X: 1>')
2164 self.assertEqual(repr(Perm.R | Perm.W), '<Perm.R|W: 6>')
2165 self.assertEqual(repr(Perm.R | Perm.W | Perm.X), '<Perm.R|W|X: 7>')
2166 self.assertEqual(repr(Perm.R | 8), '<Perm.8|R: 12>')
Ethan Furman27682d22016-09-04 11:39:01 -07002167 self.assertEqual(repr(Perm(0)), '<Perm.0: 0>')
2168 self.assertEqual(repr(Perm(8)), '<Perm.8: 8>')
Ethan Furman3515dcc2016-09-18 13:15:41 -07002169 self.assertEqual(repr(~Perm.R), '<Perm.W|X: -5>')
2170 self.assertEqual(repr(~Perm.W), '<Perm.R|X: -3>')
2171 self.assertEqual(repr(~Perm.X), '<Perm.R|W: -2>')
2172 self.assertEqual(repr(~(Perm.R | Perm.W)), '<Perm.X: -7>')
Ethan Furman27682d22016-09-04 11:39:01 -07002173 self.assertEqual(repr(~(Perm.R | Perm.W | Perm.X)), '<Perm.-8: -8>')
Ethan Furman3515dcc2016-09-18 13:15:41 -07002174 self.assertEqual(repr(~(Perm.R | 8)), '<Perm.W|X: -13>')
2175 self.assertEqual(repr(Perm(~0)), '<Perm.R|W|X: -1>')
2176 self.assertEqual(repr(Perm(~8)), '<Perm.R|W|X: -9>')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002177
2178 Open = self.Open
2179 self.assertEqual(repr(Open.RO), '<Open.RO: 0>')
2180 self.assertEqual(repr(Open.WO), '<Open.WO: 1>')
2181 self.assertEqual(repr(Open.AC), '<Open.AC: 3>')
2182 self.assertEqual(repr(Open.RO | Open.CE), '<Open.CE: 524288>')
2183 self.assertEqual(repr(Open.WO | Open.CE), '<Open.CE|WO: 524289>')
Ethan Furman27682d22016-09-04 11:39:01 -07002184 self.assertEqual(repr(Open(4)), '<Open.4: 4>')
Ethan Furman3515dcc2016-09-18 13:15:41 -07002185 self.assertEqual(repr(~Open.RO), '<Open.CE|AC|RW|WO: -1>')
2186 self.assertEqual(repr(~Open.WO), '<Open.CE|RW: -2>')
2187 self.assertEqual(repr(~Open.AC), '<Open.CE: -4>')
2188 self.assertEqual(repr(~(Open.RO | Open.CE)), '<Open.AC|RW|WO: -524289>')
2189 self.assertEqual(repr(~(Open.WO | Open.CE)), '<Open.RW: -524290>')
2190 self.assertEqual(repr(Open(~4)), '<Open.CE|AC|RW|WO: -5>')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002191
2192 def test_or(self):
2193 Perm = self.Perm
2194 for i in Perm:
2195 for j in Perm:
2196 self.assertEqual(i | j, i.value | j.value)
2197 self.assertEqual((i | j).value, i.value | j.value)
2198 self.assertIs(type(i | j), Perm)
2199 for j in range(8):
2200 self.assertEqual(i | j, i.value | j)
2201 self.assertEqual((i | j).value, i.value | j)
2202 self.assertIs(type(i | j), Perm)
2203 self.assertEqual(j | i, j | i.value)
2204 self.assertEqual((j | i).value, j | i.value)
2205 self.assertIs(type(j | i), Perm)
2206 for i in Perm:
2207 self.assertIs(i | i, i)
2208 self.assertIs(i | 0, i)
2209 self.assertIs(0 | i, i)
2210 Open = self.Open
2211 self.assertIs(Open.RO | Open.CE, Open.CE)
2212
2213 def test_and(self):
2214 Perm = self.Perm
2215 RW = Perm.R | Perm.W
2216 RX = Perm.R | Perm.X
2217 WX = Perm.W | Perm.X
2218 RWX = Perm.R | Perm.W | Perm.X
2219 values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
2220 for i in values:
2221 for j in values:
2222 self.assertEqual(i & j, i.value & j.value, 'i is %r, j is %r' % (i, j))
2223 self.assertEqual((i & j).value, i.value & j.value, 'i is %r, j is %r' % (i, j))
2224 self.assertIs(type(i & j), Perm, 'i is %r, j is %r' % (i, j))
2225 for j in range(8):
2226 self.assertEqual(i & j, i.value & j)
2227 self.assertEqual((i & j).value, i.value & j)
2228 self.assertIs(type(i & j), Perm)
2229 self.assertEqual(j & i, j & i.value)
2230 self.assertEqual((j & i).value, j & i.value)
2231 self.assertIs(type(j & i), Perm)
2232 for i in Perm:
2233 self.assertIs(i & i, i)
2234 self.assertIs(i & 7, i)
2235 self.assertIs(7 & i, i)
2236 Open = self.Open
2237 self.assertIs(Open.RO & Open.CE, Open.RO)
2238
2239 def test_xor(self):
2240 Perm = self.Perm
2241 for i in Perm:
2242 for j in Perm:
2243 self.assertEqual(i ^ j, i.value ^ j.value)
2244 self.assertEqual((i ^ j).value, i.value ^ j.value)
2245 self.assertIs(type(i ^ j), Perm)
2246 for j in range(8):
2247 self.assertEqual(i ^ j, i.value ^ j)
2248 self.assertEqual((i ^ j).value, i.value ^ j)
2249 self.assertIs(type(i ^ j), Perm)
2250 self.assertEqual(j ^ i, j ^ i.value)
2251 self.assertEqual((j ^ i).value, j ^ i.value)
2252 self.assertIs(type(j ^ i), Perm)
2253 for i in Perm:
2254 self.assertIs(i ^ 0, i)
2255 self.assertIs(0 ^ i, i)
2256 Open = self.Open
2257 self.assertIs(Open.RO ^ Open.CE, Open.CE)
2258 self.assertIs(Open.CE ^ Open.CE, Open.RO)
2259
2260 def test_invert(self):
2261 Perm = self.Perm
2262 RW = Perm.R | Perm.W
2263 RX = Perm.R | Perm.X
2264 WX = Perm.W | Perm.X
2265 RWX = Perm.R | Perm.W | Perm.X
2266 values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
2267 for i in values:
2268 self.assertEqual(~i, ~i.value)
2269 self.assertEqual((~i).value, ~i.value)
2270 self.assertIs(type(~i), Perm)
2271 self.assertEqual(~~i, i)
2272 for i in Perm:
2273 self.assertIs(~~i, i)
2274 Open = self.Open
2275 self.assertIs(Open.WO & ~Open.WO, Open.RO)
2276 self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE)
2277
2278 def test_programatic_function_string(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07002279 Perm = IntFlag('Perm', 'R W X')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002280 lst = list(Perm)
2281 self.assertEqual(len(lst), len(Perm))
2282 self.assertEqual(len(Perm), 3, Perm)
2283 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2284 for i, n in enumerate('R W X'.split()):
2285 v = 1<<i
2286 e = Perm(v)
2287 self.assertEqual(e.value, v)
2288 self.assertEqual(type(e.value), int)
2289 self.assertEqual(e, v)
2290 self.assertEqual(e.name, n)
2291 self.assertIn(e, Perm)
2292 self.assertIs(type(e), Perm)
2293
2294 def test_programatic_function_string_with_start(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07002295 Perm = IntFlag('Perm', 'R W X', start=8)
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002296 lst = list(Perm)
2297 self.assertEqual(len(lst), len(Perm))
2298 self.assertEqual(len(Perm), 3, Perm)
2299 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2300 for i, n in enumerate('R W X'.split()):
2301 v = 8<<i
2302 e = Perm(v)
2303 self.assertEqual(e.value, v)
2304 self.assertEqual(type(e.value), int)
2305 self.assertEqual(e, v)
2306 self.assertEqual(e.name, n)
2307 self.assertIn(e, Perm)
2308 self.assertIs(type(e), Perm)
2309
2310 def test_programatic_function_string_list(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07002311 Perm = IntFlag('Perm', ['R', 'W', 'X'])
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002312 lst = list(Perm)
2313 self.assertEqual(len(lst), len(Perm))
2314 self.assertEqual(len(Perm), 3, Perm)
2315 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2316 for i, n in enumerate('R W X'.split()):
2317 v = 1<<i
2318 e = Perm(v)
2319 self.assertEqual(e.value, v)
2320 self.assertEqual(type(e.value), int)
2321 self.assertEqual(e, v)
2322 self.assertEqual(e.name, n)
2323 self.assertIn(e, Perm)
2324 self.assertIs(type(e), Perm)
2325
2326 def test_programatic_function_iterable(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07002327 Perm = IntFlag('Perm', (('R', 2), ('W', 8), ('X', 32)))
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002328 lst = list(Perm)
2329 self.assertEqual(len(lst), len(Perm))
2330 self.assertEqual(len(Perm), 3, Perm)
2331 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2332 for i, n in enumerate('R W X'.split()):
2333 v = 1<<(2*i+1)
2334 e = Perm(v)
2335 self.assertEqual(e.value, v)
2336 self.assertEqual(type(e.value), int)
2337 self.assertEqual(e, v)
2338 self.assertEqual(e.name, n)
2339 self.assertIn(e, Perm)
2340 self.assertIs(type(e), Perm)
2341
2342 def test_programatic_function_from_dict(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07002343 Perm = IntFlag('Perm', OrderedDict((('R', 2), ('W', 8), ('X', 32))))
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002344 lst = list(Perm)
2345 self.assertEqual(len(lst), len(Perm))
2346 self.assertEqual(len(Perm), 3, Perm)
2347 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2348 for i, n in enumerate('R W X'.split()):
2349 v = 1<<(2*i+1)
2350 e = Perm(v)
2351 self.assertEqual(e.value, v)
2352 self.assertEqual(type(e.value), int)
2353 self.assertEqual(e, v)
2354 self.assertEqual(e.name, n)
2355 self.assertIn(e, Perm)
2356 self.assertIs(type(e), Perm)
2357
2358
Dong-hee Nadcc8ce42017-06-22 01:52:32 +09002359 def test_programatic_function_from_empty_list(self):
2360 Perm = enum.IntFlag('Perm', [])
2361 lst = list(Perm)
2362 self.assertEqual(len(lst), len(Perm))
2363 self.assertEqual(len(Perm), 0, Perm)
2364 Thing = enum.Enum('Thing', [])
2365 lst = list(Thing)
2366 self.assertEqual(len(lst), len(Thing))
2367 self.assertEqual(len(Thing), 0, Thing)
2368
2369
2370 def test_programatic_function_from_empty_tuple(self):
2371 Perm = enum.IntFlag('Perm', ())
2372 lst = list(Perm)
2373 self.assertEqual(len(lst), len(Perm))
2374 self.assertEqual(len(Perm), 0, Perm)
2375 Thing = enum.Enum('Thing', ())
2376 self.assertEqual(len(lst), len(Thing))
2377 self.assertEqual(len(Thing), 0, Thing)
2378
Ethan Furman37151762018-04-11 18:56:25 -07002379 def test_contains(self):
2380 Color = self.Color
2381 Open = self.Open
2382 self.assertTrue(Color.GREEN in Color)
2383 self.assertTrue(Open.RW in Open)
2384 self.assertFalse(Color.GREEN in Open)
2385 self.assertFalse(Open.RW in Color)
2386 with self.assertWarns(DeprecationWarning):
2387 self.assertFalse('GREEN' in Color)
2388 with self.assertWarns(DeprecationWarning):
2389 self.assertFalse('RW' in Open)
2390 with self.assertWarns(DeprecationWarning):
2391 self.assertFalse(2 in Color)
2392 with self.assertWarns(DeprecationWarning):
2393 self.assertFalse(2 in Open)
2394
2395 def test_member_contains(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07002396 Perm = self.Perm
2397 R, W, X = Perm
2398 RW = R | W
2399 RX = R | X
2400 WX = W | X
2401 RWX = R | W | X
2402 self.assertTrue(R in RW)
2403 self.assertTrue(R in RX)
2404 self.assertTrue(R in RWX)
2405 self.assertTrue(W in RW)
2406 self.assertTrue(W in WX)
2407 self.assertTrue(W in RWX)
2408 self.assertTrue(X in RX)
2409 self.assertTrue(X in WX)
2410 self.assertTrue(X in RWX)
2411 self.assertFalse(R in WX)
2412 self.assertFalse(W in RX)
2413 self.assertFalse(X in RW)
Ethan Furman37151762018-04-11 18:56:25 -07002414 with self.assertWarns(DeprecationWarning):
2415 self.assertFalse('swallow' in RW)
Ethan Furman65a5a472016-09-01 23:55:19 -07002416
Ethan Furman25d94bb2016-09-02 16:32:32 -07002417 def test_bool(self):
2418 Perm = self.Perm
2419 for f in Perm:
2420 self.assertTrue(f)
2421 Open = self.Open
2422 for f in Open:
2423 self.assertEqual(bool(f.value), bool(f))
2424
Ethan Furman28cf6632017-01-24 12:12:06 -08002425 @support.reap_threads
2426 def test_unique_composite(self):
2427 # override __eq__ to be identity only
2428 class TestFlag(IntFlag):
2429 one = auto()
2430 two = auto()
2431 three = auto()
2432 four = auto()
2433 five = auto()
2434 six = auto()
2435 seven = auto()
2436 eight = auto()
2437 def __eq__(self, other):
2438 return self is other
2439 def __hash__(self):
2440 return hash(self._value_)
2441 # have multiple threads competing to complete the composite members
2442 seen = set()
2443 failed = False
2444 def cycle_enum():
2445 nonlocal failed
2446 try:
2447 for i in range(256):
2448 seen.add(TestFlag(i))
2449 except Exception:
2450 failed = True
2451 threads = [
2452 threading.Thread(target=cycle_enum)
2453 for _ in range(8)
2454 ]
2455 with support.start_threads(threads):
2456 pass
2457 # check that only 248 members were created
2458 self.assertFalse(
2459 failed,
2460 'at least one thread failed while creating composite members')
2461 self.assertEqual(256, len(seen), 'too many composite members created')
2462
2463
Ethan Furmanf24bb352013-07-18 17:05:39 -07002464class TestUnique(unittest.TestCase):
2465
2466 def test_unique_clean(self):
2467 @unique
2468 class Clean(Enum):
2469 one = 1
2470 two = 'dos'
2471 tres = 4.0
2472 @unique
2473 class Cleaner(IntEnum):
2474 single = 1
2475 double = 2
2476 triple = 3
2477
2478 def test_unique_dirty(self):
2479 with self.assertRaisesRegex(ValueError, 'tres.*one'):
2480 @unique
2481 class Dirty(Enum):
2482 one = 1
2483 two = 'dos'
2484 tres = 1
2485 with self.assertRaisesRegex(
2486 ValueError,
2487 'double.*single.*turkey.*triple',
2488 ):
2489 @unique
2490 class Dirtier(IntEnum):
2491 single = 1
2492 double = 1
2493 triple = 3
2494 turkey = 3
2495
Ethan Furman3803ad42016-05-01 10:03:53 -07002496 def test_unique_with_name(self):
2497 @unique
2498 class Silly(Enum):
2499 one = 1
2500 two = 'dos'
2501 name = 3
2502 @unique
2503 class Sillier(IntEnum):
2504 single = 1
2505 name = 2
2506 triple = 3
2507 value = 4
2508
Ethan Furmanf24bb352013-07-18 17:05:39 -07002509
Ethan Furman3323da92015-04-11 09:39:59 -07002510expected_help_output_with_docs = """\
Ethan Furman5875d742013-10-21 20:45:55 -07002511Help on class Color in module %s:
2512
2513class Color(enum.Enum)
Serhiy Storchaka90f63322017-01-24 09:06:22 +02002514 | Color(value, names=None, *, module=None, qualname=None, type=None, start=1)
2515 |\x20\x20
Ethan Furman48a724f2015-04-11 23:23:06 -07002516 | An enumeration.
Serhiy Storchakab599ca82015-04-04 12:48:04 +03002517 |\x20\x20
Ethan Furman5875d742013-10-21 20:45:55 -07002518 | Method resolution order:
2519 | Color
2520 | enum.Enum
2521 | builtins.object
2522 |\x20\x20
2523 | Data and other attributes defined here:
2524 |\x20\x20
2525 | blue = <Color.blue: 3>
2526 |\x20\x20
2527 | green = <Color.green: 2>
2528 |\x20\x20
2529 | red = <Color.red: 1>
2530 |\x20\x20
2531 | ----------------------------------------------------------------------
2532 | Data descriptors inherited from enum.Enum:
2533 |\x20\x20
2534 | name
2535 | The name of the Enum member.
2536 |\x20\x20
2537 | value
2538 | The value of the Enum member.
2539 |\x20\x20
2540 | ----------------------------------------------------------------------
2541 | Data descriptors inherited from enum.EnumMeta:
2542 |\x20\x20
2543 | __members__
2544 | Returns a mapping of member name->value.
2545 |\x20\x20\x20\x20\x20\x20
2546 | This mapping lists all enum members, including aliases. Note that this
Ethan Furman3323da92015-04-11 09:39:59 -07002547 | is a read-only view of the internal mapping."""
2548
2549expected_help_output_without_docs = """\
2550Help on class Color in module %s:
2551
2552class Color(enum.Enum)
Serhiy Storchaka90f63322017-01-24 09:06:22 +02002553 | Color(value, names=None, *, module=None, qualname=None, type=None, start=1)
2554 |\x20\x20
Ethan Furman3323da92015-04-11 09:39:59 -07002555 | Method resolution order:
2556 | Color
2557 | enum.Enum
2558 | builtins.object
2559 |\x20\x20
2560 | Data and other attributes defined here:
2561 |\x20\x20
2562 | blue = <Color.blue: 3>
2563 |\x20\x20
2564 | green = <Color.green: 2>
2565 |\x20\x20
2566 | red = <Color.red: 1>
2567 |\x20\x20
2568 | ----------------------------------------------------------------------
2569 | Data descriptors inherited from enum.Enum:
2570 |\x20\x20
2571 | name
2572 |\x20\x20
2573 | value
2574 |\x20\x20
2575 | ----------------------------------------------------------------------
2576 | Data descriptors inherited from enum.EnumMeta:
2577 |\x20\x20
2578 | __members__"""
Ethan Furman5875d742013-10-21 20:45:55 -07002579
2580class TestStdLib(unittest.TestCase):
2581
Ethan Furman48a724f2015-04-11 23:23:06 -07002582 maxDiff = None
2583
Ethan Furman5875d742013-10-21 20:45:55 -07002584 class Color(Enum):
2585 red = 1
2586 green = 2
2587 blue = 3
2588
2589 def test_pydoc(self):
2590 # indirectly test __objclass__
Ethan Furman3323da92015-04-11 09:39:59 -07002591 if StrEnum.__doc__ is None:
2592 expected_text = expected_help_output_without_docs % __name__
2593 else:
2594 expected_text = expected_help_output_with_docs % __name__
Ethan Furman5875d742013-10-21 20:45:55 -07002595 output = StringIO()
2596 helper = pydoc.Helper(output=output)
2597 helper(self.Color)
2598 result = output.getvalue().strip()
Victor Stinner4b0432d2014-06-16 22:48:43 +02002599 self.assertEqual(result, expected_text)
Ethan Furman5875d742013-10-21 20:45:55 -07002600
2601 def test_inspect_getmembers(self):
2602 values = dict((
2603 ('__class__', EnumMeta),
Ethan Furman48a724f2015-04-11 23:23:06 -07002604 ('__doc__', 'An enumeration.'),
Ethan Furman5875d742013-10-21 20:45:55 -07002605 ('__members__', self.Color.__members__),
2606 ('__module__', __name__),
2607 ('blue', self.Color.blue),
2608 ('green', self.Color.green),
2609 ('name', Enum.__dict__['name']),
2610 ('red', self.Color.red),
2611 ('value', Enum.__dict__['value']),
2612 ))
2613 result = dict(inspect.getmembers(self.Color))
2614 self.assertEqual(values.keys(), result.keys())
2615 failed = False
2616 for k in values.keys():
2617 if result[k] != values[k]:
2618 print()
2619 print('\n%s\n key: %s\n result: %s\nexpected: %s\n%s\n' %
2620 ('=' * 75, k, result[k], values[k], '=' * 75), sep='')
2621 failed = True
2622 if failed:
2623 self.fail("result does not equal expected, see print above")
2624
2625 def test_inspect_classify_class_attrs(self):
2626 # indirectly test __objclass__
2627 from inspect import Attribute
2628 values = [
2629 Attribute(name='__class__', kind='data',
2630 defining_class=object, object=EnumMeta),
2631 Attribute(name='__doc__', kind='data',
Ethan Furman48a724f2015-04-11 23:23:06 -07002632 defining_class=self.Color, object='An enumeration.'),
Ethan Furman5875d742013-10-21 20:45:55 -07002633 Attribute(name='__members__', kind='property',
2634 defining_class=EnumMeta, object=EnumMeta.__members__),
2635 Attribute(name='__module__', kind='data',
2636 defining_class=self.Color, object=__name__),
2637 Attribute(name='blue', kind='data',
2638 defining_class=self.Color, object=self.Color.blue),
2639 Attribute(name='green', kind='data',
2640 defining_class=self.Color, object=self.Color.green),
2641 Attribute(name='red', kind='data',
2642 defining_class=self.Color, object=self.Color.red),
2643 Attribute(name='name', kind='data',
2644 defining_class=Enum, object=Enum.__dict__['name']),
2645 Attribute(name='value', kind='data',
2646 defining_class=Enum, object=Enum.__dict__['value']),
2647 ]
2648 values.sort(key=lambda item: item.name)
2649 result = list(inspect.classify_class_attrs(self.Color))
2650 result.sort(key=lambda item: item.name)
2651 failed = False
2652 for v, r in zip(values, result):
2653 if r != v:
2654 print('\n%s\n%s\n%s\n%s\n' % ('=' * 75, r, v, '=' * 75), sep='')
2655 failed = True
2656 if failed:
2657 self.fail("result does not equal expected, see print above")
2658
Martin Panter19e69c52015-11-14 12:46:42 +00002659
2660class MiscTestCase(unittest.TestCase):
2661 def test__all__(self):
2662 support.check__all__(self, enum)
2663
2664
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)6f20bd62016-06-03 19:14:52 +00002665# These are unordered here on purpose to ensure that declaration order
2666# makes no difference.
2667CONVERT_TEST_NAME_D = 5
2668CONVERT_TEST_NAME_C = 5
2669CONVERT_TEST_NAME_B = 5
2670CONVERT_TEST_NAME_A = 5 # This one should sort first.
2671CONVERT_TEST_NAME_E = 5
2672CONVERT_TEST_NAME_F = 5
2673
2674class TestIntEnumConvert(unittest.TestCase):
2675 def test_convert_value_lookup_priority(self):
2676 test_type = enum.IntEnum._convert(
Ethan Furman28cf6632017-01-24 12:12:06 -08002677 'UnittestConvert',
2678 ('test.test_enum', '__main__')[__name__=='__main__'],
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)6f20bd62016-06-03 19:14:52 +00002679 filter=lambda x: x.startswith('CONVERT_TEST_'))
2680 # We don't want the reverse lookup value to vary when there are
2681 # multiple possible names for a given value. It should always
2682 # report the first lexigraphical name in that case.
2683 self.assertEqual(test_type(5).name, 'CONVERT_TEST_NAME_A')
2684
2685 def test_convert(self):
2686 test_type = enum.IntEnum._convert(
Ethan Furman28cf6632017-01-24 12:12:06 -08002687 'UnittestConvert',
2688 ('test.test_enum', '__main__')[__name__=='__main__'],
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)6f20bd62016-06-03 19:14:52 +00002689 filter=lambda x: x.startswith('CONVERT_TEST_'))
2690 # Ensure that test_type has all of the desired names and values.
2691 self.assertEqual(test_type.CONVERT_TEST_NAME_F,
2692 test_type.CONVERT_TEST_NAME_A)
2693 self.assertEqual(test_type.CONVERT_TEST_NAME_B, 5)
2694 self.assertEqual(test_type.CONVERT_TEST_NAME_C, 5)
2695 self.assertEqual(test_type.CONVERT_TEST_NAME_D, 5)
2696 self.assertEqual(test_type.CONVERT_TEST_NAME_E, 5)
2697 # Ensure that test_type only picked up names matching the filter.
2698 self.assertEqual([name for name in dir(test_type)
2699 if name[0:2] not in ('CO', '__')],
2700 [], msg='Names other than CONVERT_TEST_* found.')
2701
2702
Ethan Furman6b3d64a2013-06-14 16:55:46 -07002703if __name__ == '__main__':
2704 unittest.main()