blob: 4b17228946015a58f0f8f5c6aa4b383717a09dae [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
orlnub123c0d63bf2018-09-10 19:39:48 +03001519 def test_subclass_duplicate_name(self):
1520 class Base(Enum):
1521 def test(self):
1522 pass
1523 class Test(Base):
1524 test = 1
1525 self.assertIs(type(Test.test), Test)
1526
1527 def test_subclass_duplicate_name_dynamic(self):
1528 from types import DynamicClassAttribute
1529 class Base(Enum):
1530 @DynamicClassAttribute
1531 def test(self):
1532 return 'dynamic'
1533 class Test(Base):
1534 test = 1
1535 self.assertEqual(Test.test.test, 'dynamic')
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001536
1537 def test_no_duplicates(self):
1538 class UniqueEnum(Enum):
1539 def __init__(self, *args):
1540 cls = self.__class__
1541 if any(self.value == e.value for e in cls):
1542 a = self.name
1543 e = cls(self.value).name
1544 raise ValueError(
1545 "aliases not allowed in UniqueEnum: %r --> %r"
1546 % (a, e)
1547 )
1548 class Color(UniqueEnum):
1549 red = 1
1550 green = 2
1551 blue = 3
1552 with self.assertRaises(ValueError):
1553 class Color(UniqueEnum):
1554 red = 1
1555 green = 2
1556 blue = 3
1557 grene = 2
1558
1559 def test_init(self):
1560 class Planet(Enum):
1561 MERCURY = (3.303e+23, 2.4397e6)
1562 VENUS = (4.869e+24, 6.0518e6)
1563 EARTH = (5.976e+24, 6.37814e6)
1564 MARS = (6.421e+23, 3.3972e6)
1565 JUPITER = (1.9e+27, 7.1492e7)
1566 SATURN = (5.688e+26, 6.0268e7)
1567 URANUS = (8.686e+25, 2.5559e7)
1568 NEPTUNE = (1.024e+26, 2.4746e7)
1569 def __init__(self, mass, radius):
1570 self.mass = mass # in kilograms
1571 self.radius = radius # in meters
1572 @property
1573 def surface_gravity(self):
1574 # universal gravitational constant (m3 kg-1 s-2)
1575 G = 6.67300E-11
1576 return G * self.mass / (self.radius * self.radius)
1577 self.assertEqual(round(Planet.EARTH.surface_gravity, 2), 9.80)
1578 self.assertEqual(Planet.EARTH.value, (5.976e+24, 6.37814e6))
1579
Ethan Furmana4b1bb42018-01-22 07:56:37 -08001580 def test_ignore(self):
1581 class Period(timedelta, Enum):
1582 '''
1583 different lengths of time
1584 '''
1585 def __new__(cls, value, period):
1586 obj = timedelta.__new__(cls, value)
1587 obj._value_ = value
1588 obj.period = period
1589 return obj
1590 _ignore_ = 'Period i'
1591 Period = vars()
1592 for i in range(13):
1593 Period['month_%d' % i] = i*30, 'month'
1594 for i in range(53):
1595 Period['week_%d' % i] = i*7, 'week'
1596 for i in range(32):
1597 Period['day_%d' % i] = i, 'day'
1598 OneDay = day_1
1599 OneWeek = week_1
1600 OneMonth = month_1
1601 self.assertFalse(hasattr(Period, '_ignore_'))
1602 self.assertFalse(hasattr(Period, 'Period'))
1603 self.assertFalse(hasattr(Period, 'i'))
1604 self.assertTrue(isinstance(Period.day_1, timedelta))
1605 self.assertTrue(Period.month_1 is Period.day_30)
1606 self.assertTrue(Period.week_4 is Period.day_28)
1607
Ethan Furman2aa27322013-07-19 19:35:56 -07001608 def test_nonhash_value(self):
1609 class AutoNumberInAList(Enum):
1610 def __new__(cls):
1611 value = [len(cls.__members__) + 1]
1612 obj = object.__new__(cls)
Ethan Furman520ad572013-07-19 19:47:21 -07001613 obj._value_ = value
Ethan Furman2aa27322013-07-19 19:35:56 -07001614 return obj
1615 class ColorInAList(AutoNumberInAList):
1616 red = ()
1617 green = ()
1618 blue = ()
1619 self.assertEqual(list(ColorInAList), [ColorInAList.red, ColorInAList.green, ColorInAList.blue])
Ethan Furman1a162882013-10-16 19:09:31 -07001620 for enum, value in zip(ColorInAList, range(3)):
1621 value += 1
1622 self.assertEqual(enum.value, [value])
1623 self.assertIs(ColorInAList([value]), enum)
Ethan Furman2aa27322013-07-19 19:35:56 -07001624
Ethan Furmanb41803e2013-07-25 13:50:45 -07001625 def test_conflicting_types_resolved_in_new(self):
1626 class LabelledIntEnum(int, Enum):
1627 def __new__(cls, *args):
1628 value, label = args
1629 obj = int.__new__(cls, value)
1630 obj.label = label
1631 obj._value_ = value
1632 return obj
1633
1634 class LabelledList(LabelledIntEnum):
1635 unprocessed = (1, "Unprocessed")
1636 payment_complete = (2, "Payment Complete")
1637
1638 self.assertEqual(list(LabelledList), [LabelledList.unprocessed, LabelledList.payment_complete])
1639 self.assertEqual(LabelledList.unprocessed, 1)
1640 self.assertEqual(LabelledList(1), LabelledList.unprocessed)
Ethan Furman2aa27322013-07-19 19:35:56 -07001641
Ethan Furmanc16595e2016-09-10 23:36:59 -07001642 def test_auto_number(self):
1643 class Color(Enum):
1644 red = auto()
1645 blue = auto()
1646 green = auto()
1647
1648 self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
1649 self.assertEqual(Color.red.value, 1)
1650 self.assertEqual(Color.blue.value, 2)
1651 self.assertEqual(Color.green.value, 3)
1652
1653 def test_auto_name(self):
1654 class Color(Enum):
1655 def _generate_next_value_(name, start, count, last):
1656 return name
1657 red = auto()
1658 blue = auto()
1659 green = auto()
1660
1661 self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
1662 self.assertEqual(Color.red.value, 'red')
1663 self.assertEqual(Color.blue.value, 'blue')
1664 self.assertEqual(Color.green.value, 'green')
1665
1666 def test_auto_name_inherit(self):
1667 class AutoNameEnum(Enum):
1668 def _generate_next_value_(name, start, count, last):
1669 return name
1670 class Color(AutoNameEnum):
1671 red = auto()
1672 blue = auto()
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, 'blue')
1678 self.assertEqual(Color.green.value, 'green')
1679
1680 def test_auto_garbage(self):
1681 class Color(Enum):
1682 red = 'red'
1683 blue = auto()
1684 self.assertEqual(Color.blue.value, 1)
1685
1686 def test_auto_garbage_corrected(self):
1687 class Color(Enum):
1688 red = 'red'
1689 blue = 2
1690 green = auto()
1691
1692 self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
1693 self.assertEqual(Color.red.value, 'red')
1694 self.assertEqual(Color.blue.value, 2)
1695 self.assertEqual(Color.green.value, 3)
1696
Ethan Furman3515dcc2016-09-18 13:15:41 -07001697 def test_duplicate_auto(self):
1698 class Dupes(Enum):
1699 first = primero = auto()
1700 second = auto()
1701 third = auto()
1702 self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes))
1703
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001704
Ethan Furmane8e61272016-08-20 07:19:31 -07001705class TestOrder(unittest.TestCase):
1706
1707 def test_same_members(self):
1708 class Color(Enum):
1709 _order_ = 'red green blue'
1710 red = 1
1711 green = 2
1712 blue = 3
1713
1714 def test_same_members_with_aliases(self):
1715 class Color(Enum):
1716 _order_ = 'red green blue'
1717 red = 1
1718 green = 2
1719 blue = 3
1720 verde = green
1721
1722 def test_same_members_wrong_order(self):
1723 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
1724 class Color(Enum):
1725 _order_ = 'red green blue'
1726 red = 1
1727 blue = 3
1728 green = 2
1729
1730 def test_order_has_extra_members(self):
1731 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
1732 class Color(Enum):
1733 _order_ = 'red green blue purple'
1734 red = 1
1735 green = 2
1736 blue = 3
1737
1738 def test_order_has_extra_members_with_aliases(self):
1739 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
1740 class Color(Enum):
1741 _order_ = 'red green blue purple'
1742 red = 1
1743 green = 2
1744 blue = 3
1745 verde = green
1746
1747 def test_enum_has_extra_members(self):
1748 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
1749 class Color(Enum):
1750 _order_ = 'red green blue'
1751 red = 1
1752 green = 2
1753 blue = 3
1754 purple = 4
1755
1756 def test_enum_has_extra_members_with_aliases(self):
1757 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
1758 class Color(Enum):
1759 _order_ = 'red green blue'
1760 red = 1
1761 green = 2
1762 blue = 3
1763 purple = 4
1764 verde = green
1765
1766
Ethan Furman65a5a472016-09-01 23:55:19 -07001767class TestFlag(unittest.TestCase):
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001768 """Tests of the Flags."""
1769
Ethan Furman65a5a472016-09-01 23:55:19 -07001770 class Perm(Flag):
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001771 R, W, X = 4, 2, 1
1772
Ethan Furman37151762018-04-11 18:56:25 -07001773 class Color(Flag):
1774 BLACK = 0
1775 RED = 1
1776 GREEN = 2
1777 BLUE = 4
1778 PURPLE = RED|BLUE
1779
Ethan Furman65a5a472016-09-01 23:55:19 -07001780 class Open(Flag):
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001781 RO = 0
1782 WO = 1
1783 RW = 2
1784 AC = 3
1785 CE = 1<<19
1786
1787 def test_str(self):
1788 Perm = self.Perm
1789 self.assertEqual(str(Perm.R), 'Perm.R')
1790 self.assertEqual(str(Perm.W), 'Perm.W')
1791 self.assertEqual(str(Perm.X), 'Perm.X')
1792 self.assertEqual(str(Perm.R | Perm.W), 'Perm.R|W')
1793 self.assertEqual(str(Perm.R | Perm.W | Perm.X), 'Perm.R|W|X')
1794 self.assertEqual(str(Perm(0)), 'Perm.0')
1795 self.assertEqual(str(~Perm.R), 'Perm.W|X')
1796 self.assertEqual(str(~Perm.W), 'Perm.R|X')
1797 self.assertEqual(str(~Perm.X), 'Perm.R|W')
1798 self.assertEqual(str(~(Perm.R | Perm.W)), 'Perm.X')
1799 self.assertEqual(str(~(Perm.R | Perm.W | Perm.X)), 'Perm.0')
1800 self.assertEqual(str(Perm(~0)), 'Perm.R|W|X')
1801
1802 Open = self.Open
1803 self.assertEqual(str(Open.RO), 'Open.RO')
1804 self.assertEqual(str(Open.WO), 'Open.WO')
1805 self.assertEqual(str(Open.AC), 'Open.AC')
1806 self.assertEqual(str(Open.RO | Open.CE), 'Open.CE')
1807 self.assertEqual(str(Open.WO | Open.CE), 'Open.CE|WO')
Ethan Furman3515dcc2016-09-18 13:15:41 -07001808 self.assertEqual(str(~Open.RO), 'Open.CE|AC|RW|WO')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001809 self.assertEqual(str(~Open.WO), 'Open.CE|RW')
1810 self.assertEqual(str(~Open.AC), 'Open.CE')
1811 self.assertEqual(str(~(Open.RO | Open.CE)), 'Open.AC')
1812 self.assertEqual(str(~(Open.WO | Open.CE)), 'Open.RW')
1813
1814 def test_repr(self):
1815 Perm = self.Perm
1816 self.assertEqual(repr(Perm.R), '<Perm.R: 4>')
1817 self.assertEqual(repr(Perm.W), '<Perm.W: 2>')
1818 self.assertEqual(repr(Perm.X), '<Perm.X: 1>')
1819 self.assertEqual(repr(Perm.R | Perm.W), '<Perm.R|W: 6>')
1820 self.assertEqual(repr(Perm.R | Perm.W | Perm.X), '<Perm.R|W|X: 7>')
Ethan Furman27682d22016-09-04 11:39:01 -07001821 self.assertEqual(repr(Perm(0)), '<Perm.0: 0>')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001822 self.assertEqual(repr(~Perm.R), '<Perm.W|X: 3>')
1823 self.assertEqual(repr(~Perm.W), '<Perm.R|X: 5>')
1824 self.assertEqual(repr(~Perm.X), '<Perm.R|W: 6>')
1825 self.assertEqual(repr(~(Perm.R | Perm.W)), '<Perm.X: 1>')
Ethan Furman27682d22016-09-04 11:39:01 -07001826 self.assertEqual(repr(~(Perm.R | Perm.W | Perm.X)), '<Perm.0: 0>')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001827 self.assertEqual(repr(Perm(~0)), '<Perm.R|W|X: 7>')
1828
1829 Open = self.Open
1830 self.assertEqual(repr(Open.RO), '<Open.RO: 0>')
1831 self.assertEqual(repr(Open.WO), '<Open.WO: 1>')
1832 self.assertEqual(repr(Open.AC), '<Open.AC: 3>')
1833 self.assertEqual(repr(Open.RO | Open.CE), '<Open.CE: 524288>')
1834 self.assertEqual(repr(Open.WO | Open.CE), '<Open.CE|WO: 524289>')
Ethan Furman3515dcc2016-09-18 13:15:41 -07001835 self.assertEqual(repr(~Open.RO), '<Open.CE|AC|RW|WO: 524291>')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001836 self.assertEqual(repr(~Open.WO), '<Open.CE|RW: 524290>')
1837 self.assertEqual(repr(~Open.AC), '<Open.CE: 524288>')
1838 self.assertEqual(repr(~(Open.RO | Open.CE)), '<Open.AC: 3>')
1839 self.assertEqual(repr(~(Open.WO | Open.CE)), '<Open.RW: 2>')
1840
1841 def test_or(self):
1842 Perm = self.Perm
1843 for i in Perm:
1844 for j in Perm:
1845 self.assertEqual((i | j), Perm(i.value | j.value))
1846 self.assertEqual((i | j).value, i.value | j.value)
1847 self.assertIs(type(i | j), Perm)
1848 for i in Perm:
1849 self.assertIs(i | i, i)
1850 Open = self.Open
1851 self.assertIs(Open.RO | Open.CE, Open.CE)
1852
1853 def test_and(self):
1854 Perm = self.Perm
1855 RW = Perm.R | Perm.W
1856 RX = Perm.R | Perm.X
1857 WX = Perm.W | Perm.X
1858 RWX = Perm.R | Perm.W | Perm.X
1859 values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
1860 for i in values:
1861 for j in values:
1862 self.assertEqual((i & j).value, i.value & j.value)
1863 self.assertIs(type(i & j), Perm)
1864 for i in Perm:
1865 self.assertIs(i & i, i)
1866 self.assertIs(i & RWX, i)
1867 self.assertIs(RWX & i, i)
1868 Open = self.Open
1869 self.assertIs(Open.RO & Open.CE, Open.RO)
1870
1871 def test_xor(self):
1872 Perm = self.Perm
1873 for i in Perm:
1874 for j in Perm:
1875 self.assertEqual((i ^ j).value, i.value ^ j.value)
1876 self.assertIs(type(i ^ j), Perm)
1877 for i in Perm:
1878 self.assertIs(i ^ Perm(0), i)
1879 self.assertIs(Perm(0) ^ i, i)
1880 Open = self.Open
1881 self.assertIs(Open.RO ^ Open.CE, Open.CE)
1882 self.assertIs(Open.CE ^ Open.CE, Open.RO)
1883
1884 def test_invert(self):
1885 Perm = self.Perm
1886 RW = Perm.R | Perm.W
1887 RX = Perm.R | Perm.X
1888 WX = Perm.W | Perm.X
1889 RWX = Perm.R | Perm.W | Perm.X
1890 values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
1891 for i in values:
1892 self.assertIs(type(~i), Perm)
1893 self.assertEqual(~~i, i)
1894 for i in Perm:
1895 self.assertIs(~~i, i)
1896 Open = self.Open
1897 self.assertIs(Open.WO & ~Open.WO, Open.RO)
1898 self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE)
1899
Ethan Furman25d94bb2016-09-02 16:32:32 -07001900 def test_bool(self):
1901 Perm = self.Perm
1902 for f in Perm:
1903 self.assertTrue(f)
1904 Open = self.Open
1905 for f in Open:
1906 self.assertEqual(bool(f.value), bool(f))
1907
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001908 def test_programatic_function_string(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07001909 Perm = Flag('Perm', 'R W X')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001910 lst = list(Perm)
1911 self.assertEqual(len(lst), len(Perm))
1912 self.assertEqual(len(Perm), 3, Perm)
1913 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
1914 for i, n in enumerate('R W X'.split()):
1915 v = 1<<i
1916 e = Perm(v)
1917 self.assertEqual(e.value, v)
1918 self.assertEqual(type(e.value), int)
1919 self.assertEqual(e.name, n)
1920 self.assertIn(e, Perm)
1921 self.assertIs(type(e), Perm)
1922
1923 def test_programatic_function_string_with_start(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07001924 Perm = Flag('Perm', 'R W X', start=8)
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001925 lst = list(Perm)
1926 self.assertEqual(len(lst), len(Perm))
1927 self.assertEqual(len(Perm), 3, Perm)
1928 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
1929 for i, n in enumerate('R W X'.split()):
1930 v = 8<<i
1931 e = Perm(v)
1932 self.assertEqual(e.value, v)
1933 self.assertEqual(type(e.value), int)
1934 self.assertEqual(e.name, n)
1935 self.assertIn(e, Perm)
1936 self.assertIs(type(e), Perm)
1937
1938 def test_programatic_function_string_list(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07001939 Perm = Flag('Perm', ['R', 'W', 'X'])
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001940 lst = list(Perm)
1941 self.assertEqual(len(lst), len(Perm))
1942 self.assertEqual(len(Perm), 3, Perm)
1943 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
1944 for i, n in enumerate('R W X'.split()):
1945 v = 1<<i
1946 e = Perm(v)
1947 self.assertEqual(e.value, v)
1948 self.assertEqual(type(e.value), int)
1949 self.assertEqual(e.name, n)
1950 self.assertIn(e, Perm)
1951 self.assertIs(type(e), Perm)
1952
1953 def test_programatic_function_iterable(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07001954 Perm = Flag('Perm', (('R', 2), ('W', 8), ('X', 32)))
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001955 lst = list(Perm)
1956 self.assertEqual(len(lst), len(Perm))
1957 self.assertEqual(len(Perm), 3, Perm)
1958 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
1959 for i, n in enumerate('R W X'.split()):
1960 v = 1<<(2*i+1)
1961 e = Perm(v)
1962 self.assertEqual(e.value, v)
1963 self.assertEqual(type(e.value), int)
1964 self.assertEqual(e.name, n)
1965 self.assertIn(e, Perm)
1966 self.assertIs(type(e), Perm)
1967
1968 def test_programatic_function_from_dict(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07001969 Perm = Flag('Perm', OrderedDict((('R', 2), ('W', 8), ('X', 32))))
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001970 lst = list(Perm)
1971 self.assertEqual(len(lst), len(Perm))
1972 self.assertEqual(len(Perm), 3, Perm)
1973 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
1974 for i, n in enumerate('R W X'.split()):
1975 v = 1<<(2*i+1)
1976 e = Perm(v)
1977 self.assertEqual(e.value, v)
1978 self.assertEqual(type(e.value), int)
1979 self.assertEqual(e.name, n)
1980 self.assertIn(e, Perm)
1981 self.assertIs(type(e), Perm)
1982
Ethan Furman65a5a472016-09-01 23:55:19 -07001983 def test_pickle(self):
1984 if isinstance(FlagStooges, Exception):
1985 raise FlagStooges
1986 test_pickle_dump_load(self.assertIs, FlagStooges.CURLY|FlagStooges.MOE)
1987 test_pickle_dump_load(self.assertIs, FlagStooges)
Ethan Furmanee47e5c2016-08-31 00:12:15 -07001988
Ethan Furman37151762018-04-11 18:56:25 -07001989 def test_contains(self):
1990 Open = self.Open
1991 Color = self.Color
1992 self.assertFalse(Color.BLACK in Open)
1993 self.assertFalse(Open.RO in Color)
1994 with self.assertWarns(DeprecationWarning):
1995 self.assertFalse('BLACK' in Color)
1996 with self.assertWarns(DeprecationWarning):
1997 self.assertFalse('RO' in Open)
1998 with self.assertWarns(DeprecationWarning):
1999 self.assertFalse(1 in Color)
2000 with self.assertWarns(DeprecationWarning):
2001 self.assertFalse(1 in Open)
2002
2003 def test_member_contains(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07002004 Perm = self.Perm
2005 R, W, X = Perm
2006 RW = R | W
2007 RX = R | X
2008 WX = W | X
2009 RWX = R | W | X
2010 self.assertTrue(R in RW)
2011 self.assertTrue(R in RX)
2012 self.assertTrue(R in RWX)
2013 self.assertTrue(W in RW)
2014 self.assertTrue(W in WX)
2015 self.assertTrue(W in RWX)
2016 self.assertTrue(X in RX)
2017 self.assertTrue(X in WX)
2018 self.assertTrue(X in RWX)
2019 self.assertFalse(R in WX)
2020 self.assertFalse(W in RX)
2021 self.assertFalse(X in RW)
2022
Ethan Furmanc16595e2016-09-10 23:36:59 -07002023 def test_auto_number(self):
2024 class Color(Flag):
2025 red = auto()
2026 blue = auto()
2027 green = auto()
2028
2029 self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
2030 self.assertEqual(Color.red.value, 1)
2031 self.assertEqual(Color.blue.value, 2)
2032 self.assertEqual(Color.green.value, 4)
2033
2034 def test_auto_number_garbage(self):
2035 with self.assertRaisesRegex(TypeError, 'Invalid Flag value: .not an int.'):
2036 class Color(Flag):
2037 red = 'not an int'
2038 blue = auto()
2039
Ethan Furman3515dcc2016-09-18 13:15:41 -07002040 def test_cascading_failure(self):
2041 class Bizarre(Flag):
2042 c = 3
2043 d = 4
2044 f = 6
2045 # Bizarre.c | Bizarre.d
2046 self.assertRaisesRegex(ValueError, "5 is not a valid Bizarre", Bizarre, 5)
2047 self.assertRaisesRegex(ValueError, "5 is not a valid Bizarre", Bizarre, 5)
2048 self.assertRaisesRegex(ValueError, "2 is not a valid Bizarre", Bizarre, 2)
2049 self.assertRaisesRegex(ValueError, "2 is not a valid Bizarre", Bizarre, 2)
2050 self.assertRaisesRegex(ValueError, "1 is not a valid Bizarre", Bizarre, 1)
2051 self.assertRaisesRegex(ValueError, "1 is not a valid Bizarre", Bizarre, 1)
2052
2053 def test_duplicate_auto(self):
2054 class Dupes(Enum):
2055 first = primero = auto()
2056 second = auto()
2057 third = auto()
2058 self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes))
2059
2060 def test_bizarre(self):
2061 class Bizarre(Flag):
2062 b = 3
2063 c = 4
2064 d = 6
2065 self.assertEqual(repr(Bizarre(7)), '<Bizarre.d|c|b: 7>')
2066
Ethan Furman28cf6632017-01-24 12:12:06 -08002067 @support.reap_threads
2068 def test_unique_composite(self):
2069 # override __eq__ to be identity only
2070 class TestFlag(Flag):
2071 one = auto()
2072 two = auto()
2073 three = auto()
2074 four = auto()
2075 five = auto()
2076 six = auto()
2077 seven = auto()
2078 eight = auto()
2079 def __eq__(self, other):
2080 return self is other
2081 def __hash__(self):
2082 return hash(self._value_)
2083 # have multiple threads competing to complete the composite members
2084 seen = set()
2085 failed = False
2086 def cycle_enum():
2087 nonlocal failed
2088 try:
2089 for i in range(256):
2090 seen.add(TestFlag(i))
2091 except Exception:
2092 failed = True
2093 threads = [
2094 threading.Thread(target=cycle_enum)
2095 for _ in range(8)
2096 ]
2097 with support.start_threads(threads):
2098 pass
2099 # check that only 248 members were created
2100 self.assertFalse(
2101 failed,
2102 'at least one thread failed while creating composite members')
2103 self.assertEqual(256, len(seen), 'too many composite members created')
2104
Ethan Furmanc16595e2016-09-10 23:36:59 -07002105
Ethan Furman65a5a472016-09-01 23:55:19 -07002106class TestIntFlag(unittest.TestCase):
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002107 """Tests of the IntFlags."""
2108
Ethan Furman65a5a472016-09-01 23:55:19 -07002109 class Perm(IntFlag):
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002110 X = 1 << 0
2111 W = 1 << 1
2112 R = 1 << 2
2113
Ethan Furman37151762018-04-11 18:56:25 -07002114 class Color(IntFlag):
2115 BLACK = 0
2116 RED = 1
2117 GREEN = 2
2118 BLUE = 4
2119 PURPLE = RED|BLUE
2120
Ethan Furman65a5a472016-09-01 23:55:19 -07002121 class Open(IntFlag):
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002122 RO = 0
2123 WO = 1
2124 RW = 2
2125 AC = 3
2126 CE = 1<<19
2127
Ethan Furman3515dcc2016-09-18 13:15:41 -07002128 def test_type(self):
2129 Perm = self.Perm
2130 Open = self.Open
2131 for f in Perm:
2132 self.assertTrue(isinstance(f, Perm))
2133 self.assertEqual(f, f.value)
2134 self.assertTrue(isinstance(Perm.W | Perm.X, Perm))
2135 self.assertEqual(Perm.W | Perm.X, 3)
2136 for f in Open:
2137 self.assertTrue(isinstance(f, Open))
2138 self.assertEqual(f, f.value)
2139 self.assertTrue(isinstance(Open.WO | Open.RW, Open))
2140 self.assertEqual(Open.WO | Open.RW, 3)
2141
2142
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002143 def test_str(self):
2144 Perm = self.Perm
2145 self.assertEqual(str(Perm.R), 'Perm.R')
2146 self.assertEqual(str(Perm.W), 'Perm.W')
2147 self.assertEqual(str(Perm.X), 'Perm.X')
2148 self.assertEqual(str(Perm.R | Perm.W), 'Perm.R|W')
2149 self.assertEqual(str(Perm.R | Perm.W | Perm.X), 'Perm.R|W|X')
2150 self.assertEqual(str(Perm.R | 8), 'Perm.8|R')
2151 self.assertEqual(str(Perm(0)), 'Perm.0')
2152 self.assertEqual(str(Perm(8)), 'Perm.8')
Ethan Furman3515dcc2016-09-18 13:15:41 -07002153 self.assertEqual(str(~Perm.R), 'Perm.W|X')
2154 self.assertEqual(str(~Perm.W), 'Perm.R|X')
2155 self.assertEqual(str(~Perm.X), 'Perm.R|W')
2156 self.assertEqual(str(~(Perm.R | Perm.W)), 'Perm.X')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002157 self.assertEqual(str(~(Perm.R | Perm.W | Perm.X)), 'Perm.-8')
Ethan Furman3515dcc2016-09-18 13:15:41 -07002158 self.assertEqual(str(~(Perm.R | 8)), 'Perm.W|X')
2159 self.assertEqual(str(Perm(~0)), 'Perm.R|W|X')
2160 self.assertEqual(str(Perm(~8)), 'Perm.R|W|X')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002161
2162 Open = self.Open
2163 self.assertEqual(str(Open.RO), 'Open.RO')
2164 self.assertEqual(str(Open.WO), 'Open.WO')
2165 self.assertEqual(str(Open.AC), 'Open.AC')
2166 self.assertEqual(str(Open.RO | Open.CE), 'Open.CE')
2167 self.assertEqual(str(Open.WO | Open.CE), 'Open.CE|WO')
2168 self.assertEqual(str(Open(4)), 'Open.4')
Ethan Furman3515dcc2016-09-18 13:15:41 -07002169 self.assertEqual(str(~Open.RO), 'Open.CE|AC|RW|WO')
2170 self.assertEqual(str(~Open.WO), 'Open.CE|RW')
2171 self.assertEqual(str(~Open.AC), 'Open.CE')
2172 self.assertEqual(str(~(Open.RO | Open.CE)), 'Open.AC|RW|WO')
2173 self.assertEqual(str(~(Open.WO | Open.CE)), 'Open.RW')
2174 self.assertEqual(str(Open(~4)), 'Open.CE|AC|RW|WO')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002175
2176 def test_repr(self):
2177 Perm = self.Perm
2178 self.assertEqual(repr(Perm.R), '<Perm.R: 4>')
2179 self.assertEqual(repr(Perm.W), '<Perm.W: 2>')
2180 self.assertEqual(repr(Perm.X), '<Perm.X: 1>')
2181 self.assertEqual(repr(Perm.R | Perm.W), '<Perm.R|W: 6>')
2182 self.assertEqual(repr(Perm.R | Perm.W | Perm.X), '<Perm.R|W|X: 7>')
2183 self.assertEqual(repr(Perm.R | 8), '<Perm.8|R: 12>')
Ethan Furman27682d22016-09-04 11:39:01 -07002184 self.assertEqual(repr(Perm(0)), '<Perm.0: 0>')
2185 self.assertEqual(repr(Perm(8)), '<Perm.8: 8>')
Ethan Furman3515dcc2016-09-18 13:15:41 -07002186 self.assertEqual(repr(~Perm.R), '<Perm.W|X: -5>')
2187 self.assertEqual(repr(~Perm.W), '<Perm.R|X: -3>')
2188 self.assertEqual(repr(~Perm.X), '<Perm.R|W: -2>')
2189 self.assertEqual(repr(~(Perm.R | Perm.W)), '<Perm.X: -7>')
Ethan Furman27682d22016-09-04 11:39:01 -07002190 self.assertEqual(repr(~(Perm.R | Perm.W | Perm.X)), '<Perm.-8: -8>')
Ethan Furman3515dcc2016-09-18 13:15:41 -07002191 self.assertEqual(repr(~(Perm.R | 8)), '<Perm.W|X: -13>')
2192 self.assertEqual(repr(Perm(~0)), '<Perm.R|W|X: -1>')
2193 self.assertEqual(repr(Perm(~8)), '<Perm.R|W|X: -9>')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002194
2195 Open = self.Open
2196 self.assertEqual(repr(Open.RO), '<Open.RO: 0>')
2197 self.assertEqual(repr(Open.WO), '<Open.WO: 1>')
2198 self.assertEqual(repr(Open.AC), '<Open.AC: 3>')
2199 self.assertEqual(repr(Open.RO | Open.CE), '<Open.CE: 524288>')
2200 self.assertEqual(repr(Open.WO | Open.CE), '<Open.CE|WO: 524289>')
Ethan Furman27682d22016-09-04 11:39:01 -07002201 self.assertEqual(repr(Open(4)), '<Open.4: 4>')
Ethan Furman3515dcc2016-09-18 13:15:41 -07002202 self.assertEqual(repr(~Open.RO), '<Open.CE|AC|RW|WO: -1>')
2203 self.assertEqual(repr(~Open.WO), '<Open.CE|RW: -2>')
2204 self.assertEqual(repr(~Open.AC), '<Open.CE: -4>')
2205 self.assertEqual(repr(~(Open.RO | Open.CE)), '<Open.AC|RW|WO: -524289>')
2206 self.assertEqual(repr(~(Open.WO | Open.CE)), '<Open.RW: -524290>')
2207 self.assertEqual(repr(Open(~4)), '<Open.CE|AC|RW|WO: -5>')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002208
2209 def test_or(self):
2210 Perm = self.Perm
2211 for i in Perm:
2212 for j in Perm:
2213 self.assertEqual(i | j, i.value | j.value)
2214 self.assertEqual((i | j).value, i.value | j.value)
2215 self.assertIs(type(i | j), Perm)
2216 for j in range(8):
2217 self.assertEqual(i | j, i.value | j)
2218 self.assertEqual((i | j).value, i.value | j)
2219 self.assertIs(type(i | j), Perm)
2220 self.assertEqual(j | i, j | i.value)
2221 self.assertEqual((j | i).value, j | i.value)
2222 self.assertIs(type(j | i), Perm)
2223 for i in Perm:
2224 self.assertIs(i | i, i)
2225 self.assertIs(i | 0, i)
2226 self.assertIs(0 | i, i)
2227 Open = self.Open
2228 self.assertIs(Open.RO | Open.CE, Open.CE)
2229
2230 def test_and(self):
2231 Perm = self.Perm
2232 RW = Perm.R | Perm.W
2233 RX = Perm.R | Perm.X
2234 WX = Perm.W | Perm.X
2235 RWX = Perm.R | Perm.W | Perm.X
2236 values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
2237 for i in values:
2238 for j in values:
2239 self.assertEqual(i & j, i.value & j.value, 'i is %r, j is %r' % (i, j))
2240 self.assertEqual((i & j).value, i.value & j.value, 'i is %r, j is %r' % (i, j))
2241 self.assertIs(type(i & j), Perm, 'i is %r, j is %r' % (i, j))
2242 for j in range(8):
2243 self.assertEqual(i & j, i.value & j)
2244 self.assertEqual((i & j).value, i.value & j)
2245 self.assertIs(type(i & j), Perm)
2246 self.assertEqual(j & i, j & i.value)
2247 self.assertEqual((j & i).value, j & i.value)
2248 self.assertIs(type(j & i), Perm)
2249 for i in Perm:
2250 self.assertIs(i & i, i)
2251 self.assertIs(i & 7, i)
2252 self.assertIs(7 & i, i)
2253 Open = self.Open
2254 self.assertIs(Open.RO & Open.CE, Open.RO)
2255
2256 def test_xor(self):
2257 Perm = self.Perm
2258 for i in Perm:
2259 for j in Perm:
2260 self.assertEqual(i ^ j, i.value ^ j.value)
2261 self.assertEqual((i ^ j).value, i.value ^ j.value)
2262 self.assertIs(type(i ^ j), Perm)
2263 for j in range(8):
2264 self.assertEqual(i ^ j, i.value ^ j)
2265 self.assertEqual((i ^ j).value, i.value ^ j)
2266 self.assertIs(type(i ^ j), Perm)
2267 self.assertEqual(j ^ i, j ^ i.value)
2268 self.assertEqual((j ^ i).value, j ^ i.value)
2269 self.assertIs(type(j ^ i), Perm)
2270 for i in Perm:
2271 self.assertIs(i ^ 0, i)
2272 self.assertIs(0 ^ i, i)
2273 Open = self.Open
2274 self.assertIs(Open.RO ^ Open.CE, Open.CE)
2275 self.assertIs(Open.CE ^ Open.CE, Open.RO)
2276
2277 def test_invert(self):
2278 Perm = self.Perm
2279 RW = Perm.R | Perm.W
2280 RX = Perm.R | Perm.X
2281 WX = Perm.W | Perm.X
2282 RWX = Perm.R | Perm.W | Perm.X
2283 values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
2284 for i in values:
2285 self.assertEqual(~i, ~i.value)
2286 self.assertEqual((~i).value, ~i.value)
2287 self.assertIs(type(~i), Perm)
2288 self.assertEqual(~~i, i)
2289 for i in Perm:
2290 self.assertIs(~~i, i)
2291 Open = self.Open
2292 self.assertIs(Open.WO & ~Open.WO, Open.RO)
2293 self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE)
2294
2295 def test_programatic_function_string(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07002296 Perm = IntFlag('Perm', 'R W X')
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002297 lst = list(Perm)
2298 self.assertEqual(len(lst), len(Perm))
2299 self.assertEqual(len(Perm), 3, Perm)
2300 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2301 for i, n in enumerate('R W X'.split()):
2302 v = 1<<i
2303 e = Perm(v)
2304 self.assertEqual(e.value, v)
2305 self.assertEqual(type(e.value), int)
2306 self.assertEqual(e, v)
2307 self.assertEqual(e.name, n)
2308 self.assertIn(e, Perm)
2309 self.assertIs(type(e), Perm)
2310
2311 def test_programatic_function_string_with_start(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07002312 Perm = IntFlag('Perm', 'R W X', start=8)
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002313 lst = list(Perm)
2314 self.assertEqual(len(lst), len(Perm))
2315 self.assertEqual(len(Perm), 3, Perm)
2316 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2317 for i, n in enumerate('R W X'.split()):
2318 v = 8<<i
2319 e = Perm(v)
2320 self.assertEqual(e.value, v)
2321 self.assertEqual(type(e.value), int)
2322 self.assertEqual(e, v)
2323 self.assertEqual(e.name, n)
2324 self.assertIn(e, Perm)
2325 self.assertIs(type(e), Perm)
2326
2327 def test_programatic_function_string_list(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07002328 Perm = IntFlag('Perm', ['R', 'W', 'X'])
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002329 lst = list(Perm)
2330 self.assertEqual(len(lst), len(Perm))
2331 self.assertEqual(len(Perm), 3, Perm)
2332 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2333 for i, n in enumerate('R W X'.split()):
2334 v = 1<<i
2335 e = Perm(v)
2336 self.assertEqual(e.value, v)
2337 self.assertEqual(type(e.value), int)
2338 self.assertEqual(e, v)
2339 self.assertEqual(e.name, n)
2340 self.assertIn(e, Perm)
2341 self.assertIs(type(e), Perm)
2342
2343 def test_programatic_function_iterable(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07002344 Perm = IntFlag('Perm', (('R', 2), ('W', 8), ('X', 32)))
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002345 lst = list(Perm)
2346 self.assertEqual(len(lst), len(Perm))
2347 self.assertEqual(len(Perm), 3, Perm)
2348 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2349 for i, n in enumerate('R W X'.split()):
2350 v = 1<<(2*i+1)
2351 e = Perm(v)
2352 self.assertEqual(e.value, v)
2353 self.assertEqual(type(e.value), int)
2354 self.assertEqual(e, v)
2355 self.assertEqual(e.name, n)
2356 self.assertIn(e, Perm)
2357 self.assertIs(type(e), Perm)
2358
2359 def test_programatic_function_from_dict(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07002360 Perm = IntFlag('Perm', OrderedDict((('R', 2), ('W', 8), ('X', 32))))
Ethan Furmanee47e5c2016-08-31 00:12:15 -07002361 lst = list(Perm)
2362 self.assertEqual(len(lst), len(Perm))
2363 self.assertEqual(len(Perm), 3, Perm)
2364 self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2365 for i, n in enumerate('R W X'.split()):
2366 v = 1<<(2*i+1)
2367 e = Perm(v)
2368 self.assertEqual(e.value, v)
2369 self.assertEqual(type(e.value), int)
2370 self.assertEqual(e, v)
2371 self.assertEqual(e.name, n)
2372 self.assertIn(e, Perm)
2373 self.assertIs(type(e), Perm)
2374
2375
Dong-hee Nadcc8ce42017-06-22 01:52:32 +09002376 def test_programatic_function_from_empty_list(self):
2377 Perm = enum.IntFlag('Perm', [])
2378 lst = list(Perm)
2379 self.assertEqual(len(lst), len(Perm))
2380 self.assertEqual(len(Perm), 0, Perm)
2381 Thing = enum.Enum('Thing', [])
2382 lst = list(Thing)
2383 self.assertEqual(len(lst), len(Thing))
2384 self.assertEqual(len(Thing), 0, Thing)
2385
2386
2387 def test_programatic_function_from_empty_tuple(self):
2388 Perm = enum.IntFlag('Perm', ())
2389 lst = list(Perm)
2390 self.assertEqual(len(lst), len(Perm))
2391 self.assertEqual(len(Perm), 0, Perm)
2392 Thing = enum.Enum('Thing', ())
2393 self.assertEqual(len(lst), len(Thing))
2394 self.assertEqual(len(Thing), 0, Thing)
2395
Ethan Furman37151762018-04-11 18:56:25 -07002396 def test_contains(self):
2397 Color = self.Color
2398 Open = self.Open
2399 self.assertTrue(Color.GREEN in Color)
2400 self.assertTrue(Open.RW in Open)
2401 self.assertFalse(Color.GREEN in Open)
2402 self.assertFalse(Open.RW in Color)
2403 with self.assertWarns(DeprecationWarning):
2404 self.assertFalse('GREEN' in Color)
2405 with self.assertWarns(DeprecationWarning):
2406 self.assertFalse('RW' in Open)
2407 with self.assertWarns(DeprecationWarning):
2408 self.assertFalse(2 in Color)
2409 with self.assertWarns(DeprecationWarning):
2410 self.assertFalse(2 in Open)
2411
2412 def test_member_contains(self):
Ethan Furman65a5a472016-09-01 23:55:19 -07002413 Perm = self.Perm
2414 R, W, X = Perm
2415 RW = R | W
2416 RX = R | X
2417 WX = W | X
2418 RWX = R | W | X
2419 self.assertTrue(R in RW)
2420 self.assertTrue(R in RX)
2421 self.assertTrue(R in RWX)
2422 self.assertTrue(W in RW)
2423 self.assertTrue(W in WX)
2424 self.assertTrue(W in RWX)
2425 self.assertTrue(X in RX)
2426 self.assertTrue(X in WX)
2427 self.assertTrue(X in RWX)
2428 self.assertFalse(R in WX)
2429 self.assertFalse(W in RX)
2430 self.assertFalse(X in RW)
Ethan Furman37151762018-04-11 18:56:25 -07002431 with self.assertWarns(DeprecationWarning):
2432 self.assertFalse('swallow' in RW)
Ethan Furman65a5a472016-09-01 23:55:19 -07002433
Ethan Furman25d94bb2016-09-02 16:32:32 -07002434 def test_bool(self):
2435 Perm = self.Perm
2436 for f in Perm:
2437 self.assertTrue(f)
2438 Open = self.Open
2439 for f in Open:
2440 self.assertEqual(bool(f.value), bool(f))
2441
Ethan Furman28cf6632017-01-24 12:12:06 -08002442 @support.reap_threads
2443 def test_unique_composite(self):
2444 # override __eq__ to be identity only
2445 class TestFlag(IntFlag):
2446 one = auto()
2447 two = auto()
2448 three = auto()
2449 four = auto()
2450 five = auto()
2451 six = auto()
2452 seven = auto()
2453 eight = auto()
2454 def __eq__(self, other):
2455 return self is other
2456 def __hash__(self):
2457 return hash(self._value_)
2458 # have multiple threads competing to complete the composite members
2459 seen = set()
2460 failed = False
2461 def cycle_enum():
2462 nonlocal failed
2463 try:
2464 for i in range(256):
2465 seen.add(TestFlag(i))
2466 except Exception:
2467 failed = True
2468 threads = [
2469 threading.Thread(target=cycle_enum)
2470 for _ in range(8)
2471 ]
2472 with support.start_threads(threads):
2473 pass
2474 # check that only 248 members were created
2475 self.assertFalse(
2476 failed,
2477 'at least one thread failed while creating composite members')
2478 self.assertEqual(256, len(seen), 'too many composite members created')
2479
2480
Ethan Furmanf24bb352013-07-18 17:05:39 -07002481class TestUnique(unittest.TestCase):
2482
2483 def test_unique_clean(self):
2484 @unique
2485 class Clean(Enum):
2486 one = 1
2487 two = 'dos'
2488 tres = 4.0
2489 @unique
2490 class Cleaner(IntEnum):
2491 single = 1
2492 double = 2
2493 triple = 3
2494
2495 def test_unique_dirty(self):
2496 with self.assertRaisesRegex(ValueError, 'tres.*one'):
2497 @unique
2498 class Dirty(Enum):
2499 one = 1
2500 two = 'dos'
2501 tres = 1
2502 with self.assertRaisesRegex(
2503 ValueError,
2504 'double.*single.*turkey.*triple',
2505 ):
2506 @unique
2507 class Dirtier(IntEnum):
2508 single = 1
2509 double = 1
2510 triple = 3
2511 turkey = 3
2512
Ethan Furman3803ad42016-05-01 10:03:53 -07002513 def test_unique_with_name(self):
2514 @unique
2515 class Silly(Enum):
2516 one = 1
2517 two = 'dos'
2518 name = 3
2519 @unique
2520 class Sillier(IntEnum):
2521 single = 1
2522 name = 2
2523 triple = 3
2524 value = 4
2525
Ethan Furmanf24bb352013-07-18 17:05:39 -07002526
Ethan Furman3323da92015-04-11 09:39:59 -07002527expected_help_output_with_docs = """\
Ethan Furman5875d742013-10-21 20:45:55 -07002528Help on class Color in module %s:
2529
2530class Color(enum.Enum)
Serhiy Storchaka90f63322017-01-24 09:06:22 +02002531 | Color(value, names=None, *, module=None, qualname=None, type=None, start=1)
2532 |\x20\x20
Ethan Furman48a724f2015-04-11 23:23:06 -07002533 | An enumeration.
Serhiy Storchakab599ca82015-04-04 12:48:04 +03002534 |\x20\x20
Ethan Furman5875d742013-10-21 20:45:55 -07002535 | Method resolution order:
2536 | Color
2537 | enum.Enum
2538 | builtins.object
2539 |\x20\x20
2540 | Data and other attributes defined here:
2541 |\x20\x20
2542 | blue = <Color.blue: 3>
2543 |\x20\x20
2544 | green = <Color.green: 2>
2545 |\x20\x20
2546 | red = <Color.red: 1>
2547 |\x20\x20
2548 | ----------------------------------------------------------------------
2549 | Data descriptors inherited from enum.Enum:
2550 |\x20\x20
2551 | name
2552 | The name of the Enum member.
2553 |\x20\x20
2554 | value
2555 | The value of the Enum member.
2556 |\x20\x20
2557 | ----------------------------------------------------------------------
2558 | Data descriptors inherited from enum.EnumMeta:
2559 |\x20\x20
2560 | __members__
2561 | Returns a mapping of member name->value.
2562 |\x20\x20\x20\x20\x20\x20
2563 | This mapping lists all enum members, including aliases. Note that this
Ethan Furman3323da92015-04-11 09:39:59 -07002564 | is a read-only view of the internal mapping."""
2565
2566expected_help_output_without_docs = """\
2567Help on class Color in module %s:
2568
2569class Color(enum.Enum)
Serhiy Storchaka90f63322017-01-24 09:06:22 +02002570 | Color(value, names=None, *, module=None, qualname=None, type=None, start=1)
2571 |\x20\x20
Ethan Furman3323da92015-04-11 09:39:59 -07002572 | Method resolution order:
2573 | Color
2574 | enum.Enum
2575 | builtins.object
2576 |\x20\x20
2577 | Data and other attributes defined here:
2578 |\x20\x20
2579 | blue = <Color.blue: 3>
2580 |\x20\x20
2581 | green = <Color.green: 2>
2582 |\x20\x20
2583 | red = <Color.red: 1>
2584 |\x20\x20
2585 | ----------------------------------------------------------------------
2586 | Data descriptors inherited from enum.Enum:
2587 |\x20\x20
2588 | name
2589 |\x20\x20
2590 | value
2591 |\x20\x20
2592 | ----------------------------------------------------------------------
2593 | Data descriptors inherited from enum.EnumMeta:
2594 |\x20\x20
2595 | __members__"""
Ethan Furman5875d742013-10-21 20:45:55 -07002596
2597class TestStdLib(unittest.TestCase):
2598
Ethan Furman48a724f2015-04-11 23:23:06 -07002599 maxDiff = None
2600
Ethan Furman5875d742013-10-21 20:45:55 -07002601 class Color(Enum):
2602 red = 1
2603 green = 2
2604 blue = 3
2605
2606 def test_pydoc(self):
2607 # indirectly test __objclass__
Ethan Furman3323da92015-04-11 09:39:59 -07002608 if StrEnum.__doc__ is None:
2609 expected_text = expected_help_output_without_docs % __name__
2610 else:
2611 expected_text = expected_help_output_with_docs % __name__
Ethan Furman5875d742013-10-21 20:45:55 -07002612 output = StringIO()
2613 helper = pydoc.Helper(output=output)
2614 helper(self.Color)
2615 result = output.getvalue().strip()
Victor Stinner4b0432d2014-06-16 22:48:43 +02002616 self.assertEqual(result, expected_text)
Ethan Furman5875d742013-10-21 20:45:55 -07002617
2618 def test_inspect_getmembers(self):
2619 values = dict((
2620 ('__class__', EnumMeta),
Ethan Furman48a724f2015-04-11 23:23:06 -07002621 ('__doc__', 'An enumeration.'),
Ethan Furman5875d742013-10-21 20:45:55 -07002622 ('__members__', self.Color.__members__),
2623 ('__module__', __name__),
2624 ('blue', self.Color.blue),
2625 ('green', self.Color.green),
2626 ('name', Enum.__dict__['name']),
2627 ('red', self.Color.red),
2628 ('value', Enum.__dict__['value']),
2629 ))
2630 result = dict(inspect.getmembers(self.Color))
2631 self.assertEqual(values.keys(), result.keys())
2632 failed = False
2633 for k in values.keys():
2634 if result[k] != values[k]:
2635 print()
2636 print('\n%s\n key: %s\n result: %s\nexpected: %s\n%s\n' %
2637 ('=' * 75, k, result[k], values[k], '=' * 75), sep='')
2638 failed = True
2639 if failed:
2640 self.fail("result does not equal expected, see print above")
2641
2642 def test_inspect_classify_class_attrs(self):
2643 # indirectly test __objclass__
2644 from inspect import Attribute
2645 values = [
2646 Attribute(name='__class__', kind='data',
2647 defining_class=object, object=EnumMeta),
2648 Attribute(name='__doc__', kind='data',
Ethan Furman48a724f2015-04-11 23:23:06 -07002649 defining_class=self.Color, object='An enumeration.'),
Ethan Furman5875d742013-10-21 20:45:55 -07002650 Attribute(name='__members__', kind='property',
2651 defining_class=EnumMeta, object=EnumMeta.__members__),
2652 Attribute(name='__module__', kind='data',
2653 defining_class=self.Color, object=__name__),
2654 Attribute(name='blue', kind='data',
2655 defining_class=self.Color, object=self.Color.blue),
2656 Attribute(name='green', kind='data',
2657 defining_class=self.Color, object=self.Color.green),
2658 Attribute(name='red', kind='data',
2659 defining_class=self.Color, object=self.Color.red),
2660 Attribute(name='name', kind='data',
2661 defining_class=Enum, object=Enum.__dict__['name']),
2662 Attribute(name='value', kind='data',
2663 defining_class=Enum, object=Enum.__dict__['value']),
2664 ]
2665 values.sort(key=lambda item: item.name)
2666 result = list(inspect.classify_class_attrs(self.Color))
2667 result.sort(key=lambda item: item.name)
2668 failed = False
2669 for v, r in zip(values, result):
2670 if r != v:
2671 print('\n%s\n%s\n%s\n%s\n' % ('=' * 75, r, v, '=' * 75), sep='')
2672 failed = True
2673 if failed:
2674 self.fail("result does not equal expected, see print above")
2675
Martin Panter19e69c52015-11-14 12:46:42 +00002676
2677class MiscTestCase(unittest.TestCase):
2678 def test__all__(self):
2679 support.check__all__(self, enum)
2680
2681
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)6f20bd62016-06-03 19:14:52 +00002682# These are unordered here on purpose to ensure that declaration order
2683# makes no difference.
2684CONVERT_TEST_NAME_D = 5
2685CONVERT_TEST_NAME_C = 5
2686CONVERT_TEST_NAME_B = 5
2687CONVERT_TEST_NAME_A = 5 # This one should sort first.
2688CONVERT_TEST_NAME_E = 5
2689CONVERT_TEST_NAME_F = 5
2690
2691class TestIntEnumConvert(unittest.TestCase):
2692 def test_convert_value_lookup_priority(self):
2693 test_type = enum.IntEnum._convert(
Ethan Furman28cf6632017-01-24 12:12:06 -08002694 'UnittestConvert',
2695 ('test.test_enum', '__main__')[__name__=='__main__'],
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)6f20bd62016-06-03 19:14:52 +00002696 filter=lambda x: x.startswith('CONVERT_TEST_'))
2697 # We don't want the reverse lookup value to vary when there are
2698 # multiple possible names for a given value. It should always
2699 # report the first lexigraphical name in that case.
2700 self.assertEqual(test_type(5).name, 'CONVERT_TEST_NAME_A')
2701
2702 def test_convert(self):
2703 test_type = enum.IntEnum._convert(
Ethan Furman28cf6632017-01-24 12:12:06 -08002704 'UnittestConvert',
2705 ('test.test_enum', '__main__')[__name__=='__main__'],
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)6f20bd62016-06-03 19:14:52 +00002706 filter=lambda x: x.startswith('CONVERT_TEST_'))
2707 # Ensure that test_type has all of the desired names and values.
2708 self.assertEqual(test_type.CONVERT_TEST_NAME_F,
2709 test_type.CONVERT_TEST_NAME_A)
2710 self.assertEqual(test_type.CONVERT_TEST_NAME_B, 5)
2711 self.assertEqual(test_type.CONVERT_TEST_NAME_C, 5)
2712 self.assertEqual(test_type.CONVERT_TEST_NAME_D, 5)
2713 self.assertEqual(test_type.CONVERT_TEST_NAME_E, 5)
2714 # Ensure that test_type only picked up names matching the filter.
2715 self.assertEqual([name for name in dir(test_type)
2716 if name[0:2] not in ('CO', '__')],
2717 [], msg='Names other than CONVERT_TEST_* found.')
2718
2719
Ethan Furman6b3d64a2013-06-14 16:55:46 -07002720if __name__ == '__main__':
2721 unittest.main()