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