• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import enum
2import inspect
3import pydoc
4import sys
5import unittest
6import threading
7from collections import OrderedDict
8from enum import Enum, IntEnum, EnumMeta, Flag, IntFlag, unique, auto
9from io import StringIO
10from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL
11from test import support
12from test.support import ALWAYS_EQ
13from datetime import timedelta
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# for subclassing tests
122
123class classproperty:
124
125    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
126        self.fget = fget
127        self.fset = fset
128        self.fdel = fdel
129        if doc is None and fget is not None:
130            doc = fget.__doc__
131        self.__doc__ = doc
132
133    def __get__(self, instance, ownerclass):
134        return self.fget(ownerclass)
135
136
137# tests
138
139class TestEnum(unittest.TestCase):
140
141    def setUp(self):
142        class Season(Enum):
143            SPRING = 1
144            SUMMER = 2
145            AUTUMN = 3
146            WINTER = 4
147        self.Season = Season
148
149        class Konstants(float, Enum):
150            E = 2.7182818
151            PI = 3.1415926
152            TAU = 2 * PI
153        self.Konstants = Konstants
154
155        class Grades(IntEnum):
156            A = 5
157            B = 4
158            C = 3
159            D = 2
160            F = 0
161        self.Grades = Grades
162
163        class Directional(str, Enum):
164            EAST = 'east'
165            WEST = 'west'
166            NORTH = 'north'
167            SOUTH = 'south'
168        self.Directional = Directional
169
170        from datetime import date
171        class Holiday(date, Enum):
172            NEW_YEAR = 2013, 1, 1
173            IDES_OF_MARCH = 2013, 3, 15
174        self.Holiday = Holiday
175
176    def test_dir_on_class(self):
177        Season = self.Season
178        self.assertEqual(
179            set(dir(Season)),
180            set(['__class__', '__doc__', '__members__', '__module__',
181                'SPRING', 'SUMMER', 'AUTUMN', 'WINTER']),
182            )
183
184    def test_dir_on_item(self):
185        Season = self.Season
186        self.assertEqual(
187            set(dir(Season.WINTER)),
188            set(['__class__', '__doc__', '__module__', 'name', 'value']),
189            )
190
191    def test_dir_with_added_behavior(self):
192        class Test(Enum):
193            this = 'that'
194            these = 'those'
195            def wowser(self):
196                return ("Wowser! I'm %s!" % self.name)
197        self.assertEqual(
198                set(dir(Test)),
199                set(['__class__', '__doc__', '__members__', '__module__', 'this', 'these']),
200                )
201        self.assertEqual(
202                set(dir(Test.this)),
203                set(['__class__', '__doc__', '__module__', 'name', 'value', 'wowser']),
204                )
205
206    def test_dir_on_sub_with_behavior_on_super(self):
207        # see issue22506
208        class SuperEnum(Enum):
209            def invisible(self):
210                return "did you see me?"
211        class SubEnum(SuperEnum):
212            sample = 5
213        self.assertEqual(
214                set(dir(SubEnum.sample)),
215                set(['__class__', '__doc__', '__module__', 'name', 'value', 'invisible']),
216                )
217
218    def test_dir_on_sub_with_behavior_including_instance_dict_on_super(self):
219        # see issue40084
220        class SuperEnum(IntEnum):
221            def __new__(cls, value, description=""):
222                obj = int.__new__(cls, value)
223                obj._value_ = value
224                obj.description = description
225                return obj
226        class SubEnum(SuperEnum):
227            sample = 5
228        self.assertTrue({'description'} <= set(dir(SubEnum.sample)))
229
230    def test_enum_in_enum_out(self):
231        Season = self.Season
232        self.assertIs(Season(Season.WINTER), Season.WINTER)
233
234    def test_enum_value(self):
235        Season = self.Season
236        self.assertEqual(Season.SPRING.value, 1)
237
238    def test_intenum_value(self):
239        self.assertEqual(IntStooges.CURLY.value, 2)
240
241    def test_enum(self):
242        Season = self.Season
243        lst = list(Season)
244        self.assertEqual(len(lst), len(Season))
245        self.assertEqual(len(Season), 4, Season)
246        self.assertEqual(
247            [Season.SPRING, Season.SUMMER, Season.AUTUMN, Season.WINTER], lst)
248
249        for i, season in enumerate('SPRING SUMMER AUTUMN WINTER'.split(), 1):
250            e = Season(i)
251            self.assertEqual(e, getattr(Season, season))
252            self.assertEqual(e.value, i)
253            self.assertNotEqual(e, i)
254            self.assertEqual(e.name, season)
255            self.assertIn(e, Season)
256            self.assertIs(type(e), Season)
257            self.assertIsInstance(e, Season)
258            self.assertEqual(str(e), 'Season.' + season)
259            self.assertEqual(
260                    repr(e),
261                    '<Season.{0}: {1}>'.format(season, i),
262                    )
263
264    def test_value_name(self):
265        Season = self.Season
266        self.assertEqual(Season.SPRING.name, 'SPRING')
267        self.assertEqual(Season.SPRING.value, 1)
268        with self.assertRaises(AttributeError):
269            Season.SPRING.name = 'invierno'
270        with self.assertRaises(AttributeError):
271            Season.SPRING.value = 2
272
273    def test_changing_member(self):
274        Season = self.Season
275        with self.assertRaises(AttributeError):
276            Season.WINTER = 'really cold'
277
278    def test_attribute_deletion(self):
279        class Season(Enum):
280            SPRING = 1
281            SUMMER = 2
282            AUTUMN = 3
283            WINTER = 4
284
285            def spam(cls):
286                pass
287
288        self.assertTrue(hasattr(Season, 'spam'))
289        del Season.spam
290        self.assertFalse(hasattr(Season, 'spam'))
291
292        with self.assertRaises(AttributeError):
293            del Season.SPRING
294        with self.assertRaises(AttributeError):
295            del Season.DRY
296        with self.assertRaises(AttributeError):
297            del Season.SPRING.name
298
299    def test_bool_of_class(self):
300        class Empty(Enum):
301            pass
302        self.assertTrue(bool(Empty))
303
304    def test_bool_of_member(self):
305        class Count(Enum):
306            zero = 0
307            one = 1
308            two = 2
309        for member in Count:
310            self.assertTrue(bool(member))
311
312    def test_invalid_names(self):
313        with self.assertRaises(ValueError):
314            class Wrong(Enum):
315                mro = 9
316        with self.assertRaises(ValueError):
317            class Wrong(Enum):
318                _create_= 11
319        with self.assertRaises(ValueError):
320            class Wrong(Enum):
321                _get_mixins_ = 9
322        with self.assertRaises(ValueError):
323            class Wrong(Enum):
324                _find_new_ = 1
325        with self.assertRaises(ValueError):
326            class Wrong(Enum):
327                _any_name_ = 9
328
329    def test_bool(self):
330        # plain Enum members are always True
331        class Logic(Enum):
332            true = True
333            false = False
334        self.assertTrue(Logic.true)
335        self.assertTrue(Logic.false)
336        # unless overridden
337        class RealLogic(Enum):
338            true = True
339            false = False
340            def __bool__(self):
341                return bool(self._value_)
342        self.assertTrue(RealLogic.true)
343        self.assertFalse(RealLogic.false)
344        # mixed Enums depend on mixed-in type
345        class IntLogic(int, Enum):
346            true = 1
347            false = 0
348        self.assertTrue(IntLogic.true)
349        self.assertFalse(IntLogic.false)
350
351    def test_contains(self):
352        Season = self.Season
353        self.assertIn(Season.AUTUMN, Season)
354        with self.assertRaises(TypeError):
355            3 in Season
356        with self.assertRaises(TypeError):
357            'AUTUMN' in Season
358
359        val = Season(3)
360        self.assertIn(val, Season)
361
362        class OtherEnum(Enum):
363            one = 1; two = 2
364        self.assertNotIn(OtherEnum.two, Season)
365
366    def test_comparisons(self):
367        Season = self.Season
368        with self.assertRaises(TypeError):
369            Season.SPRING < Season.WINTER
370        with self.assertRaises(TypeError):
371            Season.SPRING > 4
372
373        self.assertNotEqual(Season.SPRING, 1)
374
375        class Part(Enum):
376            SPRING = 1
377            CLIP = 2
378            BARREL = 3
379
380        self.assertNotEqual(Season.SPRING, Part.SPRING)
381        with self.assertRaises(TypeError):
382            Season.SPRING < Part.CLIP
383
384    def test_enum_duplicates(self):
385        class Season(Enum):
386            SPRING = 1
387            SUMMER = 2
388            AUTUMN = FALL = 3
389            WINTER = 4
390            ANOTHER_SPRING = 1
391        lst = list(Season)
392        self.assertEqual(
393            lst,
394            [Season.SPRING, Season.SUMMER,
395             Season.AUTUMN, Season.WINTER,
396            ])
397        self.assertIs(Season.FALL, Season.AUTUMN)
398        self.assertEqual(Season.FALL.value, 3)
399        self.assertEqual(Season.AUTUMN.value, 3)
400        self.assertIs(Season(3), Season.AUTUMN)
401        self.assertIs(Season(1), Season.SPRING)
402        self.assertEqual(Season.FALL.name, 'AUTUMN')
403        self.assertEqual(
404                [k for k,v in Season.__members__.items() if v.name != k],
405                ['FALL', 'ANOTHER_SPRING'],
406                )
407
408    def test_duplicate_name(self):
409        with self.assertRaises(TypeError):
410            class Color(Enum):
411                red = 1
412                green = 2
413                blue = 3
414                red = 4
415
416        with self.assertRaises(TypeError):
417            class Color(Enum):
418                red = 1
419                green = 2
420                blue = 3
421                def red(self):
422                    return 'red'
423
424        with self.assertRaises(TypeError):
425            class Color(Enum):
426                @property
427                def red(self):
428                    return 'redder'
429                red = 1
430                green = 2
431                blue = 3
432
433
434    def test_enum_with_value_name(self):
435        class Huh(Enum):
436            name = 1
437            value = 2
438        self.assertEqual(
439            list(Huh),
440            [Huh.name, Huh.value],
441            )
442        self.assertIs(type(Huh.name), Huh)
443        self.assertEqual(Huh.name.name, 'name')
444        self.assertEqual(Huh.name.value, 1)
445
446    def test_format_enum(self):
447        Season = self.Season
448        self.assertEqual('{}'.format(Season.SPRING),
449                         '{}'.format(str(Season.SPRING)))
450        self.assertEqual( '{:}'.format(Season.SPRING),
451                          '{:}'.format(str(Season.SPRING)))
452        self.assertEqual('{:20}'.format(Season.SPRING),
453                         '{:20}'.format(str(Season.SPRING)))
454        self.assertEqual('{:^20}'.format(Season.SPRING),
455                         '{:^20}'.format(str(Season.SPRING)))
456        self.assertEqual('{:>20}'.format(Season.SPRING),
457                         '{:>20}'.format(str(Season.SPRING)))
458        self.assertEqual('{:<20}'.format(Season.SPRING),
459                         '{:<20}'.format(str(Season.SPRING)))
460
461    def test_str_override_enum(self):
462        class EnumWithStrOverrides(Enum):
463            one = auto()
464            two = auto()
465
466            def __str__(self):
467                return 'Str!'
468        self.assertEqual(str(EnumWithStrOverrides.one), 'Str!')
469        self.assertEqual('{}'.format(EnumWithStrOverrides.one), 'Str!')
470
471    def test_format_override_enum(self):
472        class EnumWithFormatOverride(Enum):
473            one = 1.0
474            two = 2.0
475            def __format__(self, spec):
476                return 'Format!!'
477        self.assertEqual(str(EnumWithFormatOverride.one), 'EnumWithFormatOverride.one')
478        self.assertEqual('{}'.format(EnumWithFormatOverride.one), 'Format!!')
479
480    def test_str_and_format_override_enum(self):
481        class EnumWithStrFormatOverrides(Enum):
482            one = auto()
483            two = auto()
484            def __str__(self):
485                return 'Str!'
486            def __format__(self, spec):
487                return 'Format!'
488        self.assertEqual(str(EnumWithStrFormatOverrides.one), 'Str!')
489        self.assertEqual('{}'.format(EnumWithStrFormatOverrides.one), 'Format!')
490
491    def test_str_override_mixin(self):
492        class MixinEnumWithStrOverride(float, Enum):
493            one = 1.0
494            two = 2.0
495            def __str__(self):
496                return 'Overridden!'
497        self.assertEqual(str(MixinEnumWithStrOverride.one), 'Overridden!')
498        self.assertEqual('{}'.format(MixinEnumWithStrOverride.one), 'Overridden!')
499
500    def test_str_and_format_override_mixin(self):
501        class MixinWithStrFormatOverrides(float, Enum):
502            one = 1.0
503            two = 2.0
504            def __str__(self):
505                return 'Str!'
506            def __format__(self, spec):
507                return 'Format!'
508        self.assertEqual(str(MixinWithStrFormatOverrides.one), 'Str!')
509        self.assertEqual('{}'.format(MixinWithStrFormatOverrides.one), 'Format!')
510
511    def test_format_override_mixin(self):
512        class TestFloat(float, Enum):
513            one = 1.0
514            two = 2.0
515            def __format__(self, spec):
516                return 'TestFloat success!'
517        self.assertEqual(str(TestFloat.one), 'TestFloat.one')
518        self.assertEqual('{}'.format(TestFloat.one), 'TestFloat success!')
519
520    def assertFormatIsValue(self, spec, member):
521        self.assertEqual(spec.format(member), spec.format(member.value))
522
523    def test_format_enum_date(self):
524        Holiday = self.Holiday
525        self.assertFormatIsValue('{}', Holiday.IDES_OF_MARCH)
526        self.assertFormatIsValue('{:}', Holiday.IDES_OF_MARCH)
527        self.assertFormatIsValue('{:20}', Holiday.IDES_OF_MARCH)
528        self.assertFormatIsValue('{:^20}', Holiday.IDES_OF_MARCH)
529        self.assertFormatIsValue('{:>20}', Holiday.IDES_OF_MARCH)
530        self.assertFormatIsValue('{:<20}', Holiday.IDES_OF_MARCH)
531        self.assertFormatIsValue('{:%Y %m}', Holiday.IDES_OF_MARCH)
532        self.assertFormatIsValue('{:%Y %m %M:00}', Holiday.IDES_OF_MARCH)
533
534    def test_format_enum_float(self):
535        Konstants = self.Konstants
536        self.assertFormatIsValue('{}', Konstants.TAU)
537        self.assertFormatIsValue('{:}', Konstants.TAU)
538        self.assertFormatIsValue('{:20}', Konstants.TAU)
539        self.assertFormatIsValue('{:^20}', Konstants.TAU)
540        self.assertFormatIsValue('{:>20}', Konstants.TAU)
541        self.assertFormatIsValue('{:<20}', Konstants.TAU)
542        self.assertFormatIsValue('{:n}', Konstants.TAU)
543        self.assertFormatIsValue('{:5.2}', Konstants.TAU)
544        self.assertFormatIsValue('{:f}', Konstants.TAU)
545
546    def test_format_enum_int(self):
547        Grades = self.Grades
548        self.assertFormatIsValue('{}', Grades.C)
549        self.assertFormatIsValue('{:}', Grades.C)
550        self.assertFormatIsValue('{:20}', Grades.C)
551        self.assertFormatIsValue('{:^20}', Grades.C)
552        self.assertFormatIsValue('{:>20}', Grades.C)
553        self.assertFormatIsValue('{:<20}', Grades.C)
554        self.assertFormatIsValue('{:+}', Grades.C)
555        self.assertFormatIsValue('{:08X}', Grades.C)
556        self.assertFormatIsValue('{:b}', Grades.C)
557
558    def test_format_enum_str(self):
559        Directional = self.Directional
560        self.assertFormatIsValue('{}', Directional.WEST)
561        self.assertFormatIsValue('{:}', Directional.WEST)
562        self.assertFormatIsValue('{:20}', Directional.WEST)
563        self.assertFormatIsValue('{:^20}', Directional.WEST)
564        self.assertFormatIsValue('{:>20}', Directional.WEST)
565        self.assertFormatIsValue('{:<20}', Directional.WEST)
566
567    def test_object_str_override(self):
568        class Colors(Enum):
569            RED, GREEN, BLUE = 1, 2, 3
570            def __repr__(self):
571                return "test.%s" % (self._name_, )
572            __str__ = object.__str__
573        self.assertEqual(str(Colors.RED), 'test.RED')
574
575    def test_enum_str_override(self):
576        class MyStrEnum(Enum):
577            def __str__(self):
578                return 'MyStr'
579        class MyMethodEnum(Enum):
580            def hello(self):
581                return 'Hello!  My name is %s' % self.name
582        class Test1Enum(MyMethodEnum, int, MyStrEnum):
583            One = 1
584            Two = 2
585        self.assertTrue(Test1Enum._member_type_ is int)
586        self.assertEqual(str(Test1Enum.One), 'MyStr')
587        self.assertEqual(format(Test1Enum.One, ''), 'MyStr')
588        #
589        class Test2Enum(MyStrEnum, MyMethodEnum):
590            One = 1
591            Two = 2
592        self.assertEqual(str(Test2Enum.One), 'MyStr')
593        self.assertEqual(format(Test1Enum.One, ''), 'MyStr')
594
595    def test_inherited_data_type(self):
596        class HexInt(int):
597            def __repr__(self):
598                return hex(self)
599        class MyEnum(HexInt, enum.Enum):
600            A = 1
601            B = 2
602            C = 3
603        self.assertEqual(repr(MyEnum.A), '<MyEnum.A: 0x1>')
604
605    def test_too_many_data_types(self):
606        with self.assertRaisesRegex(TypeError, 'too many data types'):
607            class Huh(str, int, Enum):
608                One = 1
609
610        class MyStr(str):
611            def hello(self):
612                return 'hello, %s' % self
613        class MyInt(int):
614            def repr(self):
615                return hex(self)
616        with self.assertRaisesRegex(TypeError, 'too many data types'):
617            class Huh(MyStr, MyInt, Enum):
618                One = 1
619
620    def test_hash(self):
621        Season = self.Season
622        dates = {}
623        dates[Season.WINTER] = '1225'
624        dates[Season.SPRING] = '0315'
625        dates[Season.SUMMER] = '0704'
626        dates[Season.AUTUMN] = '1031'
627        self.assertEqual(dates[Season.AUTUMN], '1031')
628
629    def test_intenum_from_scratch(self):
630        class phy(int, Enum):
631            pi = 3
632            tau = 2 * pi
633        self.assertTrue(phy.pi < phy.tau)
634
635    def test_intenum_inherited(self):
636        class IntEnum(int, Enum):
637            pass
638        class phy(IntEnum):
639            pi = 3
640            tau = 2 * pi
641        self.assertTrue(phy.pi < phy.tau)
642
643    def test_floatenum_from_scratch(self):
644        class phy(float, Enum):
645            pi = 3.1415926
646            tau = 2 * pi
647        self.assertTrue(phy.pi < phy.tau)
648
649    def test_floatenum_inherited(self):
650        class FloatEnum(float, Enum):
651            pass
652        class phy(FloatEnum):
653            pi = 3.1415926
654            tau = 2 * pi
655        self.assertTrue(phy.pi < phy.tau)
656
657    def test_strenum_from_scratch(self):
658        class phy(str, Enum):
659            pi = 'Pi'
660            tau = 'Tau'
661        self.assertTrue(phy.pi < phy.tau)
662
663    def test_strenum_inherited(self):
664        class StrEnum(str, Enum):
665            pass
666        class phy(StrEnum):
667            pi = 'Pi'
668            tau = 'Tau'
669        self.assertTrue(phy.pi < phy.tau)
670
671
672    def test_intenum(self):
673        class WeekDay(IntEnum):
674            SUNDAY = 1
675            MONDAY = 2
676            TUESDAY = 3
677            WEDNESDAY = 4
678            THURSDAY = 5
679            FRIDAY = 6
680            SATURDAY = 7
681
682        self.assertEqual(['a', 'b', 'c'][WeekDay.MONDAY], 'c')
683        self.assertEqual([i for i in range(WeekDay.TUESDAY)], [0, 1, 2])
684
685        lst = list(WeekDay)
686        self.assertEqual(len(lst), len(WeekDay))
687        self.assertEqual(len(WeekDay), 7)
688        target = 'SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY'
689        target = target.split()
690        for i, weekday in enumerate(target, 1):
691            e = WeekDay(i)
692            self.assertEqual(e, i)
693            self.assertEqual(int(e), i)
694            self.assertEqual(e.name, weekday)
695            self.assertIn(e, WeekDay)
696            self.assertEqual(lst.index(e)+1, i)
697            self.assertTrue(0 < e < 8)
698            self.assertIs(type(e), WeekDay)
699            self.assertIsInstance(e, int)
700            self.assertIsInstance(e, Enum)
701
702    def test_intenum_duplicates(self):
703        class WeekDay(IntEnum):
704            SUNDAY = 1
705            MONDAY = 2
706            TUESDAY = TEUSDAY = 3
707            WEDNESDAY = 4
708            THURSDAY = 5
709            FRIDAY = 6
710            SATURDAY = 7
711        self.assertIs(WeekDay.TEUSDAY, WeekDay.TUESDAY)
712        self.assertEqual(WeekDay(3).name, 'TUESDAY')
713        self.assertEqual([k for k,v in WeekDay.__members__.items()
714                if v.name != k], ['TEUSDAY', ])
715
716    def test_intenum_from_bytes(self):
717        self.assertIs(IntStooges.from_bytes(b'\x00\x03', 'big'), IntStooges.MOE)
718        with self.assertRaises(ValueError):
719            IntStooges.from_bytes(b'\x00\x05', 'big')
720
721    def test_floatenum_fromhex(self):
722        h = float.hex(FloatStooges.MOE.value)
723        self.assertIs(FloatStooges.fromhex(h), FloatStooges.MOE)
724        h = float.hex(FloatStooges.MOE.value + 0.01)
725        with self.assertRaises(ValueError):
726            FloatStooges.fromhex(h)
727
728    def test_pickle_enum(self):
729        if isinstance(Stooges, Exception):
730            raise Stooges
731        test_pickle_dump_load(self.assertIs, Stooges.CURLY)
732        test_pickle_dump_load(self.assertIs, Stooges)
733
734    def test_pickle_int(self):
735        if isinstance(IntStooges, Exception):
736            raise IntStooges
737        test_pickle_dump_load(self.assertIs, IntStooges.CURLY)
738        test_pickle_dump_load(self.assertIs, IntStooges)
739
740    def test_pickle_float(self):
741        if isinstance(FloatStooges, Exception):
742            raise FloatStooges
743        test_pickle_dump_load(self.assertIs, FloatStooges.CURLY)
744        test_pickle_dump_load(self.assertIs, FloatStooges)
745
746    def test_pickle_enum_function(self):
747        if isinstance(Answer, Exception):
748            raise Answer
749        test_pickle_dump_load(self.assertIs, Answer.him)
750        test_pickle_dump_load(self.assertIs, Answer)
751
752    def test_pickle_enum_function_with_module(self):
753        if isinstance(Question, Exception):
754            raise Question
755        test_pickle_dump_load(self.assertIs, Question.who)
756        test_pickle_dump_load(self.assertIs, Question)
757
758    def test_enum_function_with_qualname(self):
759        if isinstance(Theory, Exception):
760            raise Theory
761        self.assertEqual(Theory.__qualname__, 'spanish_inquisition')
762
763    def test_class_nested_enum_and_pickle_protocol_four(self):
764        # would normally just have this directly in the class namespace
765        class NestedEnum(Enum):
766            twigs = 'common'
767            shiny = 'rare'
768
769        self.__class__.NestedEnum = NestedEnum
770        self.NestedEnum.__qualname__ = '%s.NestedEnum' % self.__class__.__name__
771        test_pickle_dump_load(self.assertIs, self.NestedEnum.twigs)
772
773    def test_pickle_by_name(self):
774        class ReplaceGlobalInt(IntEnum):
775            ONE = 1
776            TWO = 2
777        ReplaceGlobalInt.__reduce_ex__ = enum._reduce_ex_by_name
778        for proto in range(HIGHEST_PROTOCOL):
779            self.assertEqual(ReplaceGlobalInt.TWO.__reduce_ex__(proto), 'TWO')
780
781    def test_exploding_pickle(self):
782        BadPickle = Enum(
783                'BadPickle', 'dill sweet bread-n-butter', module=__name__)
784        globals()['BadPickle'] = BadPickle
785        # now break BadPickle to test exception raising
786        enum._make_class_unpicklable(BadPickle)
787        test_pickle_exception(self.assertRaises, TypeError, BadPickle.dill)
788        test_pickle_exception(self.assertRaises, PicklingError, BadPickle)
789
790    def test_string_enum(self):
791        class SkillLevel(str, Enum):
792            master = 'what is the sound of one hand clapping?'
793            journeyman = 'why did the chicken cross the road?'
794            apprentice = 'knock, knock!'
795        self.assertEqual(SkillLevel.apprentice, 'knock, knock!')
796
797    def test_getattr_getitem(self):
798        class Period(Enum):
799            morning = 1
800            noon = 2
801            evening = 3
802            night = 4
803        self.assertIs(Period(2), Period.noon)
804        self.assertIs(getattr(Period, 'night'), Period.night)
805        self.assertIs(Period['morning'], Period.morning)
806
807    def test_getattr_dunder(self):
808        Season = self.Season
809        self.assertTrue(getattr(Season, '__eq__'))
810
811    def test_iteration_order(self):
812        class Season(Enum):
813            SUMMER = 2
814            WINTER = 4
815            AUTUMN = 3
816            SPRING = 1
817        self.assertEqual(
818                list(Season),
819                [Season.SUMMER, Season.WINTER, Season.AUTUMN, Season.SPRING],
820                )
821
822    def test_reversed_iteration_order(self):
823        self.assertEqual(
824                list(reversed(self.Season)),
825                [self.Season.WINTER, self.Season.AUTUMN, self.Season.SUMMER,
826                 self.Season.SPRING]
827                )
828
829    def test_programmatic_function_string(self):
830        SummerMonth = Enum('SummerMonth', 'june july august')
831        lst = list(SummerMonth)
832        self.assertEqual(len(lst), len(SummerMonth))
833        self.assertEqual(len(SummerMonth), 3, SummerMonth)
834        self.assertEqual(
835                [SummerMonth.june, SummerMonth.july, SummerMonth.august],
836                lst,
837                )
838        for i, month in enumerate('june july august'.split(), 1):
839            e = SummerMonth(i)
840            self.assertEqual(int(e.value), i)
841            self.assertNotEqual(e, i)
842            self.assertEqual(e.name, month)
843            self.assertIn(e, SummerMonth)
844            self.assertIs(type(e), SummerMonth)
845
846    def test_programmatic_function_string_with_start(self):
847        SummerMonth = Enum('SummerMonth', 'june july august', start=10)
848        lst = list(SummerMonth)
849        self.assertEqual(len(lst), len(SummerMonth))
850        self.assertEqual(len(SummerMonth), 3, SummerMonth)
851        self.assertEqual(
852                [SummerMonth.june, SummerMonth.july, SummerMonth.august],
853                lst,
854                )
855        for i, month in enumerate('june july august'.split(), 10):
856            e = SummerMonth(i)
857            self.assertEqual(int(e.value), i)
858            self.assertNotEqual(e, i)
859            self.assertEqual(e.name, month)
860            self.assertIn(e, SummerMonth)
861            self.assertIs(type(e), SummerMonth)
862
863    def test_programmatic_function_string_list(self):
864        SummerMonth = Enum('SummerMonth', ['june', 'july', 'august'])
865        lst = list(SummerMonth)
866        self.assertEqual(len(lst), len(SummerMonth))
867        self.assertEqual(len(SummerMonth), 3, SummerMonth)
868        self.assertEqual(
869                [SummerMonth.june, SummerMonth.july, SummerMonth.august],
870                lst,
871                )
872        for i, month in enumerate('june july august'.split(), 1):
873            e = SummerMonth(i)
874            self.assertEqual(int(e.value), i)
875            self.assertNotEqual(e, i)
876            self.assertEqual(e.name, month)
877            self.assertIn(e, SummerMonth)
878            self.assertIs(type(e), SummerMonth)
879
880    def test_programmatic_function_string_list_with_start(self):
881        SummerMonth = Enum('SummerMonth', ['june', 'july', 'august'], start=20)
882        lst = list(SummerMonth)
883        self.assertEqual(len(lst), len(SummerMonth))
884        self.assertEqual(len(SummerMonth), 3, SummerMonth)
885        self.assertEqual(
886                [SummerMonth.june, SummerMonth.july, SummerMonth.august],
887                lst,
888                )
889        for i, month in enumerate('june july august'.split(), 20):
890            e = SummerMonth(i)
891            self.assertEqual(int(e.value), i)
892            self.assertNotEqual(e, i)
893            self.assertEqual(e.name, month)
894            self.assertIn(e, SummerMonth)
895            self.assertIs(type(e), SummerMonth)
896
897    def test_programmatic_function_iterable(self):
898        SummerMonth = Enum(
899                'SummerMonth',
900                (('june', 1), ('july', 2), ('august', 3))
901                )
902        lst = list(SummerMonth)
903        self.assertEqual(len(lst), len(SummerMonth))
904        self.assertEqual(len(SummerMonth), 3, SummerMonth)
905        self.assertEqual(
906                [SummerMonth.june, SummerMonth.july, SummerMonth.august],
907                lst,
908                )
909        for i, month in enumerate('june july august'.split(), 1):
910            e = SummerMonth(i)
911            self.assertEqual(int(e.value), i)
912            self.assertNotEqual(e, i)
913            self.assertEqual(e.name, month)
914            self.assertIn(e, SummerMonth)
915            self.assertIs(type(e), SummerMonth)
916
917    def test_programmatic_function_from_dict(self):
918        SummerMonth = Enum(
919                'SummerMonth',
920                OrderedDict((('june', 1), ('july', 2), ('august', 3)))
921                )
922        lst = list(SummerMonth)
923        self.assertEqual(len(lst), len(SummerMonth))
924        self.assertEqual(len(SummerMonth), 3, SummerMonth)
925        self.assertEqual(
926                [SummerMonth.june, SummerMonth.july, SummerMonth.august],
927                lst,
928                )
929        for i, month in enumerate('june july august'.split(), 1):
930            e = SummerMonth(i)
931            self.assertEqual(int(e.value), i)
932            self.assertNotEqual(e, i)
933            self.assertEqual(e.name, month)
934            self.assertIn(e, SummerMonth)
935            self.assertIs(type(e), SummerMonth)
936
937    def test_programmatic_function_type(self):
938        SummerMonth = Enum('SummerMonth', 'june july august', type=int)
939        lst = list(SummerMonth)
940        self.assertEqual(len(lst), len(SummerMonth))
941        self.assertEqual(len(SummerMonth), 3, SummerMonth)
942        self.assertEqual(
943                [SummerMonth.june, SummerMonth.july, SummerMonth.august],
944                lst,
945                )
946        for i, month in enumerate('june july august'.split(), 1):
947            e = SummerMonth(i)
948            self.assertEqual(e, i)
949            self.assertEqual(e.name, month)
950            self.assertIn(e, SummerMonth)
951            self.assertIs(type(e), SummerMonth)
952
953    def test_programmatic_function_type_with_start(self):
954        SummerMonth = Enum('SummerMonth', 'june july august', type=int, start=30)
955        lst = list(SummerMonth)
956        self.assertEqual(len(lst), len(SummerMonth))
957        self.assertEqual(len(SummerMonth), 3, SummerMonth)
958        self.assertEqual(
959                [SummerMonth.june, SummerMonth.july, SummerMonth.august],
960                lst,
961                )
962        for i, month in enumerate('june july august'.split(), 30):
963            e = SummerMonth(i)
964            self.assertEqual(e, i)
965            self.assertEqual(e.name, month)
966            self.assertIn(e, SummerMonth)
967            self.assertIs(type(e), SummerMonth)
968
969    def test_programmatic_function_type_from_subclass(self):
970        SummerMonth = IntEnum('SummerMonth', 'june july august')
971        lst = list(SummerMonth)
972        self.assertEqual(len(lst), len(SummerMonth))
973        self.assertEqual(len(SummerMonth), 3, SummerMonth)
974        self.assertEqual(
975                [SummerMonth.june, SummerMonth.july, SummerMonth.august],
976                lst,
977                )
978        for i, month in enumerate('june july august'.split(), 1):
979            e = SummerMonth(i)
980            self.assertEqual(e, i)
981            self.assertEqual(e.name, month)
982            self.assertIn(e, SummerMonth)
983            self.assertIs(type(e), SummerMonth)
984
985    def test_programmatic_function_type_from_subclass_with_start(self):
986        SummerMonth = IntEnum('SummerMonth', 'june july august', start=40)
987        lst = list(SummerMonth)
988        self.assertEqual(len(lst), len(SummerMonth))
989        self.assertEqual(len(SummerMonth), 3, SummerMonth)
990        self.assertEqual(
991                [SummerMonth.june, SummerMonth.july, SummerMonth.august],
992                lst,
993                )
994        for i, month in enumerate('june july august'.split(), 40):
995            e = SummerMonth(i)
996            self.assertEqual(e, i)
997            self.assertEqual(e.name, month)
998            self.assertIn(e, SummerMonth)
999            self.assertIs(type(e), SummerMonth)
1000
1001    def test_subclassing(self):
1002        if isinstance(Name, Exception):
1003            raise Name
1004        self.assertEqual(Name.BDFL, 'Guido van Rossum')
1005        self.assertTrue(Name.BDFL, Name('Guido van Rossum'))
1006        self.assertIs(Name.BDFL, getattr(Name, 'BDFL'))
1007        test_pickle_dump_load(self.assertIs, Name.BDFL)
1008
1009    def test_extending(self):
1010        class Color(Enum):
1011            red = 1
1012            green = 2
1013            blue = 3
1014        with self.assertRaises(TypeError):
1015            class MoreColor(Color):
1016                cyan = 4
1017                magenta = 5
1018                yellow = 6
1019        with self.assertRaisesRegex(TypeError, "EvenMoreColor: cannot extend enumeration 'Color'"):
1020            class EvenMoreColor(Color, IntEnum):
1021                chartruese = 7
1022
1023    def test_exclude_methods(self):
1024        class whatever(Enum):
1025            this = 'that'
1026            these = 'those'
1027            def really(self):
1028                return 'no, not %s' % self.value
1029        self.assertIsNot(type(whatever.really), whatever)
1030        self.assertEqual(whatever.this.really(), 'no, not that')
1031
1032    def test_wrong_inheritance_order(self):
1033        with self.assertRaises(TypeError):
1034            class Wrong(Enum, str):
1035                NotHere = 'error before this point'
1036
1037    def test_intenum_transitivity(self):
1038        class number(IntEnum):
1039            one = 1
1040            two = 2
1041            three = 3
1042        class numero(IntEnum):
1043            uno = 1
1044            dos = 2
1045            tres = 3
1046        self.assertEqual(number.one, numero.uno)
1047        self.assertEqual(number.two, numero.dos)
1048        self.assertEqual(number.three, numero.tres)
1049
1050    def test_wrong_enum_in_call(self):
1051        class Monochrome(Enum):
1052            black = 0
1053            white = 1
1054        class Gender(Enum):
1055            male = 0
1056            female = 1
1057        self.assertRaises(ValueError, Monochrome, Gender.male)
1058
1059    def test_wrong_enum_in_mixed_call(self):
1060        class Monochrome(IntEnum):
1061            black = 0
1062            white = 1
1063        class Gender(Enum):
1064            male = 0
1065            female = 1
1066        self.assertRaises(ValueError, Monochrome, Gender.male)
1067
1068    def test_mixed_enum_in_call_1(self):
1069        class Monochrome(IntEnum):
1070            black = 0
1071            white = 1
1072        class Gender(IntEnum):
1073            male = 0
1074            female = 1
1075        self.assertIs(Monochrome(Gender.female), Monochrome.white)
1076
1077    def test_mixed_enum_in_call_2(self):
1078        class Monochrome(Enum):
1079            black = 0
1080            white = 1
1081        class Gender(IntEnum):
1082            male = 0
1083            female = 1
1084        self.assertIs(Monochrome(Gender.male), Monochrome.black)
1085
1086    def test_flufl_enum(self):
1087        class Fluflnum(Enum):
1088            def __int__(self):
1089                return int(self.value)
1090        class MailManOptions(Fluflnum):
1091            option1 = 1
1092            option2 = 2
1093            option3 = 3
1094        self.assertEqual(int(MailManOptions.option1), 1)
1095
1096    def test_introspection(self):
1097        class Number(IntEnum):
1098            one = 100
1099            two = 200
1100        self.assertIs(Number.one._member_type_, int)
1101        self.assertIs(Number._member_type_, int)
1102        class String(str, Enum):
1103            yarn = 'soft'
1104            rope = 'rough'
1105            wire = 'hard'
1106        self.assertIs(String.yarn._member_type_, str)
1107        self.assertIs(String._member_type_, str)
1108        class Plain(Enum):
1109            vanilla = 'white'
1110            one = 1
1111        self.assertIs(Plain.vanilla._member_type_, object)
1112        self.assertIs(Plain._member_type_, object)
1113
1114    def test_no_such_enum_member(self):
1115        class Color(Enum):
1116            red = 1
1117            green = 2
1118            blue = 3
1119        with self.assertRaises(ValueError):
1120            Color(4)
1121        with self.assertRaises(KeyError):
1122            Color['chartreuse']
1123
1124    def test_new_repr(self):
1125        class Color(Enum):
1126            red = 1
1127            green = 2
1128            blue = 3
1129            def __repr__(self):
1130                return "don't you just love shades of %s?" % self.name
1131        self.assertEqual(
1132                repr(Color.blue),
1133                "don't you just love shades of blue?",
1134                )
1135
1136    def test_inherited_repr(self):
1137        class MyEnum(Enum):
1138            def __repr__(self):
1139                return "My name is %s." % self.name
1140        class MyIntEnum(int, MyEnum):
1141            this = 1
1142            that = 2
1143            theother = 3
1144        self.assertEqual(repr(MyIntEnum.that), "My name is that.")
1145
1146    def test_multiple_mixin_mro(self):
1147        class auto_enum(type(Enum)):
1148            def __new__(metacls, cls, bases, classdict):
1149                temp = type(classdict)()
1150                temp._cls_name = cls
1151                names = set(classdict._member_names)
1152                i = 0
1153                for k in classdict._member_names:
1154                    v = classdict[k]
1155                    if v is Ellipsis:
1156                        v = i
1157                    else:
1158                        i = v
1159                    i += 1
1160                    temp[k] = v
1161                for k, v in classdict.items():
1162                    if k not in names:
1163                        temp[k] = v
1164                return super(auto_enum, metacls).__new__(
1165                        metacls, cls, bases, temp)
1166
1167        class AutoNumberedEnum(Enum, metaclass=auto_enum):
1168            pass
1169
1170        class AutoIntEnum(IntEnum, metaclass=auto_enum):
1171            pass
1172
1173        class TestAutoNumber(AutoNumberedEnum):
1174            a = ...
1175            b = 3
1176            c = ...
1177
1178        class TestAutoInt(AutoIntEnum):
1179            a = ...
1180            b = 3
1181            c = ...
1182
1183    def test_subclasses_with_getnewargs(self):
1184        class NamedInt(int):
1185            __qualname__ = 'NamedInt'       # needed for pickle protocol 4
1186            def __new__(cls, *args):
1187                _args = args
1188                name, *args = args
1189                if len(args) == 0:
1190                    raise TypeError("name and value must be specified")
1191                self = int.__new__(cls, *args)
1192                self._intname = name
1193                self._args = _args
1194                return self
1195            def __getnewargs__(self):
1196                return self._args
1197            @property
1198            def __name__(self):
1199                return self._intname
1200            def __repr__(self):
1201                # repr() is updated to include the name and type info
1202                return "{}({!r}, {})".format(type(self).__name__,
1203                                             self.__name__,
1204                                             int.__repr__(self))
1205            def __str__(self):
1206                # str() is unchanged, even if it relies on the repr() fallback
1207                base = int
1208                base_str = base.__str__
1209                if base_str.__objclass__ is object:
1210                    return base.__repr__(self)
1211                return base_str(self)
1212            # for simplicity, we only define one operator that
1213            # propagates expressions
1214            def __add__(self, other):
1215                temp = int(self) + int( other)
1216                if isinstance(self, NamedInt) and isinstance(other, NamedInt):
1217                    return NamedInt(
1218                        '({0} + {1})'.format(self.__name__, other.__name__),
1219                        temp )
1220                else:
1221                    return temp
1222
1223        class NEI(NamedInt, Enum):
1224            __qualname__ = 'NEI'      # needed for pickle protocol 4
1225            x = ('the-x', 1)
1226            y = ('the-y', 2)
1227
1228
1229        self.assertIs(NEI.__new__, Enum.__new__)
1230        self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
1231        globals()['NamedInt'] = NamedInt
1232        globals()['NEI'] = NEI
1233        NI5 = NamedInt('test', 5)
1234        self.assertEqual(NI5, 5)
1235        test_pickle_dump_load(self.assertEqual, NI5, 5)
1236        self.assertEqual(NEI.y.value, 2)
1237        test_pickle_dump_load(self.assertIs, NEI.y)
1238        test_pickle_dump_load(self.assertIs, NEI)
1239
1240    def test_subclasses_with_getnewargs_ex(self):
1241        class NamedInt(int):
1242            __qualname__ = 'NamedInt'       # needed for pickle protocol 4
1243            def __new__(cls, *args):
1244                _args = args
1245                name, *args = args
1246                if len(args) == 0:
1247                    raise TypeError("name and value must be specified")
1248                self = int.__new__(cls, *args)
1249                self._intname = name
1250                self._args = _args
1251                return self
1252            def __getnewargs_ex__(self):
1253                return self._args, {}
1254            @property
1255            def __name__(self):
1256                return self._intname
1257            def __repr__(self):
1258                # repr() is updated to include the name and type info
1259                return "{}({!r}, {})".format(type(self).__name__,
1260                                             self.__name__,
1261                                             int.__repr__(self))
1262            def __str__(self):
1263                # str() is unchanged, even if it relies on the repr() fallback
1264                base = int
1265                base_str = base.__str__
1266                if base_str.__objclass__ is object:
1267                    return base.__repr__(self)
1268                return base_str(self)
1269            # for simplicity, we only define one operator that
1270            # propagates expressions
1271            def __add__(self, other):
1272                temp = int(self) + int( other)
1273                if isinstance(self, NamedInt) and isinstance(other, NamedInt):
1274                    return NamedInt(
1275                        '({0} + {1})'.format(self.__name__, other.__name__),
1276                        temp )
1277                else:
1278                    return temp
1279
1280        class NEI(NamedInt, Enum):
1281            __qualname__ = 'NEI'      # needed for pickle protocol 4
1282            x = ('the-x', 1)
1283            y = ('the-y', 2)
1284
1285
1286        self.assertIs(NEI.__new__, Enum.__new__)
1287        self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
1288        globals()['NamedInt'] = NamedInt
1289        globals()['NEI'] = NEI
1290        NI5 = NamedInt('test', 5)
1291        self.assertEqual(NI5, 5)
1292        test_pickle_dump_load(self.assertEqual, NI5, 5)
1293        self.assertEqual(NEI.y.value, 2)
1294        test_pickle_dump_load(self.assertIs, NEI.y)
1295        test_pickle_dump_load(self.assertIs, NEI)
1296
1297    def test_subclasses_with_reduce(self):
1298        class NamedInt(int):
1299            __qualname__ = 'NamedInt'       # needed for pickle protocol 4
1300            def __new__(cls, *args):
1301                _args = args
1302                name, *args = args
1303                if len(args) == 0:
1304                    raise TypeError("name and value must be specified")
1305                self = int.__new__(cls, *args)
1306                self._intname = name
1307                self._args = _args
1308                return self
1309            def __reduce__(self):
1310                return self.__class__, self._args
1311            @property
1312            def __name__(self):
1313                return self._intname
1314            def __repr__(self):
1315                # repr() is updated to include the name and type info
1316                return "{}({!r}, {})".format(type(self).__name__,
1317                                             self.__name__,
1318                                             int.__repr__(self))
1319            def __str__(self):
1320                # str() is unchanged, even if it relies on the repr() fallback
1321                base = int
1322                base_str = base.__str__
1323                if base_str.__objclass__ is object:
1324                    return base.__repr__(self)
1325                return base_str(self)
1326            # for simplicity, we only define one operator that
1327            # propagates expressions
1328            def __add__(self, other):
1329                temp = int(self) + int( other)
1330                if isinstance(self, NamedInt) and isinstance(other, NamedInt):
1331                    return NamedInt(
1332                        '({0} + {1})'.format(self.__name__, other.__name__),
1333                        temp )
1334                else:
1335                    return temp
1336
1337        class NEI(NamedInt, Enum):
1338            __qualname__ = 'NEI'      # needed for pickle protocol 4
1339            x = ('the-x', 1)
1340            y = ('the-y', 2)
1341
1342
1343        self.assertIs(NEI.__new__, Enum.__new__)
1344        self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
1345        globals()['NamedInt'] = NamedInt
1346        globals()['NEI'] = NEI
1347        NI5 = NamedInt('test', 5)
1348        self.assertEqual(NI5, 5)
1349        test_pickle_dump_load(self.assertEqual, NI5, 5)
1350        self.assertEqual(NEI.y.value, 2)
1351        test_pickle_dump_load(self.assertIs, NEI.y)
1352        test_pickle_dump_load(self.assertIs, NEI)
1353
1354    def test_subclasses_with_reduce_ex(self):
1355        class NamedInt(int):
1356            __qualname__ = 'NamedInt'       # needed for pickle protocol 4
1357            def __new__(cls, *args):
1358                _args = args
1359                name, *args = args
1360                if len(args) == 0:
1361                    raise TypeError("name and value must be specified")
1362                self = int.__new__(cls, *args)
1363                self._intname = name
1364                self._args = _args
1365                return self
1366            def __reduce_ex__(self, proto):
1367                return self.__class__, self._args
1368            @property
1369            def __name__(self):
1370                return self._intname
1371            def __repr__(self):
1372                # repr() is updated to include the name and type info
1373                return "{}({!r}, {})".format(type(self).__name__,
1374                                             self.__name__,
1375                                             int.__repr__(self))
1376            def __str__(self):
1377                # str() is unchanged, even if it relies on the repr() fallback
1378                base = int
1379                base_str = base.__str__
1380                if base_str.__objclass__ is object:
1381                    return base.__repr__(self)
1382                return base_str(self)
1383            # for simplicity, we only define one operator that
1384            # propagates expressions
1385            def __add__(self, other):
1386                temp = int(self) + int( other)
1387                if isinstance(self, NamedInt) and isinstance(other, NamedInt):
1388                    return NamedInt(
1389                        '({0} + {1})'.format(self.__name__, other.__name__),
1390                        temp )
1391                else:
1392                    return temp
1393
1394        class NEI(NamedInt, Enum):
1395            __qualname__ = 'NEI'      # needed for pickle protocol 4
1396            x = ('the-x', 1)
1397            y = ('the-y', 2)
1398
1399
1400        self.assertIs(NEI.__new__, Enum.__new__)
1401        self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
1402        globals()['NamedInt'] = NamedInt
1403        globals()['NEI'] = NEI
1404        NI5 = NamedInt('test', 5)
1405        self.assertEqual(NI5, 5)
1406        test_pickle_dump_load(self.assertEqual, NI5, 5)
1407        self.assertEqual(NEI.y.value, 2)
1408        test_pickle_dump_load(self.assertIs, NEI.y)
1409        test_pickle_dump_load(self.assertIs, NEI)
1410
1411    def test_subclasses_without_direct_pickle_support(self):
1412        class NamedInt(int):
1413            __qualname__ = 'NamedInt'
1414            def __new__(cls, *args):
1415                _args = args
1416                name, *args = args
1417                if len(args) == 0:
1418                    raise TypeError("name and value must be specified")
1419                self = int.__new__(cls, *args)
1420                self._intname = name
1421                self._args = _args
1422                return self
1423            @property
1424            def __name__(self):
1425                return self._intname
1426            def __repr__(self):
1427                # repr() is updated to include the name and type info
1428                return "{}({!r}, {})".format(type(self).__name__,
1429                                             self.__name__,
1430                                             int.__repr__(self))
1431            def __str__(self):
1432                # str() is unchanged, even if it relies on the repr() fallback
1433                base = int
1434                base_str = base.__str__
1435                if base_str.__objclass__ is object:
1436                    return base.__repr__(self)
1437                return base_str(self)
1438            # for simplicity, we only define one operator that
1439            # propagates expressions
1440            def __add__(self, other):
1441                temp = int(self) + int( other)
1442                if isinstance(self, NamedInt) and isinstance(other, NamedInt):
1443                    return NamedInt(
1444                        '({0} + {1})'.format(self.__name__, other.__name__),
1445                        temp )
1446                else:
1447                    return temp
1448
1449        class NEI(NamedInt, Enum):
1450            __qualname__ = 'NEI'
1451            x = ('the-x', 1)
1452            y = ('the-y', 2)
1453
1454        self.assertIs(NEI.__new__, Enum.__new__)
1455        self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
1456        globals()['NamedInt'] = NamedInt
1457        globals()['NEI'] = NEI
1458        NI5 = NamedInt('test', 5)
1459        self.assertEqual(NI5, 5)
1460        self.assertEqual(NEI.y.value, 2)
1461        test_pickle_exception(self.assertRaises, TypeError, NEI.x)
1462        test_pickle_exception(self.assertRaises, PicklingError, NEI)
1463
1464    def test_subclasses_without_direct_pickle_support_using_name(self):
1465        class NamedInt(int):
1466            __qualname__ = 'NamedInt'
1467            def __new__(cls, *args):
1468                _args = args
1469                name, *args = args
1470                if len(args) == 0:
1471                    raise TypeError("name and value must be specified")
1472                self = int.__new__(cls, *args)
1473                self._intname = name
1474                self._args = _args
1475                return self
1476            @property
1477            def __name__(self):
1478                return self._intname
1479            def __repr__(self):
1480                # repr() is updated to include the name and type info
1481                return "{}({!r}, {})".format(type(self).__name__,
1482                                             self.__name__,
1483                                             int.__repr__(self))
1484            def __str__(self):
1485                # str() is unchanged, even if it relies on the repr() fallback
1486                base = int
1487                base_str = base.__str__
1488                if base_str.__objclass__ is object:
1489                    return base.__repr__(self)
1490                return base_str(self)
1491            # for simplicity, we only define one operator that
1492            # propagates expressions
1493            def __add__(self, other):
1494                temp = int(self) + int( other)
1495                if isinstance(self, NamedInt) and isinstance(other, NamedInt):
1496                    return NamedInt(
1497                        '({0} + {1})'.format(self.__name__, other.__name__),
1498                        temp )
1499                else:
1500                    return temp
1501
1502        class NEI(NamedInt, Enum):
1503            __qualname__ = 'NEI'
1504            x = ('the-x', 1)
1505            y = ('the-y', 2)
1506            def __reduce_ex__(self, proto):
1507                return getattr, (self.__class__, self._name_)
1508
1509        self.assertIs(NEI.__new__, Enum.__new__)
1510        self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
1511        globals()['NamedInt'] = NamedInt
1512        globals()['NEI'] = NEI
1513        NI5 = NamedInt('test', 5)
1514        self.assertEqual(NI5, 5)
1515        self.assertEqual(NEI.y.value, 2)
1516        test_pickle_dump_load(self.assertIs, NEI.y)
1517        test_pickle_dump_load(self.assertIs, NEI)
1518
1519    def test_tuple_subclass(self):
1520        class SomeTuple(tuple, Enum):
1521            __qualname__ = 'SomeTuple'      # needed for pickle protocol 4
1522            first = (1, 'for the money')
1523            second = (2, 'for the show')
1524            third = (3, 'for the music')
1525        self.assertIs(type(SomeTuple.first), SomeTuple)
1526        self.assertIsInstance(SomeTuple.second, tuple)
1527        self.assertEqual(SomeTuple.third, (3, 'for the music'))
1528        globals()['SomeTuple'] = SomeTuple
1529        test_pickle_dump_load(self.assertIs, SomeTuple.first)
1530
1531    def test_duplicate_values_give_unique_enum_items(self):
1532        class AutoNumber(Enum):
1533            first = ()
1534            second = ()
1535            third = ()
1536            def __new__(cls):
1537                value = len(cls.__members__) + 1
1538                obj = object.__new__(cls)
1539                obj._value_ = value
1540                return obj
1541            def __int__(self):
1542                return int(self._value_)
1543        self.assertEqual(
1544                list(AutoNumber),
1545                [AutoNumber.first, AutoNumber.second, AutoNumber.third],
1546                )
1547        self.assertEqual(int(AutoNumber.second), 2)
1548        self.assertEqual(AutoNumber.third.value, 3)
1549        self.assertIs(AutoNumber(1), AutoNumber.first)
1550
1551    def test_inherited_new_from_enhanced_enum(self):
1552        class AutoNumber(Enum):
1553            def __new__(cls):
1554                value = len(cls.__members__) + 1
1555                obj = object.__new__(cls)
1556                obj._value_ = value
1557                return obj
1558            def __int__(self):
1559                return int(self._value_)
1560        class Color(AutoNumber):
1561            red = ()
1562            green = ()
1563            blue = ()
1564        self.assertEqual(list(Color), [Color.red, Color.green, Color.blue])
1565        self.assertEqual(list(map(int, Color)), [1, 2, 3])
1566
1567    def test_inherited_new_from_mixed_enum(self):
1568        class AutoNumber(IntEnum):
1569            def __new__(cls):
1570                value = len(cls.__members__) + 1
1571                obj = int.__new__(cls, value)
1572                obj._value_ = value
1573                return obj
1574        class Color(AutoNumber):
1575            red = ()
1576            green = ()
1577            blue = ()
1578        self.assertEqual(list(Color), [Color.red, Color.green, Color.blue])
1579        self.assertEqual(list(map(int, Color)), [1, 2, 3])
1580
1581    def test_equality(self):
1582        class OrdinaryEnum(Enum):
1583            a = 1
1584        self.assertEqual(ALWAYS_EQ, OrdinaryEnum.a)
1585        self.assertEqual(OrdinaryEnum.a, ALWAYS_EQ)
1586
1587    def test_ordered_mixin(self):
1588        class OrderedEnum(Enum):
1589            def __ge__(self, other):
1590                if self.__class__ is other.__class__:
1591                    return self._value_ >= other._value_
1592                return NotImplemented
1593            def __gt__(self, other):
1594                if self.__class__ is other.__class__:
1595                    return self._value_ > other._value_
1596                return NotImplemented
1597            def __le__(self, other):
1598                if self.__class__ is other.__class__:
1599                    return self._value_ <= other._value_
1600                return NotImplemented
1601            def __lt__(self, other):
1602                if self.__class__ is other.__class__:
1603                    return self._value_ < other._value_
1604                return NotImplemented
1605        class Grade(OrderedEnum):
1606            A = 5
1607            B = 4
1608            C = 3
1609            D = 2
1610            F = 1
1611        self.assertGreater(Grade.A, Grade.B)
1612        self.assertLessEqual(Grade.F, Grade.C)
1613        self.assertLess(Grade.D, Grade.A)
1614        self.assertGreaterEqual(Grade.B, Grade.B)
1615        self.assertEqual(Grade.B, Grade.B)
1616        self.assertNotEqual(Grade.C, Grade.D)
1617
1618    def test_extending2(self):
1619        class Shade(Enum):
1620            def shade(self):
1621                print(self.name)
1622        class Color(Shade):
1623            red = 1
1624            green = 2
1625            blue = 3
1626        with self.assertRaises(TypeError):
1627            class MoreColor(Color):
1628                cyan = 4
1629                magenta = 5
1630                yellow = 6
1631
1632    def test_extending3(self):
1633        class Shade(Enum):
1634            def shade(self):
1635                return self.name
1636        class Color(Shade):
1637            def hex(self):
1638                return '%s hexlified!' % self.value
1639        class MoreColor(Color):
1640            cyan = 4
1641            magenta = 5
1642            yellow = 6
1643        self.assertEqual(MoreColor.magenta.hex(), '5 hexlified!')
1644
1645    def test_subclass_duplicate_name(self):
1646        class Base(Enum):
1647            def test(self):
1648                pass
1649        class Test(Base):
1650            test = 1
1651        self.assertIs(type(Test.test), Test)
1652
1653    def test_subclass_duplicate_name_dynamic(self):
1654        from types import DynamicClassAttribute
1655        class Base(Enum):
1656            @DynamicClassAttribute
1657            def test(self):
1658                return 'dynamic'
1659        class Test(Base):
1660            test = 1
1661        self.assertEqual(Test.test.test, 'dynamic')
1662
1663    def test_no_duplicates(self):
1664        class UniqueEnum(Enum):
1665            def __init__(self, *args):
1666                cls = self.__class__
1667                if any(self.value == e.value for e in cls):
1668                    a = self.name
1669                    e = cls(self.value).name
1670                    raise ValueError(
1671                            "aliases not allowed in UniqueEnum:  %r --> %r"
1672                            % (a, e)
1673                            )
1674        class Color(UniqueEnum):
1675            red = 1
1676            green = 2
1677            blue = 3
1678        with self.assertRaises(ValueError):
1679            class Color(UniqueEnum):
1680                red = 1
1681                green = 2
1682                blue = 3
1683                grene = 2
1684
1685    def test_init(self):
1686        class Planet(Enum):
1687            MERCURY = (3.303e+23, 2.4397e6)
1688            VENUS   = (4.869e+24, 6.0518e6)
1689            EARTH   = (5.976e+24, 6.37814e6)
1690            MARS    = (6.421e+23, 3.3972e6)
1691            JUPITER = (1.9e+27,   7.1492e7)
1692            SATURN  = (5.688e+26, 6.0268e7)
1693            URANUS  = (8.686e+25, 2.5559e7)
1694            NEPTUNE = (1.024e+26, 2.4746e7)
1695            def __init__(self, mass, radius):
1696                self.mass = mass       # in kilograms
1697                self.radius = radius   # in meters
1698            @property
1699            def surface_gravity(self):
1700                # universal gravitational constant  (m3 kg-1 s-2)
1701                G = 6.67300E-11
1702                return G * self.mass / (self.radius * self.radius)
1703        self.assertEqual(round(Planet.EARTH.surface_gravity, 2), 9.80)
1704        self.assertEqual(Planet.EARTH.value, (5.976e+24, 6.37814e6))
1705
1706    def test_ignore(self):
1707        class Period(timedelta, Enum):
1708            '''
1709            different lengths of time
1710            '''
1711            def __new__(cls, value, period):
1712                obj = timedelta.__new__(cls, value)
1713                obj._value_ = value
1714                obj.period = period
1715                return obj
1716            _ignore_ = 'Period i'
1717            Period = vars()
1718            for i in range(13):
1719                Period['month_%d' % i] = i*30, 'month'
1720            for i in range(53):
1721                Period['week_%d' % i] = i*7, 'week'
1722            for i in range(32):
1723                Period['day_%d' % i] = i, 'day'
1724            OneDay = day_1
1725            OneWeek = week_1
1726            OneMonth = month_1
1727        self.assertFalse(hasattr(Period, '_ignore_'))
1728        self.assertFalse(hasattr(Period, 'Period'))
1729        self.assertFalse(hasattr(Period, 'i'))
1730        self.assertTrue(isinstance(Period.day_1, timedelta))
1731        self.assertTrue(Period.month_1 is Period.day_30)
1732        self.assertTrue(Period.week_4 is Period.day_28)
1733
1734    def test_nonhash_value(self):
1735        class AutoNumberInAList(Enum):
1736            def __new__(cls):
1737                value = [len(cls.__members__) + 1]
1738                obj = object.__new__(cls)
1739                obj._value_ = value
1740                return obj
1741        class ColorInAList(AutoNumberInAList):
1742            red = ()
1743            green = ()
1744            blue = ()
1745        self.assertEqual(list(ColorInAList), [ColorInAList.red, ColorInAList.green, ColorInAList.blue])
1746        for enum, value in zip(ColorInAList, range(3)):
1747            value += 1
1748            self.assertEqual(enum.value, [value])
1749            self.assertIs(ColorInAList([value]), enum)
1750
1751    def test_conflicting_types_resolved_in_new(self):
1752        class LabelledIntEnum(int, Enum):
1753            def __new__(cls, *args):
1754                value, label = args
1755                obj = int.__new__(cls, value)
1756                obj.label = label
1757                obj._value_ = value
1758                return obj
1759
1760        class LabelledList(LabelledIntEnum):
1761            unprocessed = (1, "Unprocessed")
1762            payment_complete = (2, "Payment Complete")
1763
1764        self.assertEqual(list(LabelledList), [LabelledList.unprocessed, LabelledList.payment_complete])
1765        self.assertEqual(LabelledList.unprocessed, 1)
1766        self.assertEqual(LabelledList(1), LabelledList.unprocessed)
1767
1768    def test_auto_number(self):
1769        class Color(Enum):
1770            red = auto()
1771            blue = auto()
1772            green = auto()
1773
1774        self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
1775        self.assertEqual(Color.red.value, 1)
1776        self.assertEqual(Color.blue.value, 2)
1777        self.assertEqual(Color.green.value, 3)
1778
1779    def test_auto_name(self):
1780        class Color(Enum):
1781            def _generate_next_value_(name, start, count, last):
1782                return name
1783            red = auto()
1784            blue = auto()
1785            green = auto()
1786
1787        self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
1788        self.assertEqual(Color.red.value, 'red')
1789        self.assertEqual(Color.blue.value, 'blue')
1790        self.assertEqual(Color.green.value, 'green')
1791
1792    def test_auto_name_inherit(self):
1793        class AutoNameEnum(Enum):
1794            def _generate_next_value_(name, start, count, last):
1795                return name
1796        class Color(AutoNameEnum):
1797            red = auto()
1798            blue = auto()
1799            green = auto()
1800
1801        self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
1802        self.assertEqual(Color.red.value, 'red')
1803        self.assertEqual(Color.blue.value, 'blue')
1804        self.assertEqual(Color.green.value, 'green')
1805
1806    def test_auto_garbage(self):
1807        class Color(Enum):
1808            red = 'red'
1809            blue = auto()
1810        self.assertEqual(Color.blue.value, 1)
1811
1812    def test_auto_garbage_corrected(self):
1813        class Color(Enum):
1814            red = 'red'
1815            blue = 2
1816            green = auto()
1817
1818        self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
1819        self.assertEqual(Color.red.value, 'red')
1820        self.assertEqual(Color.blue.value, 2)
1821        self.assertEqual(Color.green.value, 3)
1822
1823    def test_auto_order(self):
1824        with self.assertRaises(TypeError):
1825            class Color(Enum):
1826                red = auto()
1827                green = auto()
1828                blue = auto()
1829                def _generate_next_value_(name, start, count, last):
1830                    return name
1831
1832    def test_auto_order_wierd(self):
1833        weird_auto = auto()
1834        weird_auto.value = 'pathological case'
1835        class Color(Enum):
1836            red = weird_auto
1837            def _generate_next_value_(name, start, count, last):
1838                return name
1839            blue = auto()
1840        self.assertEqual(list(Color), [Color.red, Color.blue])
1841        self.assertEqual(Color.red.value, 'pathological case')
1842        self.assertEqual(Color.blue.value, 'blue')
1843
1844    def test_duplicate_auto(self):
1845        class Dupes(Enum):
1846            first = primero = auto()
1847            second = auto()
1848            third = auto()
1849        self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes))
1850
1851    def test_default_missing(self):
1852        class Color(Enum):
1853            RED = 1
1854            GREEN = 2
1855            BLUE = 3
1856        try:
1857            Color(7)
1858        except ValueError as exc:
1859            self.assertTrue(exc.__context__ is None)
1860        else:
1861            raise Exception('Exception not raised.')
1862
1863    def test_missing(self):
1864        class Color(Enum):
1865            red = 1
1866            green = 2
1867            blue = 3
1868            @classmethod
1869            def _missing_(cls, item):
1870                if item == 'three':
1871                    return cls.blue
1872                elif item == 'bad return':
1873                    # trigger internal error
1874                    return 5
1875                elif item == 'error out':
1876                    raise ZeroDivisionError
1877                else:
1878                    # trigger not found
1879                    return None
1880        self.assertIs(Color('three'), Color.blue)
1881        try:
1882            Color(7)
1883        except ValueError as exc:
1884            self.assertTrue(exc.__context__ is None)
1885        else:
1886            raise Exception('Exception not raised.')
1887        try:
1888            Color('bad return')
1889        except TypeError as exc:
1890            self.assertTrue(isinstance(exc.__context__, ValueError))
1891        else:
1892            raise Exception('Exception not raised.')
1893        try:
1894            Color('error out')
1895        except ZeroDivisionError as exc:
1896            self.assertTrue(isinstance(exc.__context__, ValueError))
1897        else:
1898            raise Exception('Exception not raised.')
1899
1900    def test_multiple_mixin(self):
1901        class MaxMixin:
1902            @classproperty
1903            def MAX(cls):
1904                max = len(cls)
1905                cls.MAX = max
1906                return max
1907        class StrMixin:
1908            def __str__(self):
1909                return self._name_.lower()
1910        class SomeEnum(Enum):
1911            def behavior(self):
1912                return 'booyah'
1913        class AnotherEnum(Enum):
1914            def behavior(self):
1915                return 'nuhuh!'
1916            def social(self):
1917                return "what's up?"
1918        class Color(MaxMixin, Enum):
1919            RED = auto()
1920            GREEN = auto()
1921            BLUE = auto()
1922        self.assertEqual(Color.RED.value, 1)
1923        self.assertEqual(Color.GREEN.value, 2)
1924        self.assertEqual(Color.BLUE.value, 3)
1925        self.assertEqual(Color.MAX, 3)
1926        self.assertEqual(str(Color.BLUE), 'Color.BLUE')
1927        class Color(MaxMixin, StrMixin, Enum):
1928            RED = auto()
1929            GREEN = auto()
1930            BLUE = auto()
1931        self.assertEqual(Color.RED.value, 1)
1932        self.assertEqual(Color.GREEN.value, 2)
1933        self.assertEqual(Color.BLUE.value, 3)
1934        self.assertEqual(Color.MAX, 3)
1935        self.assertEqual(str(Color.BLUE), 'blue')
1936        class Color(StrMixin, MaxMixin, Enum):
1937            RED = auto()
1938            GREEN = auto()
1939            BLUE = auto()
1940        self.assertEqual(Color.RED.value, 1)
1941        self.assertEqual(Color.GREEN.value, 2)
1942        self.assertEqual(Color.BLUE.value, 3)
1943        self.assertEqual(Color.MAX, 3)
1944        self.assertEqual(str(Color.BLUE), 'blue')
1945        class CoolColor(StrMixin, SomeEnum, Enum):
1946            RED = auto()
1947            GREEN = auto()
1948            BLUE = auto()
1949        self.assertEqual(CoolColor.RED.value, 1)
1950        self.assertEqual(CoolColor.GREEN.value, 2)
1951        self.assertEqual(CoolColor.BLUE.value, 3)
1952        self.assertEqual(str(CoolColor.BLUE), 'blue')
1953        self.assertEqual(CoolColor.RED.behavior(), 'booyah')
1954        class CoolerColor(StrMixin, AnotherEnum, Enum):
1955            RED = auto()
1956            GREEN = auto()
1957            BLUE = auto()
1958        self.assertEqual(CoolerColor.RED.value, 1)
1959        self.assertEqual(CoolerColor.GREEN.value, 2)
1960        self.assertEqual(CoolerColor.BLUE.value, 3)
1961        self.assertEqual(str(CoolerColor.BLUE), 'blue')
1962        self.assertEqual(CoolerColor.RED.behavior(), 'nuhuh!')
1963        self.assertEqual(CoolerColor.RED.social(), "what's up?")
1964        class CoolestColor(StrMixin, SomeEnum, AnotherEnum):
1965            RED = auto()
1966            GREEN = auto()
1967            BLUE = auto()
1968        self.assertEqual(CoolestColor.RED.value, 1)
1969        self.assertEqual(CoolestColor.GREEN.value, 2)
1970        self.assertEqual(CoolestColor.BLUE.value, 3)
1971        self.assertEqual(str(CoolestColor.BLUE), 'blue')
1972        self.assertEqual(CoolestColor.RED.behavior(), 'booyah')
1973        self.assertEqual(CoolestColor.RED.social(), "what's up?")
1974        class ConfusedColor(StrMixin, AnotherEnum, SomeEnum):
1975            RED = auto()
1976            GREEN = auto()
1977            BLUE = auto()
1978        self.assertEqual(ConfusedColor.RED.value, 1)
1979        self.assertEqual(ConfusedColor.GREEN.value, 2)
1980        self.assertEqual(ConfusedColor.BLUE.value, 3)
1981        self.assertEqual(str(ConfusedColor.BLUE), 'blue')
1982        self.assertEqual(ConfusedColor.RED.behavior(), 'nuhuh!')
1983        self.assertEqual(ConfusedColor.RED.social(), "what's up?")
1984        class ReformedColor(StrMixin, IntEnum, SomeEnum, AnotherEnum):
1985            RED = auto()
1986            GREEN = auto()
1987            BLUE = auto()
1988        self.assertEqual(ReformedColor.RED.value, 1)
1989        self.assertEqual(ReformedColor.GREEN.value, 2)
1990        self.assertEqual(ReformedColor.BLUE.value, 3)
1991        self.assertEqual(str(ReformedColor.BLUE), 'blue')
1992        self.assertEqual(ReformedColor.RED.behavior(), 'booyah')
1993        self.assertEqual(ConfusedColor.RED.social(), "what's up?")
1994        self.assertTrue(issubclass(ReformedColor, int))
1995
1996    def test_multiple_inherited_mixin(self):
1997        class StrEnum(str, Enum):
1998            def __new__(cls, *args, **kwargs):
1999                for a in args:
2000                    if not isinstance(a, str):
2001                        raise TypeError("Enumeration '%s' (%s) is not"
2002                                        " a string" % (a, type(a).__name__))
2003                return str.__new__(cls, *args, **kwargs)
2004        @unique
2005        class Decision1(StrEnum):
2006            REVERT = "REVERT"
2007            REVERT_ALL = "REVERT_ALL"
2008            RETRY = "RETRY"
2009        class MyEnum(StrEnum):
2010            pass
2011        @unique
2012        class Decision2(MyEnum):
2013            REVERT = "REVERT"
2014            REVERT_ALL = "REVERT_ALL"
2015            RETRY = "RETRY"
2016
2017    def test_multiple_mixin_inherited(self):
2018        class MyInt(int):
2019            def __new__(cls, value):
2020                return super().__new__(cls, value)
2021
2022        class HexMixin:
2023            def __repr__(self):
2024                return hex(self)
2025
2026        class MyIntEnum(HexMixin, MyInt, enum.Enum):
2027            pass
2028
2029        class Foo(MyIntEnum):
2030            TEST = 1
2031        self.assertTrue(isinstance(Foo.TEST, MyInt))
2032        self.assertEqual(repr(Foo.TEST), "0x1")
2033
2034        class Fee(MyIntEnum):
2035            TEST = 1
2036            def __new__(cls, value):
2037                value += 1
2038                member = int.__new__(cls, value)
2039                member._value_ = value
2040                return member
2041        self.assertEqual(Fee.TEST, 2)
2042
2043    def test_empty_globals(self):
2044        # bpo-35717: sys._getframe(2).f_globals['__name__'] fails with KeyError
2045        # when using compile and exec because f_globals is empty
2046        code = "from enum import Enum; Enum('Animal', 'ANT BEE CAT DOG')"
2047        code = compile(code, "<string>", "exec")
2048        global_ns = {}
2049        local_ls = {}
2050        exec(code, global_ns, local_ls)
2051
2052    @unittest.skipUnless(
2053            sys.version_info[:2] == (3, 9),
2054            'private variables are now normal attributes',
2055            )
2056    def test_warning_for_private_variables(self):
2057        with self.assertWarns(DeprecationWarning):
2058            class Private(Enum):
2059                __corporal = 'Radar'
2060        self.assertEqual(Private._Private__corporal.value, 'Radar')
2061        try:
2062            with self.assertWarns(DeprecationWarning):
2063                class Private(Enum):
2064                    __major_ = 'Hoolihan'
2065        except ValueError:
2066            pass
2067
2068
2069class TestOrder(unittest.TestCase):
2070
2071    def test_same_members(self):
2072        class Color(Enum):
2073            _order_ = 'red green blue'
2074            red = 1
2075            green = 2
2076            blue = 3
2077
2078    def test_same_members_with_aliases(self):
2079        class Color(Enum):
2080            _order_ = 'red green blue'
2081            red = 1
2082            green = 2
2083            blue = 3
2084            verde = green
2085
2086    def test_same_members_wrong_order(self):
2087        with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
2088            class Color(Enum):
2089                _order_ = 'red green blue'
2090                red = 1
2091                blue = 3
2092                green = 2
2093
2094    def test_order_has_extra_members(self):
2095        with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
2096            class Color(Enum):
2097                _order_ = 'red green blue purple'
2098                red = 1
2099                green = 2
2100                blue = 3
2101
2102    def test_order_has_extra_members_with_aliases(self):
2103        with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
2104            class Color(Enum):
2105                _order_ = 'red green blue purple'
2106                red = 1
2107                green = 2
2108                blue = 3
2109                verde = green
2110
2111    def test_enum_has_extra_members(self):
2112        with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
2113            class Color(Enum):
2114                _order_ = 'red green blue'
2115                red = 1
2116                green = 2
2117                blue = 3
2118                purple = 4
2119
2120    def test_enum_has_extra_members_with_aliases(self):
2121        with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
2122            class Color(Enum):
2123                _order_ = 'red green blue'
2124                red = 1
2125                green = 2
2126                blue = 3
2127                purple = 4
2128                verde = green
2129
2130
2131class TestFlag(unittest.TestCase):
2132    """Tests of the Flags."""
2133
2134    class Perm(Flag):
2135        R, W, X = 4, 2, 1
2136
2137    class Open(Flag):
2138        RO = 0
2139        WO = 1
2140        RW = 2
2141        AC = 3
2142        CE = 1<<19
2143
2144    class Color(Flag):
2145        BLACK = 0
2146        RED = 1
2147        GREEN = 2
2148        BLUE = 4
2149        PURPLE = RED|BLUE
2150
2151    def test_str(self):
2152        Perm = self.Perm
2153        self.assertEqual(str(Perm.R), 'Perm.R')
2154        self.assertEqual(str(Perm.W), 'Perm.W')
2155        self.assertEqual(str(Perm.X), 'Perm.X')
2156        self.assertEqual(str(Perm.R | Perm.W), 'Perm.R|W')
2157        self.assertEqual(str(Perm.R | Perm.W | Perm.X), 'Perm.R|W|X')
2158        self.assertEqual(str(Perm(0)), 'Perm.0')
2159        self.assertEqual(str(~Perm.R), 'Perm.W|X')
2160        self.assertEqual(str(~Perm.W), 'Perm.R|X')
2161        self.assertEqual(str(~Perm.X), 'Perm.R|W')
2162        self.assertEqual(str(~(Perm.R | Perm.W)), 'Perm.X')
2163        self.assertEqual(str(~(Perm.R | Perm.W | Perm.X)), 'Perm.0')
2164        self.assertEqual(str(Perm(~0)), 'Perm.R|W|X')
2165
2166        Open = self.Open
2167        self.assertEqual(str(Open.RO), 'Open.RO')
2168        self.assertEqual(str(Open.WO), 'Open.WO')
2169        self.assertEqual(str(Open.AC), 'Open.AC')
2170        self.assertEqual(str(Open.RO | Open.CE), 'Open.CE')
2171        self.assertEqual(str(Open.WO | Open.CE), 'Open.CE|WO')
2172        self.assertEqual(str(~Open.RO), 'Open.CE|AC|RW|WO')
2173        self.assertEqual(str(~Open.WO), 'Open.CE|RW')
2174        self.assertEqual(str(~Open.AC), 'Open.CE')
2175        self.assertEqual(str(~(Open.RO | Open.CE)), 'Open.AC')
2176        self.assertEqual(str(~(Open.WO | Open.CE)), 'Open.RW')
2177
2178    def test_repr(self):
2179        Perm = self.Perm
2180        self.assertEqual(repr(Perm.R), '<Perm.R: 4>')
2181        self.assertEqual(repr(Perm.W), '<Perm.W: 2>')
2182        self.assertEqual(repr(Perm.X), '<Perm.X: 1>')
2183        self.assertEqual(repr(Perm.R | Perm.W), '<Perm.R|W: 6>')
2184        self.assertEqual(repr(Perm.R | Perm.W | Perm.X), '<Perm.R|W|X: 7>')
2185        self.assertEqual(repr(Perm(0)), '<Perm.0: 0>')
2186        self.assertEqual(repr(~Perm.R), '<Perm.W|X: 3>')
2187        self.assertEqual(repr(~Perm.W), '<Perm.R|X: 5>')
2188        self.assertEqual(repr(~Perm.X), '<Perm.R|W: 6>')
2189        self.assertEqual(repr(~(Perm.R | Perm.W)), '<Perm.X: 1>')
2190        self.assertEqual(repr(~(Perm.R | Perm.W | Perm.X)), '<Perm.0: 0>')
2191        self.assertEqual(repr(Perm(~0)), '<Perm.R|W|X: 7>')
2192
2193        Open = self.Open
2194        self.assertEqual(repr(Open.RO), '<Open.RO: 0>')
2195        self.assertEqual(repr(Open.WO), '<Open.WO: 1>')
2196        self.assertEqual(repr(Open.AC), '<Open.AC: 3>')
2197        self.assertEqual(repr(Open.RO | Open.CE), '<Open.CE: 524288>')
2198        self.assertEqual(repr(Open.WO | Open.CE), '<Open.CE|WO: 524289>')
2199        self.assertEqual(repr(~Open.RO), '<Open.CE|AC|RW|WO: 524291>')
2200        self.assertEqual(repr(~Open.WO), '<Open.CE|RW: 524290>')
2201        self.assertEqual(repr(~Open.AC), '<Open.CE: 524288>')
2202        self.assertEqual(repr(~(Open.RO | Open.CE)), '<Open.AC: 3>')
2203        self.assertEqual(repr(~(Open.WO | Open.CE)), '<Open.RW: 2>')
2204
2205    def test_format(self):
2206        Perm = self.Perm
2207        self.assertEqual(format(Perm.R, ''), 'Perm.R')
2208        self.assertEqual(format(Perm.R | Perm.X, ''), 'Perm.R|X')
2209
2210    def test_or(self):
2211        Perm = self.Perm
2212        for i in Perm:
2213            for j in Perm:
2214                self.assertEqual((i | j), Perm(i.value | j.value))
2215                self.assertEqual((i | j).value, i.value | j.value)
2216                self.assertIs(type(i | j), Perm)
2217        for i in Perm:
2218            self.assertIs(i | i, i)
2219        Open = self.Open
2220        self.assertIs(Open.RO | Open.CE, Open.CE)
2221
2222    def test_and(self):
2223        Perm = self.Perm
2224        RW = Perm.R | Perm.W
2225        RX = Perm.R | Perm.X
2226        WX = Perm.W | Perm.X
2227        RWX = Perm.R | Perm.W | Perm.X
2228        values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
2229        for i in values:
2230            for j in values:
2231                self.assertEqual((i & j).value, i.value & j.value)
2232                self.assertIs(type(i & j), Perm)
2233        for i in Perm:
2234            self.assertIs(i & i, i)
2235            self.assertIs(i & RWX, i)
2236            self.assertIs(RWX & i, i)
2237        Open = self.Open
2238        self.assertIs(Open.RO & Open.CE, Open.RO)
2239
2240    def test_xor(self):
2241        Perm = self.Perm
2242        for i in Perm:
2243            for j in Perm:
2244                self.assertEqual((i ^ j).value, i.value ^ j.value)
2245                self.assertIs(type(i ^ j), Perm)
2246        for i in Perm:
2247            self.assertIs(i ^ Perm(0), i)
2248            self.assertIs(Perm(0) ^ i, i)
2249        Open = self.Open
2250        self.assertIs(Open.RO ^ Open.CE, Open.CE)
2251        self.assertIs(Open.CE ^ Open.CE, Open.RO)
2252
2253    def test_invert(self):
2254        Perm = self.Perm
2255        RW = Perm.R | Perm.W
2256        RX = Perm.R | Perm.X
2257        WX = Perm.W | Perm.X
2258        RWX = Perm.R | Perm.W | Perm.X
2259        values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
2260        for i in values:
2261            self.assertIs(type(~i), Perm)
2262            self.assertEqual(~~i, i)
2263        for i in Perm:
2264            self.assertIs(~~i, i)
2265        Open = self.Open
2266        self.assertIs(Open.WO & ~Open.WO, Open.RO)
2267        self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE)
2268
2269    def test_bool(self):
2270        Perm = self.Perm
2271        for f in Perm:
2272            self.assertTrue(f)
2273        Open = self.Open
2274        for f in Open:
2275            self.assertEqual(bool(f.value), bool(f))
2276
2277    def test_programatic_function_string(self):
2278        Perm = Flag('Perm', 'R W X')
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<<i
2285            e = Perm(v)
2286            self.assertEqual(e.value, v)
2287            self.assertEqual(type(e.value), int)
2288            self.assertEqual(e.name, n)
2289            self.assertIn(e, Perm)
2290            self.assertIs(type(e), Perm)
2291
2292    def test_programatic_function_string_with_start(self):
2293        Perm = Flag('Perm', 'R W X', start=8)
2294        lst = list(Perm)
2295        self.assertEqual(len(lst), len(Perm))
2296        self.assertEqual(len(Perm), 3, Perm)
2297        self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2298        for i, n in enumerate('R W X'.split()):
2299            v = 8<<i
2300            e = Perm(v)
2301            self.assertEqual(e.value, v)
2302            self.assertEqual(type(e.value), int)
2303            self.assertEqual(e.name, n)
2304            self.assertIn(e, Perm)
2305            self.assertIs(type(e), Perm)
2306
2307    def test_programatic_function_string_list(self):
2308        Perm = Flag('Perm', ['R', 'W', 'X'])
2309        lst = list(Perm)
2310        self.assertEqual(len(lst), len(Perm))
2311        self.assertEqual(len(Perm), 3, Perm)
2312        self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2313        for i, n in enumerate('R W X'.split()):
2314            v = 1<<i
2315            e = Perm(v)
2316            self.assertEqual(e.value, v)
2317            self.assertEqual(type(e.value), int)
2318            self.assertEqual(e.name, n)
2319            self.assertIn(e, Perm)
2320            self.assertIs(type(e), Perm)
2321
2322    def test_programatic_function_iterable(self):
2323        Perm = Flag('Perm', (('R', 2), ('W', 8), ('X', 32)))
2324        lst = list(Perm)
2325        self.assertEqual(len(lst), len(Perm))
2326        self.assertEqual(len(Perm), 3, Perm)
2327        self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2328        for i, n in enumerate('R W X'.split()):
2329            v = 1<<(2*i+1)
2330            e = Perm(v)
2331            self.assertEqual(e.value, v)
2332            self.assertEqual(type(e.value), int)
2333            self.assertEqual(e.name, n)
2334            self.assertIn(e, Perm)
2335            self.assertIs(type(e), Perm)
2336
2337    def test_programatic_function_from_dict(self):
2338        Perm = Flag('Perm', OrderedDict((('R', 2), ('W', 8), ('X', 32))))
2339        lst = list(Perm)
2340        self.assertEqual(len(lst), len(Perm))
2341        self.assertEqual(len(Perm), 3, Perm)
2342        self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2343        for i, n in enumerate('R W X'.split()):
2344            v = 1<<(2*i+1)
2345            e = Perm(v)
2346            self.assertEqual(e.value, v)
2347            self.assertEqual(type(e.value), int)
2348            self.assertEqual(e.name, n)
2349            self.assertIn(e, Perm)
2350            self.assertIs(type(e), Perm)
2351
2352    def test_pickle(self):
2353        if isinstance(FlagStooges, Exception):
2354            raise FlagStooges
2355        test_pickle_dump_load(self.assertIs, FlagStooges.CURLY|FlagStooges.MOE)
2356        test_pickle_dump_load(self.assertIs, FlagStooges)
2357
2358    def test_contains(self):
2359        Open = self.Open
2360        Color = self.Color
2361        self.assertFalse(Color.BLACK in Open)
2362        self.assertFalse(Open.RO in Color)
2363        with self.assertRaises(TypeError):
2364            'BLACK' in Color
2365        with self.assertRaises(TypeError):
2366            'RO' in Open
2367        with self.assertRaises(TypeError):
2368            1 in Color
2369        with self.assertRaises(TypeError):
2370            1 in Open
2371
2372    def test_member_contains(self):
2373        Perm = self.Perm
2374        R, W, X = Perm
2375        RW = R | W
2376        RX = R | X
2377        WX = W | X
2378        RWX = R | W | X
2379        self.assertTrue(R in RW)
2380        self.assertTrue(R in RX)
2381        self.assertTrue(R in RWX)
2382        self.assertTrue(W in RW)
2383        self.assertTrue(W in WX)
2384        self.assertTrue(W in RWX)
2385        self.assertTrue(X in RX)
2386        self.assertTrue(X in WX)
2387        self.assertTrue(X in RWX)
2388        self.assertFalse(R in WX)
2389        self.assertFalse(W in RX)
2390        self.assertFalse(X in RW)
2391
2392    def test_auto_number(self):
2393        class Color(Flag):
2394            red = auto()
2395            blue = auto()
2396            green = auto()
2397
2398        self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
2399        self.assertEqual(Color.red.value, 1)
2400        self.assertEqual(Color.blue.value, 2)
2401        self.assertEqual(Color.green.value, 4)
2402
2403    def test_auto_number_garbage(self):
2404        with self.assertRaisesRegex(TypeError, 'Invalid Flag value: .not an int.'):
2405            class Color(Flag):
2406                red = 'not an int'
2407                blue = auto()
2408
2409    def test_cascading_failure(self):
2410        class Bizarre(Flag):
2411            c = 3
2412            d = 4
2413            f = 6
2414        # Bizarre.c | Bizarre.d
2415        name = "TestFlag.test_cascading_failure.<locals>.Bizarre"
2416        self.assertRaisesRegex(ValueError, "5 is not a valid " + name, Bizarre, 5)
2417        self.assertRaisesRegex(ValueError, "5 is not a valid " + name, Bizarre, 5)
2418        self.assertRaisesRegex(ValueError, "2 is not a valid " + name, Bizarre, 2)
2419        self.assertRaisesRegex(ValueError, "2 is not a valid " + name, Bizarre, 2)
2420        self.assertRaisesRegex(ValueError, "1 is not a valid " + name, Bizarre, 1)
2421        self.assertRaisesRegex(ValueError, "1 is not a valid " + name, Bizarre, 1)
2422
2423    def test_duplicate_auto(self):
2424        class Dupes(Enum):
2425            first = primero = auto()
2426            second = auto()
2427            third = auto()
2428        self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes))
2429
2430    def test_bizarre(self):
2431        class Bizarre(Flag):
2432            b = 3
2433            c = 4
2434            d = 6
2435        self.assertEqual(repr(Bizarre(7)), '<Bizarre.d|c|b: 7>')
2436
2437    def test_multiple_mixin(self):
2438        class AllMixin:
2439            @classproperty
2440            def ALL(cls):
2441                members = list(cls)
2442                all_value = None
2443                if members:
2444                    all_value = members[0]
2445                    for member in members[1:]:
2446                        all_value |= member
2447                cls.ALL = all_value
2448                return all_value
2449        class StrMixin:
2450            def __str__(self):
2451                return self._name_.lower()
2452        class Color(AllMixin, Flag):
2453            RED = auto()
2454            GREEN = auto()
2455            BLUE = auto()
2456        self.assertEqual(Color.RED.value, 1)
2457        self.assertEqual(Color.GREEN.value, 2)
2458        self.assertEqual(Color.BLUE.value, 4)
2459        self.assertEqual(Color.ALL.value, 7)
2460        self.assertEqual(str(Color.BLUE), 'Color.BLUE')
2461        class Color(AllMixin, StrMixin, Flag):
2462            RED = auto()
2463            GREEN = auto()
2464            BLUE = auto()
2465        self.assertEqual(Color.RED.value, 1)
2466        self.assertEqual(Color.GREEN.value, 2)
2467        self.assertEqual(Color.BLUE.value, 4)
2468        self.assertEqual(Color.ALL.value, 7)
2469        self.assertEqual(str(Color.BLUE), 'blue')
2470        class Color(StrMixin, AllMixin, Flag):
2471            RED = auto()
2472            GREEN = auto()
2473            BLUE = auto()
2474        self.assertEqual(Color.RED.value, 1)
2475        self.assertEqual(Color.GREEN.value, 2)
2476        self.assertEqual(Color.BLUE.value, 4)
2477        self.assertEqual(Color.ALL.value, 7)
2478        self.assertEqual(str(Color.BLUE), 'blue')
2479
2480    @support.reap_threads
2481    def test_unique_composite(self):
2482        # override __eq__ to be identity only
2483        class TestFlag(Flag):
2484            one = auto()
2485            two = auto()
2486            three = auto()
2487            four = auto()
2488            five = auto()
2489            six = auto()
2490            seven = auto()
2491            eight = auto()
2492            def __eq__(self, other):
2493                return self is other
2494            def __hash__(self):
2495                return hash(self._value_)
2496        # have multiple threads competing to complete the composite members
2497        seen = set()
2498        failed = False
2499        def cycle_enum():
2500            nonlocal failed
2501            try:
2502                for i in range(256):
2503                    seen.add(TestFlag(i))
2504            except Exception:
2505                failed = True
2506        threads = [
2507                threading.Thread(target=cycle_enum)
2508                for _ in range(8)
2509                ]
2510        with support.start_threads(threads):
2511            pass
2512        # check that only 248 members were created
2513        self.assertFalse(
2514                failed,
2515                'at least one thread failed while creating composite members')
2516        self.assertEqual(256, len(seen), 'too many composite members created')
2517
2518    def test_init_subclass(self):
2519        class MyEnum(Flag):
2520            def __init_subclass__(cls, **kwds):
2521                super().__init_subclass__(**kwds)
2522                self.assertFalse(cls.__dict__.get('_test', False))
2523                cls._test1 = 'MyEnum'
2524        #
2525        class TheirEnum(MyEnum):
2526            def __init_subclass__(cls, **kwds):
2527                super(TheirEnum, cls).__init_subclass__(**kwds)
2528                cls._test2 = 'TheirEnum'
2529        class WhoseEnum(TheirEnum):
2530            def __init_subclass__(cls, **kwds):
2531                pass
2532        class NoEnum(WhoseEnum):
2533            ONE = 1
2534        self.assertEqual(TheirEnum.__dict__['_test1'], 'MyEnum')
2535        self.assertEqual(WhoseEnum.__dict__['_test1'], 'MyEnum')
2536        self.assertEqual(WhoseEnum.__dict__['_test2'], 'TheirEnum')
2537        self.assertFalse(NoEnum.__dict__.get('_test1', False))
2538        self.assertFalse(NoEnum.__dict__.get('_test2', False))
2539        #
2540        class OurEnum(MyEnum):
2541            def __init_subclass__(cls, **kwds):
2542                cls._test2 = 'OurEnum'
2543        class WhereEnum(OurEnum):
2544            def __init_subclass__(cls, **kwds):
2545                pass
2546        class NeverEnum(WhereEnum):
2547            ONE = 1
2548        self.assertEqual(OurEnum.__dict__['_test1'], 'MyEnum')
2549        self.assertFalse(WhereEnum.__dict__.get('_test1', False))
2550        self.assertEqual(WhereEnum.__dict__['_test2'], 'OurEnum')
2551        self.assertFalse(NeverEnum.__dict__.get('_test1', False))
2552        self.assertFalse(NeverEnum.__dict__.get('_test2', False))
2553
2554
2555class TestIntFlag(unittest.TestCase):
2556    """Tests of the IntFlags."""
2557
2558    class Perm(IntFlag):
2559        X = 1 << 0
2560        W = 1 << 1
2561        R = 1 << 2
2562
2563    class Open(IntFlag):
2564        RO = 0
2565        WO = 1
2566        RW = 2
2567        AC = 3
2568        CE = 1<<19
2569
2570    class Color(IntFlag):
2571        BLACK = 0
2572        RED = 1
2573        GREEN = 2
2574        BLUE = 4
2575        PURPLE = RED|BLUE
2576
2577    def test_type(self):
2578        Perm = self.Perm
2579        self.assertTrue(Perm._member_type_ is int)
2580        Open = self.Open
2581        for f in Perm:
2582            self.assertTrue(isinstance(f, Perm))
2583            self.assertEqual(f, f.value)
2584        self.assertTrue(isinstance(Perm.W | Perm.X, Perm))
2585        self.assertEqual(Perm.W | Perm.X, 3)
2586        for f in Open:
2587            self.assertTrue(isinstance(f, Open))
2588            self.assertEqual(f, f.value)
2589        self.assertTrue(isinstance(Open.WO | Open.RW, Open))
2590        self.assertEqual(Open.WO | Open.RW, 3)
2591
2592
2593    def test_str(self):
2594        Perm = self.Perm
2595        self.assertEqual(str(Perm.R), 'Perm.R')
2596        self.assertEqual(str(Perm.W), 'Perm.W')
2597        self.assertEqual(str(Perm.X), 'Perm.X')
2598        self.assertEqual(str(Perm.R | Perm.W), 'Perm.R|W')
2599        self.assertEqual(str(Perm.R | Perm.W | Perm.X), 'Perm.R|W|X')
2600        self.assertEqual(str(Perm.R | 8), 'Perm.8|R')
2601        self.assertEqual(str(Perm(0)), 'Perm.0')
2602        self.assertEqual(str(Perm(8)), 'Perm.8')
2603        self.assertEqual(str(~Perm.R), 'Perm.W|X')
2604        self.assertEqual(str(~Perm.W), 'Perm.R|X')
2605        self.assertEqual(str(~Perm.X), 'Perm.R|W')
2606        self.assertEqual(str(~(Perm.R | Perm.W)), 'Perm.X')
2607        self.assertEqual(str(~(Perm.R | Perm.W | Perm.X)), 'Perm.-8')
2608        self.assertEqual(str(~(Perm.R | 8)), 'Perm.W|X')
2609        self.assertEqual(str(Perm(~0)), 'Perm.R|W|X')
2610        self.assertEqual(str(Perm(~8)), 'Perm.R|W|X')
2611
2612        Open = self.Open
2613        self.assertEqual(str(Open.RO), 'Open.RO')
2614        self.assertEqual(str(Open.WO), 'Open.WO')
2615        self.assertEqual(str(Open.AC), 'Open.AC')
2616        self.assertEqual(str(Open.RO | Open.CE), 'Open.CE')
2617        self.assertEqual(str(Open.WO | Open.CE), 'Open.CE|WO')
2618        self.assertEqual(str(Open(4)), 'Open.4')
2619        self.assertEqual(str(~Open.RO), 'Open.CE|AC|RW|WO')
2620        self.assertEqual(str(~Open.WO), 'Open.CE|RW')
2621        self.assertEqual(str(~Open.AC), 'Open.CE')
2622        self.assertEqual(str(~(Open.RO | Open.CE)), 'Open.AC|RW|WO')
2623        self.assertEqual(str(~(Open.WO | Open.CE)), 'Open.RW')
2624        self.assertEqual(str(Open(~4)), 'Open.CE|AC|RW|WO')
2625
2626    def test_repr(self):
2627        Perm = self.Perm
2628        self.assertEqual(repr(Perm.R), '<Perm.R: 4>')
2629        self.assertEqual(repr(Perm.W), '<Perm.W: 2>')
2630        self.assertEqual(repr(Perm.X), '<Perm.X: 1>')
2631        self.assertEqual(repr(Perm.R | Perm.W), '<Perm.R|W: 6>')
2632        self.assertEqual(repr(Perm.R | Perm.W | Perm.X), '<Perm.R|W|X: 7>')
2633        self.assertEqual(repr(Perm.R | 8), '<Perm.8|R: 12>')
2634        self.assertEqual(repr(Perm(0)), '<Perm.0: 0>')
2635        self.assertEqual(repr(Perm(8)), '<Perm.8: 8>')
2636        self.assertEqual(repr(~Perm.R), '<Perm.W|X: -5>')
2637        self.assertEqual(repr(~Perm.W), '<Perm.R|X: -3>')
2638        self.assertEqual(repr(~Perm.X), '<Perm.R|W: -2>')
2639        self.assertEqual(repr(~(Perm.R | Perm.W)), '<Perm.X: -7>')
2640        self.assertEqual(repr(~(Perm.R | Perm.W | Perm.X)), '<Perm.-8: -8>')
2641        self.assertEqual(repr(~(Perm.R | 8)), '<Perm.W|X: -13>')
2642        self.assertEqual(repr(Perm(~0)), '<Perm.R|W|X: -1>')
2643        self.assertEqual(repr(Perm(~8)), '<Perm.R|W|X: -9>')
2644
2645        Open = self.Open
2646        self.assertEqual(repr(Open.RO), '<Open.RO: 0>')
2647        self.assertEqual(repr(Open.WO), '<Open.WO: 1>')
2648        self.assertEqual(repr(Open.AC), '<Open.AC: 3>')
2649        self.assertEqual(repr(Open.RO | Open.CE), '<Open.CE: 524288>')
2650        self.assertEqual(repr(Open.WO | Open.CE), '<Open.CE|WO: 524289>')
2651        self.assertEqual(repr(Open(4)), '<Open.4: 4>')
2652        self.assertEqual(repr(~Open.RO), '<Open.CE|AC|RW|WO: -1>')
2653        self.assertEqual(repr(~Open.WO), '<Open.CE|RW: -2>')
2654        self.assertEqual(repr(~Open.AC), '<Open.CE: -4>')
2655        self.assertEqual(repr(~(Open.RO | Open.CE)), '<Open.AC|RW|WO: -524289>')
2656        self.assertEqual(repr(~(Open.WO | Open.CE)), '<Open.RW: -524290>')
2657        self.assertEqual(repr(Open(~4)), '<Open.CE|AC|RW|WO: -5>')
2658
2659    def test_format(self):
2660        Perm = self.Perm
2661        self.assertEqual(format(Perm.R, ''), '4')
2662        self.assertEqual(format(Perm.R | Perm.X, ''), '5')
2663
2664    def test_or(self):
2665        Perm = self.Perm
2666        for i in Perm:
2667            for j in Perm:
2668                self.assertEqual(i | j, i.value | j.value)
2669                self.assertEqual((i | j).value, i.value | j.value)
2670                self.assertIs(type(i | j), Perm)
2671            for j in range(8):
2672                self.assertEqual(i | j, i.value | j)
2673                self.assertEqual((i | j).value, i.value | j)
2674                self.assertIs(type(i | j), Perm)
2675                self.assertEqual(j | i, j | i.value)
2676                self.assertEqual((j | i).value, j | i.value)
2677                self.assertIs(type(j | i), Perm)
2678        for i in Perm:
2679            self.assertIs(i | i, i)
2680            self.assertIs(i | 0, i)
2681            self.assertIs(0 | i, i)
2682        Open = self.Open
2683        self.assertIs(Open.RO | Open.CE, Open.CE)
2684
2685    def test_and(self):
2686        Perm = self.Perm
2687        RW = Perm.R | Perm.W
2688        RX = Perm.R | Perm.X
2689        WX = Perm.W | Perm.X
2690        RWX = Perm.R | Perm.W | Perm.X
2691        values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
2692        for i in values:
2693            for j in values:
2694                self.assertEqual(i & j, i.value & j.value, 'i is %r, j is %r' % (i, j))
2695                self.assertEqual((i & j).value, i.value & j.value, 'i is %r, j is %r' % (i, j))
2696                self.assertIs(type(i & j), Perm, 'i is %r, j is %r' % (i, j))
2697            for j in range(8):
2698                self.assertEqual(i & j, i.value & j)
2699                self.assertEqual((i & j).value, i.value & j)
2700                self.assertIs(type(i & j), Perm)
2701                self.assertEqual(j & i, j & i.value)
2702                self.assertEqual((j & i).value, j & i.value)
2703                self.assertIs(type(j & i), Perm)
2704        for i in Perm:
2705            self.assertIs(i & i, i)
2706            self.assertIs(i & 7, i)
2707            self.assertIs(7 & i, i)
2708        Open = self.Open
2709        self.assertIs(Open.RO & Open.CE, Open.RO)
2710
2711    def test_xor(self):
2712        Perm = self.Perm
2713        for i in Perm:
2714            for j in Perm:
2715                self.assertEqual(i ^ j, i.value ^ j.value)
2716                self.assertEqual((i ^ j).value, i.value ^ j.value)
2717                self.assertIs(type(i ^ j), Perm)
2718            for j in range(8):
2719                self.assertEqual(i ^ j, i.value ^ j)
2720                self.assertEqual((i ^ j).value, i.value ^ j)
2721                self.assertIs(type(i ^ j), Perm)
2722                self.assertEqual(j ^ i, j ^ i.value)
2723                self.assertEqual((j ^ i).value, j ^ i.value)
2724                self.assertIs(type(j ^ i), Perm)
2725        for i in Perm:
2726            self.assertIs(i ^ 0, i)
2727            self.assertIs(0 ^ i, i)
2728        Open = self.Open
2729        self.assertIs(Open.RO ^ Open.CE, Open.CE)
2730        self.assertIs(Open.CE ^ Open.CE, Open.RO)
2731
2732    def test_invert(self):
2733        Perm = self.Perm
2734        RW = Perm.R | Perm.W
2735        RX = Perm.R | Perm.X
2736        WX = Perm.W | Perm.X
2737        RWX = Perm.R | Perm.W | Perm.X
2738        values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
2739        for i in values:
2740            self.assertEqual(~i, ~i.value)
2741            self.assertEqual((~i).value, ~i.value)
2742            self.assertIs(type(~i), Perm)
2743            self.assertEqual(~~i, i)
2744        for i in Perm:
2745            self.assertIs(~~i, i)
2746        Open = self.Open
2747        self.assertIs(Open.WO & ~Open.WO, Open.RO)
2748        self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE)
2749
2750    def test_programatic_function_string(self):
2751        Perm = IntFlag('Perm', 'R W X')
2752        lst = list(Perm)
2753        self.assertEqual(len(lst), len(Perm))
2754        self.assertEqual(len(Perm), 3, Perm)
2755        self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2756        for i, n in enumerate('R W X'.split()):
2757            v = 1<<i
2758            e = Perm(v)
2759            self.assertEqual(e.value, v)
2760            self.assertEqual(type(e.value), int)
2761            self.assertEqual(e, v)
2762            self.assertEqual(e.name, n)
2763            self.assertIn(e, Perm)
2764            self.assertIs(type(e), Perm)
2765
2766    def test_programatic_function_string_with_start(self):
2767        Perm = IntFlag('Perm', 'R W X', start=8)
2768        lst = list(Perm)
2769        self.assertEqual(len(lst), len(Perm))
2770        self.assertEqual(len(Perm), 3, Perm)
2771        self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2772        for i, n in enumerate('R W X'.split()):
2773            v = 8<<i
2774            e = Perm(v)
2775            self.assertEqual(e.value, v)
2776            self.assertEqual(type(e.value), int)
2777            self.assertEqual(e, v)
2778            self.assertEqual(e.name, n)
2779            self.assertIn(e, Perm)
2780            self.assertIs(type(e), Perm)
2781
2782    def test_programatic_function_string_list(self):
2783        Perm = IntFlag('Perm', ['R', 'W', 'X'])
2784        lst = list(Perm)
2785        self.assertEqual(len(lst), len(Perm))
2786        self.assertEqual(len(Perm), 3, Perm)
2787        self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2788        for i, n in enumerate('R W X'.split()):
2789            v = 1<<i
2790            e = Perm(v)
2791            self.assertEqual(e.value, v)
2792            self.assertEqual(type(e.value), int)
2793            self.assertEqual(e, v)
2794            self.assertEqual(e.name, n)
2795            self.assertIn(e, Perm)
2796            self.assertIs(type(e), Perm)
2797
2798    def test_programatic_function_iterable(self):
2799        Perm = IntFlag('Perm', (('R', 2), ('W', 8), ('X', 32)))
2800        lst = list(Perm)
2801        self.assertEqual(len(lst), len(Perm))
2802        self.assertEqual(len(Perm), 3, Perm)
2803        self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2804        for i, n in enumerate('R W X'.split()):
2805            v = 1<<(2*i+1)
2806            e = Perm(v)
2807            self.assertEqual(e.value, v)
2808            self.assertEqual(type(e.value), int)
2809            self.assertEqual(e, v)
2810            self.assertEqual(e.name, n)
2811            self.assertIn(e, Perm)
2812            self.assertIs(type(e), Perm)
2813
2814    def test_programatic_function_from_dict(self):
2815        Perm = IntFlag('Perm', OrderedDict((('R', 2), ('W', 8), ('X', 32))))
2816        lst = list(Perm)
2817        self.assertEqual(len(lst), len(Perm))
2818        self.assertEqual(len(Perm), 3, Perm)
2819        self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
2820        for i, n in enumerate('R W X'.split()):
2821            v = 1<<(2*i+1)
2822            e = Perm(v)
2823            self.assertEqual(e.value, v)
2824            self.assertEqual(type(e.value), int)
2825            self.assertEqual(e, v)
2826            self.assertEqual(e.name, n)
2827            self.assertIn(e, Perm)
2828            self.assertIs(type(e), Perm)
2829
2830
2831    def test_programatic_function_from_empty_list(self):
2832        Perm = enum.IntFlag('Perm', [])
2833        lst = list(Perm)
2834        self.assertEqual(len(lst), len(Perm))
2835        self.assertEqual(len(Perm), 0, Perm)
2836        Thing = enum.Enum('Thing', [])
2837        lst = list(Thing)
2838        self.assertEqual(len(lst), len(Thing))
2839        self.assertEqual(len(Thing), 0, Thing)
2840
2841
2842    def test_programatic_function_from_empty_tuple(self):
2843        Perm = enum.IntFlag('Perm', ())
2844        lst = list(Perm)
2845        self.assertEqual(len(lst), len(Perm))
2846        self.assertEqual(len(Perm), 0, Perm)
2847        Thing = enum.Enum('Thing', ())
2848        self.assertEqual(len(lst), len(Thing))
2849        self.assertEqual(len(Thing), 0, Thing)
2850
2851    def test_contains(self):
2852        Open = self.Open
2853        Color = self.Color
2854        self.assertTrue(Color.GREEN in Color)
2855        self.assertTrue(Open.RW in Open)
2856        self.assertFalse(Color.GREEN in Open)
2857        self.assertFalse(Open.RW in Color)
2858        with self.assertRaises(TypeError):
2859            'GREEN' in Color
2860        with self.assertRaises(TypeError):
2861            'RW' in Open
2862        with self.assertRaises(TypeError):
2863            2 in Color
2864        with self.assertRaises(TypeError):
2865            2 in Open
2866
2867    def test_member_contains(self):
2868        Perm = self.Perm
2869        R, W, X = Perm
2870        RW = R | W
2871        RX = R | X
2872        WX = W | X
2873        RWX = R | W | X
2874        self.assertTrue(R in RW)
2875        self.assertTrue(R in RX)
2876        self.assertTrue(R in RWX)
2877        self.assertTrue(W in RW)
2878        self.assertTrue(W in WX)
2879        self.assertTrue(W in RWX)
2880        self.assertTrue(X in RX)
2881        self.assertTrue(X in WX)
2882        self.assertTrue(X in RWX)
2883        self.assertFalse(R in WX)
2884        self.assertFalse(W in RX)
2885        self.assertFalse(X in RW)
2886        with self.assertRaises(TypeError):
2887            self.assertFalse('test' in RW)
2888
2889    def test_bool(self):
2890        Perm = self.Perm
2891        for f in Perm:
2892            self.assertTrue(f)
2893        Open = self.Open
2894        for f in Open:
2895            self.assertEqual(bool(f.value), bool(f))
2896
2897    def test_multiple_mixin(self):
2898        class AllMixin:
2899            @classproperty
2900            def ALL(cls):
2901                members = list(cls)
2902                all_value = None
2903                if members:
2904                    all_value = members[0]
2905                    for member in members[1:]:
2906                        all_value |= member
2907                cls.ALL = all_value
2908                return all_value
2909        class StrMixin:
2910            def __str__(self):
2911                return self._name_.lower()
2912        class Color(AllMixin, IntFlag):
2913            RED = auto()
2914            GREEN = auto()
2915            BLUE = auto()
2916        self.assertEqual(Color.RED.value, 1)
2917        self.assertEqual(Color.GREEN.value, 2)
2918        self.assertEqual(Color.BLUE.value, 4)
2919        self.assertEqual(Color.ALL.value, 7)
2920        self.assertEqual(str(Color.BLUE), 'Color.BLUE')
2921        class Color(AllMixin, StrMixin, IntFlag):
2922            RED = auto()
2923            GREEN = auto()
2924            BLUE = auto()
2925        self.assertEqual(Color.RED.value, 1)
2926        self.assertEqual(Color.GREEN.value, 2)
2927        self.assertEqual(Color.BLUE.value, 4)
2928        self.assertEqual(Color.ALL.value, 7)
2929        self.assertEqual(str(Color.BLUE), 'blue')
2930        class Color(StrMixin, AllMixin, IntFlag):
2931            RED = auto()
2932            GREEN = auto()
2933            BLUE = auto()
2934        self.assertEqual(Color.RED.value, 1)
2935        self.assertEqual(Color.GREEN.value, 2)
2936        self.assertEqual(Color.BLUE.value, 4)
2937        self.assertEqual(Color.ALL.value, 7)
2938        self.assertEqual(str(Color.BLUE), 'blue')
2939
2940    @support.reap_threads
2941    def test_unique_composite(self):
2942        # override __eq__ to be identity only
2943        class TestFlag(IntFlag):
2944            one = auto()
2945            two = auto()
2946            three = auto()
2947            four = auto()
2948            five = auto()
2949            six = auto()
2950            seven = auto()
2951            eight = auto()
2952            def __eq__(self, other):
2953                return self is other
2954            def __hash__(self):
2955                return hash(self._value_)
2956        # have multiple threads competing to complete the composite members
2957        seen = set()
2958        failed = False
2959        def cycle_enum():
2960            nonlocal failed
2961            try:
2962                for i in range(256):
2963                    seen.add(TestFlag(i))
2964            except Exception:
2965                failed = True
2966        threads = [
2967                threading.Thread(target=cycle_enum)
2968                for _ in range(8)
2969                ]
2970        with support.start_threads(threads):
2971            pass
2972        # check that only 248 members were created
2973        self.assertFalse(
2974                failed,
2975                'at least one thread failed while creating composite members')
2976        self.assertEqual(256, len(seen), 'too many composite members created')
2977
2978
2979class TestEmptyAndNonLatinStrings(unittest.TestCase):
2980
2981    def test_empty_string(self):
2982        with self.assertRaises(ValueError):
2983            empty_abc = Enum('empty_abc', ('', 'B', 'C'))
2984
2985    def test_non_latin_character_string(self):
2986        greek_abc = Enum('greek_abc', ('\u03B1', 'B', 'C'))
2987        item = getattr(greek_abc, '\u03B1')
2988        self.assertEqual(item.value, 1)
2989
2990    def test_non_latin_number_string(self):
2991        hebrew_123 = Enum('hebrew_123', ('\u05D0', '2', '3'))
2992        item = getattr(hebrew_123, '\u05D0')
2993        self.assertEqual(item.value, 1)
2994
2995
2996class TestUnique(unittest.TestCase):
2997
2998    def test_unique_clean(self):
2999        @unique
3000        class Clean(Enum):
3001            one = 1
3002            two = 'dos'
3003            tres = 4.0
3004        @unique
3005        class Cleaner(IntEnum):
3006            single = 1
3007            double = 2
3008            triple = 3
3009
3010    def test_unique_dirty(self):
3011        with self.assertRaisesRegex(ValueError, 'tres.*one'):
3012            @unique
3013            class Dirty(Enum):
3014                one = 1
3015                two = 'dos'
3016                tres = 1
3017        with self.assertRaisesRegex(
3018                ValueError,
3019                'double.*single.*turkey.*triple',
3020                ):
3021            @unique
3022            class Dirtier(IntEnum):
3023                single = 1
3024                double = 1
3025                triple = 3
3026                turkey = 3
3027
3028    def test_unique_with_name(self):
3029        @unique
3030        class Silly(Enum):
3031            one = 1
3032            two = 'dos'
3033            name = 3
3034        @unique
3035        class Sillier(IntEnum):
3036            single = 1
3037            name = 2
3038            triple = 3
3039            value = 4
3040
3041
3042
3043expected_help_output_with_docs = """\
3044Help on class Color in module %s:
3045
3046class Color(enum.Enum)
3047 |  Color(value, names=None, *, module=None, qualname=None, type=None, start=1)
3048 |\x20\x20
3049 |  An enumeration.
3050 |\x20\x20
3051 |  Method resolution order:
3052 |      Color
3053 |      enum.Enum
3054 |      builtins.object
3055 |\x20\x20
3056 |  Data and other attributes defined here:
3057 |\x20\x20
3058 |  blue = <Color.blue: 3>
3059 |\x20\x20
3060 |  green = <Color.green: 2>
3061 |\x20\x20
3062 |  red = <Color.red: 1>
3063 |\x20\x20
3064 |  ----------------------------------------------------------------------
3065 |  Data descriptors inherited from enum.Enum:
3066 |\x20\x20
3067 |  name
3068 |      The name of the Enum member.
3069 |\x20\x20
3070 |  value
3071 |      The value of the Enum member.
3072 |\x20\x20
3073 |  ----------------------------------------------------------------------
3074 |  Readonly properties inherited from enum.EnumMeta:
3075 |\x20\x20
3076 |  __members__
3077 |      Returns a mapping of member name->value.
3078 |\x20\x20\x20\x20\x20\x20
3079 |      This mapping lists all enum members, including aliases. Note that this
3080 |      is a read-only view of the internal mapping."""
3081
3082expected_help_output_without_docs = """\
3083Help on class Color in module %s:
3084
3085class Color(enum.Enum)
3086 |  Color(value, names=None, *, module=None, qualname=None, type=None, start=1)
3087 |\x20\x20
3088 |  Method resolution order:
3089 |      Color
3090 |      enum.Enum
3091 |      builtins.object
3092 |\x20\x20
3093 |  Data and other attributes defined here:
3094 |\x20\x20
3095 |  blue = <Color.blue: 3>
3096 |\x20\x20
3097 |  green = <Color.green: 2>
3098 |\x20\x20
3099 |  red = <Color.red: 1>
3100 |\x20\x20
3101 |  ----------------------------------------------------------------------
3102 |  Data descriptors inherited from enum.Enum:
3103 |\x20\x20
3104 |  name
3105 |\x20\x20
3106 |  value
3107 |\x20\x20
3108 |  ----------------------------------------------------------------------
3109 |  Data descriptors inherited from enum.EnumMeta:
3110 |\x20\x20
3111 |  __members__"""
3112
3113class TestStdLib(unittest.TestCase):
3114
3115    maxDiff = None
3116
3117    class Color(Enum):
3118        red = 1
3119        green = 2
3120        blue = 3
3121
3122    def test_pydoc(self):
3123        # indirectly test __objclass__
3124        if StrEnum.__doc__ is None:
3125            expected_text = expected_help_output_without_docs % __name__
3126        else:
3127            expected_text = expected_help_output_with_docs % __name__
3128        output = StringIO()
3129        helper = pydoc.Helper(output=output)
3130        helper(self.Color)
3131        result = output.getvalue().strip()
3132        self.assertEqual(result, expected_text)
3133
3134    def test_inspect_getmembers(self):
3135        values = dict((
3136                ('__class__', EnumMeta),
3137                ('__doc__', 'An enumeration.'),
3138                ('__members__', self.Color.__members__),
3139                ('__module__', __name__),
3140                ('blue', self.Color.blue),
3141                ('green', self.Color.green),
3142                ('name', Enum.__dict__['name']),
3143                ('red', self.Color.red),
3144                ('value', Enum.__dict__['value']),
3145                ))
3146        result = dict(inspect.getmembers(self.Color))
3147        self.assertEqual(values.keys(), result.keys())
3148        failed = False
3149        for k in values.keys():
3150            if result[k] != values[k]:
3151                print()
3152                print('\n%s\n     key: %s\n  result: %s\nexpected: %s\n%s\n' %
3153                        ('=' * 75, k, result[k], values[k], '=' * 75), sep='')
3154                failed = True
3155        if failed:
3156            self.fail("result does not equal expected, see print above")
3157
3158    def test_inspect_classify_class_attrs(self):
3159        # indirectly test __objclass__
3160        from inspect import Attribute
3161        values = [
3162                Attribute(name='__class__', kind='data',
3163                    defining_class=object, object=EnumMeta),
3164                Attribute(name='__doc__', kind='data',
3165                    defining_class=self.Color, object='An enumeration.'),
3166                Attribute(name='__members__', kind='property',
3167                    defining_class=EnumMeta, object=EnumMeta.__members__),
3168                Attribute(name='__module__', kind='data',
3169                    defining_class=self.Color, object=__name__),
3170                Attribute(name='blue', kind='data',
3171                    defining_class=self.Color, object=self.Color.blue),
3172                Attribute(name='green', kind='data',
3173                    defining_class=self.Color, object=self.Color.green),
3174                Attribute(name='red', kind='data',
3175                    defining_class=self.Color, object=self.Color.red),
3176                Attribute(name='name', kind='data',
3177                    defining_class=Enum, object=Enum.__dict__['name']),
3178                Attribute(name='value', kind='data',
3179                    defining_class=Enum, object=Enum.__dict__['value']),
3180                ]
3181        values.sort(key=lambda item: item.name)
3182        result = list(inspect.classify_class_attrs(self.Color))
3183        result.sort(key=lambda item: item.name)
3184        failed = False
3185        for v, r in zip(values, result):
3186            if r != v:
3187                print('\n%s\n%s\n%s\n%s\n' % ('=' * 75, r, v, '=' * 75), sep='')
3188                failed = True
3189        if failed:
3190            self.fail("result does not equal expected, see print above")
3191
3192
3193class MiscTestCase(unittest.TestCase):
3194    def test__all__(self):
3195        support.check__all__(self, enum)
3196
3197
3198# These are unordered here on purpose to ensure that declaration order
3199# makes no difference.
3200CONVERT_TEST_NAME_D = 5
3201CONVERT_TEST_NAME_C = 5
3202CONVERT_TEST_NAME_B = 5
3203CONVERT_TEST_NAME_A = 5  # This one should sort first.
3204CONVERT_TEST_NAME_E = 5
3205CONVERT_TEST_NAME_F = 5
3206
3207class TestIntEnumConvert(unittest.TestCase):
3208    def test_convert_value_lookup_priority(self):
3209        test_type = enum.IntEnum._convert_(
3210                'UnittestConvert',
3211                ('test.test_enum', '__main__')[__name__=='__main__'],
3212                filter=lambda x: x.startswith('CONVERT_TEST_'))
3213        # We don't want the reverse lookup value to vary when there are
3214        # multiple possible names for a given value.  It should always
3215        # report the first lexigraphical name in that case.
3216        self.assertEqual(test_type(5).name, 'CONVERT_TEST_NAME_A')
3217
3218    def test_convert(self):
3219        test_type = enum.IntEnum._convert_(
3220                'UnittestConvert',
3221                ('test.test_enum', '__main__')[__name__=='__main__'],
3222                filter=lambda x: x.startswith('CONVERT_TEST_'))
3223        # Ensure that test_type has all of the desired names and values.
3224        self.assertEqual(test_type.CONVERT_TEST_NAME_F,
3225                         test_type.CONVERT_TEST_NAME_A)
3226        self.assertEqual(test_type.CONVERT_TEST_NAME_B, 5)
3227        self.assertEqual(test_type.CONVERT_TEST_NAME_C, 5)
3228        self.assertEqual(test_type.CONVERT_TEST_NAME_D, 5)
3229        self.assertEqual(test_type.CONVERT_TEST_NAME_E, 5)
3230        # Ensure that test_type only picked up names matching the filter.
3231        self.assertEqual([name for name in dir(test_type)
3232                          if name[0:2] not in ('CO', '__')],
3233                         [], msg='Names other than CONVERT_TEST_* found.')
3234
3235    @unittest.skipUnless(sys.version_info[:2] == (3, 8),
3236                         '_convert was deprecated in 3.8')
3237    def test_convert_warn(self):
3238        with self.assertWarns(DeprecationWarning):
3239            enum.IntEnum._convert(
3240                'UnittestConvert',
3241                ('test.test_enum', '__main__')[__name__=='__main__'],
3242                filter=lambda x: x.startswith('CONVERT_TEST_'))
3243
3244    @unittest.skipUnless(sys.version_info >= (3, 9),
3245                         '_convert was removed in 3.9')
3246    def test_convert_raise(self):
3247        with self.assertRaises(AttributeError):
3248            enum.IntEnum._convert(
3249                'UnittestConvert',
3250                ('test.test_enum', '__main__')[__name__=='__main__'],
3251                filter=lambda x: x.startswith('CONVERT_TEST_'))
3252
3253
3254if __name__ == '__main__':
3255    unittest.main()
3256