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