test.py 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820
  1. from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL
  2. import sys
  3. import unittest
  4. pyver = float('%s.%s' % sys.version_info[:2])
  5. if pyver < 2.5:
  6. sys.path.insert(0, '.')
  7. import enum
  8. from enum import Enum, IntEnum, unique, EnumMeta
  9. if pyver < 2.6:
  10. from __builtin__ import enumerate as bltin_enumerate
  11. def enumerate(thing, start=0):
  12. result = []
  13. for i, item in bltin_enumerate(thing):
  14. i = i + start
  15. result.append((i, item))
  16. return result
  17. try:
  18. any
  19. except NameError:
  20. def any(iterable):
  21. for element in iterable:
  22. if element:
  23. return True
  24. return False
  25. try:
  26. unicode
  27. except NameError:
  28. unicode = str
  29. try:
  30. from collections import OrderedDict
  31. except ImportError:
  32. OrderedDict = None
  33. # for pickle tests
  34. try:
  35. class Stooges(Enum):
  36. LARRY = 1
  37. CURLY = 2
  38. MOE = 3
  39. except Exception:
  40. Stooges = sys.exc_info()[1]
  41. try:
  42. class IntStooges(int, Enum):
  43. LARRY = 1
  44. CURLY = 2
  45. MOE = 3
  46. except Exception:
  47. IntStooges = sys.exc_info()[1]
  48. try:
  49. class FloatStooges(float, Enum):
  50. LARRY = 1.39
  51. CURLY = 2.72
  52. MOE = 3.142596
  53. except Exception:
  54. FloatStooges = sys.exc_info()[1]
  55. # for pickle test and subclass tests
  56. try:
  57. class StrEnum(str, Enum):
  58. 'accepts only string values'
  59. class Name(StrEnum):
  60. BDFL = 'Guido van Rossum'
  61. FLUFL = 'Barry Warsaw'
  62. except Exception:
  63. Name = sys.exc_info()[1]
  64. try:
  65. Question = Enum('Question', 'who what when where why', module=__name__)
  66. except Exception:
  67. Question = sys.exc_info()[1]
  68. try:
  69. Answer = Enum('Answer', 'him this then there because')
  70. except Exception:
  71. Answer = sys.exc_info()[1]
  72. try:
  73. Theory = Enum('Theory', 'rule law supposition', qualname='spanish_inquisition')
  74. except Exception:
  75. Theory = sys.exc_info()[1]
  76. # for doctests
  77. try:
  78. class Fruit(Enum):
  79. tomato = 1
  80. banana = 2
  81. cherry = 3
  82. except Exception:
  83. pass
  84. def test_pickle_dump_load(assertion, source, target=None,
  85. protocol=(0, HIGHEST_PROTOCOL)):
  86. start, stop = protocol
  87. failures = []
  88. for protocol in range(start, stop+1):
  89. try:
  90. if target is None:
  91. assertion(loads(dumps(source, protocol=protocol)) is source)
  92. else:
  93. assertion(loads(dumps(source, protocol=protocol)), target)
  94. except Exception:
  95. exc, tb = sys.exc_info()[1:]
  96. failures.append('%2d: %s' %(protocol, exc))
  97. if failures:
  98. raise ValueError('Failed with protocols: %s' % ', '.join(failures))
  99. def test_pickle_exception(assertion, exception, obj,
  100. protocol=(0, HIGHEST_PROTOCOL)):
  101. start, stop = protocol
  102. failures = []
  103. for protocol in range(start, stop+1):
  104. try:
  105. assertion(exception, dumps, obj, protocol=protocol)
  106. except Exception:
  107. exc = sys.exc_info()[1]
  108. failures.append('%d: %s %s' % (protocol, exc.__class__.__name__, exc))
  109. if failures:
  110. raise ValueError('Failed with protocols: %s' % ', '.join(failures))
  111. class TestHelpers(unittest.TestCase):
  112. # _is_descriptor, _is_sunder, _is_dunder
  113. def test_is_descriptor(self):
  114. class foo:
  115. pass
  116. for attr in ('__get__','__set__','__delete__'):
  117. obj = foo()
  118. self.assertFalse(enum._is_descriptor(obj))
  119. setattr(obj, attr, 1)
  120. self.assertTrue(enum._is_descriptor(obj))
  121. def test_is_sunder(self):
  122. for s in ('_a_', '_aa_'):
  123. self.assertTrue(enum._is_sunder(s))
  124. for s in ('a', 'a_', '_a', '__a', 'a__', '__a__', '_a__', '__a_', '_',
  125. '__', '___', '____', '_____',):
  126. self.assertFalse(enum._is_sunder(s))
  127. def test_is_dunder(self):
  128. for s in ('__a__', '__aa__'):
  129. self.assertTrue(enum._is_dunder(s))
  130. for s in ('a', 'a_', '_a', '__a', 'a__', '_a_', '_a__', '__a_', '_',
  131. '__', '___', '____', '_____',):
  132. self.assertFalse(enum._is_dunder(s))
  133. class TestEnum(unittest.TestCase):
  134. def setUp(self):
  135. class Season(Enum):
  136. SPRING = 1
  137. SUMMER = 2
  138. AUTUMN = 3
  139. WINTER = 4
  140. self.Season = Season
  141. class Konstants(float, Enum):
  142. E = 2.7182818
  143. PI = 3.1415926
  144. TAU = 2 * PI
  145. self.Konstants = Konstants
  146. class Grades(IntEnum):
  147. A = 5
  148. B = 4
  149. C = 3
  150. D = 2
  151. F = 0
  152. self.Grades = Grades
  153. class Directional(str, Enum):
  154. EAST = 'east'
  155. WEST = 'west'
  156. NORTH = 'north'
  157. SOUTH = 'south'
  158. self.Directional = Directional
  159. from datetime import date
  160. class Holiday(date, Enum):
  161. NEW_YEAR = 2013, 1, 1
  162. IDES_OF_MARCH = 2013, 3, 15
  163. self.Holiday = Holiday
  164. if pyver >= 3.0: # do not specify custom `dir` on previous versions
  165. def test_dir_on_class(self):
  166. Season = self.Season
  167. self.assertEqual(
  168. set(dir(Season)),
  169. set(['__class__', '__doc__', '__members__', '__module__',
  170. 'SPRING', 'SUMMER', 'AUTUMN', 'WINTER']),
  171. )
  172. def test_dir_on_item(self):
  173. Season = self.Season
  174. self.assertEqual(
  175. set(dir(Season.WINTER)),
  176. set(['__class__', '__doc__', '__module__', 'name', 'value']),
  177. )
  178. def test_dir_with_added_behavior(self):
  179. class Test(Enum):
  180. this = 'that'
  181. these = 'those'
  182. def wowser(self):
  183. return ("Wowser! I'm %s!" % self.name)
  184. self.assertEqual(
  185. set(dir(Test)),
  186. set(['__class__', '__doc__', '__members__', '__module__', 'this', 'these']),
  187. )
  188. self.assertEqual(
  189. set(dir(Test.this)),
  190. set(['__class__', '__doc__', '__module__', 'name', 'value', 'wowser']),
  191. )
  192. def test_dir_on_sub_with_behavior_on_super(self):
  193. # see issue22506
  194. class SuperEnum(Enum):
  195. def invisible(self):
  196. return "did you see me?"
  197. class SubEnum(SuperEnum):
  198. sample = 5
  199. self.assertEqual(
  200. set(dir(SubEnum.sample)),
  201. set(['__class__', '__doc__', '__module__', 'name', 'value', 'invisible']),
  202. )
  203. if pyver >= 2.7: # OrderedDict first available here
  204. def test_members_is_ordereddict_if_ordered(self):
  205. class Ordered(Enum):
  206. __order__ = 'first second third'
  207. first = 'bippity'
  208. second = 'boppity'
  209. third = 'boo'
  210. self.assertTrue(type(Ordered.__members__) is OrderedDict)
  211. def test_members_is_ordereddict_if_not_ordered(self):
  212. class Unordered(Enum):
  213. this = 'that'
  214. these = 'those'
  215. self.assertTrue(type(Unordered.__members__) is OrderedDict)
  216. if pyver >= 3.0: # all objects are ordered in Python 2.x
  217. def test_members_is_always_ordered(self):
  218. class AlwaysOrdered(Enum):
  219. first = 1
  220. second = 2
  221. third = 3
  222. self.assertTrue(type(AlwaysOrdered.__members__) is OrderedDict)
  223. def test_comparisons(self):
  224. def bad_compare():
  225. Season.SPRING > 4
  226. Season = self.Season
  227. self.assertNotEqual(Season.SPRING, 1)
  228. self.assertRaises(TypeError, bad_compare)
  229. class Part(Enum):
  230. SPRING = 1
  231. CLIP = 2
  232. BARREL = 3
  233. self.assertNotEqual(Season.SPRING, Part.SPRING)
  234. def bad_compare():
  235. Season.SPRING < Part.CLIP
  236. self.assertRaises(TypeError, bad_compare)
  237. def test_enum_in_enum_out(self):
  238. Season = self.Season
  239. self.assertTrue(Season(Season.WINTER) is Season.WINTER)
  240. def test_enum_value(self):
  241. Season = self.Season
  242. self.assertEqual(Season.SPRING.value, 1)
  243. def test_intenum_value(self):
  244. self.assertEqual(IntStooges.CURLY.value, 2)
  245. def test_enum(self):
  246. Season = self.Season
  247. lst = list(Season)
  248. self.assertEqual(len(lst), len(Season))
  249. self.assertEqual(len(Season), 4, Season)
  250. self.assertEqual(
  251. [Season.SPRING, Season.SUMMER, Season.AUTUMN, Season.WINTER], lst)
  252. for i, season in enumerate('SPRING SUMMER AUTUMN WINTER'.split()):
  253. i += 1
  254. e = Season(i)
  255. self.assertEqual(e, getattr(Season, season))
  256. self.assertEqual(e.value, i)
  257. self.assertNotEqual(e, i)
  258. self.assertEqual(e.name, season)
  259. self.assertTrue(e in Season)
  260. self.assertTrue(type(e) is Season)
  261. self.assertTrue(isinstance(e, Season))
  262. self.assertEqual(str(e), 'Season.' + season)
  263. self.assertEqual(
  264. repr(e),
  265. '<Season.%s: %s>' % (season, i),
  266. )
  267. def test_value_name(self):
  268. Season = self.Season
  269. self.assertEqual(Season.SPRING.name, 'SPRING')
  270. self.assertEqual(Season.SPRING.value, 1)
  271. def set_name(obj, new_value):
  272. obj.name = new_value
  273. def set_value(obj, new_value):
  274. obj.value = new_value
  275. self.assertRaises(AttributeError, set_name, Season.SPRING, 'invierno', )
  276. self.assertRaises(AttributeError, set_value, Season.SPRING, 2)
  277. def test_attribute_deletion(self):
  278. class Season(Enum):
  279. SPRING = 1
  280. SUMMER = 2
  281. AUTUMN = 3
  282. WINTER = 4
  283. def spam(cls):
  284. pass
  285. self.assertTrue(hasattr(Season, 'spam'))
  286. del Season.spam
  287. self.assertFalse(hasattr(Season, 'spam'))
  288. self.assertRaises(AttributeError, delattr, Season, 'SPRING')
  289. self.assertRaises(AttributeError, delattr, Season, 'DRY')
  290. self.assertRaises(AttributeError, delattr, Season.SPRING, 'name')
  291. def test_bool_of_class(self):
  292. class Empty(Enum):
  293. pass
  294. self.assertTrue(bool(Empty))
  295. def test_bool_of_member(self):
  296. class Count(Enum):
  297. zero = 0
  298. one = 1
  299. two = 2
  300. for member in Count:
  301. self.assertTrue(bool(member))
  302. def test_invalid_names(self):
  303. def create_bad_class_1():
  304. class Wrong(Enum):
  305. mro = 9
  306. def create_bad_class_2():
  307. class Wrong(Enum):
  308. _reserved_ = 3
  309. self.assertRaises(ValueError, create_bad_class_1)
  310. self.assertRaises(ValueError, create_bad_class_2)
  311. def test_contains(self):
  312. Season = self.Season
  313. self.assertTrue(Season.AUTUMN in Season)
  314. self.assertTrue(3 not in Season)
  315. val = Season(3)
  316. self.assertTrue(val in Season)
  317. class OtherEnum(Enum):
  318. one = 1; two = 2
  319. self.assertTrue(OtherEnum.two not in Season)
  320. if pyver >= 2.6: # when `format` came into being
  321. def test_format_enum(self):
  322. Season = self.Season
  323. self.assertEqual('{0}'.format(Season.SPRING),
  324. '{0}'.format(str(Season.SPRING)))
  325. self.assertEqual( '{0:}'.format(Season.SPRING),
  326. '{0:}'.format(str(Season.SPRING)))
  327. self.assertEqual('{0:20}'.format(Season.SPRING),
  328. '{0:20}'.format(str(Season.SPRING)))
  329. self.assertEqual('{0:^20}'.format(Season.SPRING),
  330. '{0:^20}'.format(str(Season.SPRING)))
  331. self.assertEqual('{0:>20}'.format(Season.SPRING),
  332. '{0:>20}'.format(str(Season.SPRING)))
  333. self.assertEqual('{0:<20}'.format(Season.SPRING),
  334. '{0:<20}'.format(str(Season.SPRING)))
  335. def test_format_enum_custom(self):
  336. class TestFloat(float, Enum):
  337. one = 1.0
  338. two = 2.0
  339. def __format__(self, spec):
  340. return 'TestFloat success!'
  341. self.assertEqual('{0}'.format(TestFloat.one), 'TestFloat success!')
  342. def assertFormatIsValue(self, spec, member):
  343. self.assertEqual(spec.format(member), spec.format(member.value))
  344. def test_format_enum_date(self):
  345. Holiday = self.Holiday
  346. self.assertFormatIsValue('{0}', Holiday.IDES_OF_MARCH)
  347. self.assertFormatIsValue('{0:}', Holiday.IDES_OF_MARCH)
  348. self.assertFormatIsValue('{0:20}', Holiday.IDES_OF_MARCH)
  349. self.assertFormatIsValue('{0:^20}', Holiday.IDES_OF_MARCH)
  350. self.assertFormatIsValue('{0:>20}', Holiday.IDES_OF_MARCH)
  351. self.assertFormatIsValue('{0:<20}', Holiday.IDES_OF_MARCH)
  352. self.assertFormatIsValue('{0:%Y %m}', Holiday.IDES_OF_MARCH)
  353. self.assertFormatIsValue('{0:%Y %m %M:00}', Holiday.IDES_OF_MARCH)
  354. def test_format_enum_float(self):
  355. Konstants = self.Konstants
  356. self.assertFormatIsValue('{0}', Konstants.TAU)
  357. self.assertFormatIsValue('{0:}', Konstants.TAU)
  358. self.assertFormatIsValue('{0:20}', Konstants.TAU)
  359. self.assertFormatIsValue('{0:^20}', Konstants.TAU)
  360. self.assertFormatIsValue('{0:>20}', Konstants.TAU)
  361. self.assertFormatIsValue('{0:<20}', Konstants.TAU)
  362. self.assertFormatIsValue('{0:n}', Konstants.TAU)
  363. self.assertFormatIsValue('{0:5.2}', Konstants.TAU)
  364. self.assertFormatIsValue('{0:f}', Konstants.TAU)
  365. def test_format_enum_int(self):
  366. Grades = self.Grades
  367. self.assertFormatIsValue('{0}', Grades.C)
  368. self.assertFormatIsValue('{0:}', Grades.C)
  369. self.assertFormatIsValue('{0:20}', Grades.C)
  370. self.assertFormatIsValue('{0:^20}', Grades.C)
  371. self.assertFormatIsValue('{0:>20}', Grades.C)
  372. self.assertFormatIsValue('{0:<20}', Grades.C)
  373. self.assertFormatIsValue('{0:+}', Grades.C)
  374. self.assertFormatIsValue('{0:08X}', Grades.C)
  375. self.assertFormatIsValue('{0:b}', Grades.C)
  376. def test_format_enum_str(self):
  377. Directional = self.Directional
  378. self.assertFormatIsValue('{0}', Directional.WEST)
  379. self.assertFormatIsValue('{0:}', Directional.WEST)
  380. self.assertFormatIsValue('{0:20}', Directional.WEST)
  381. self.assertFormatIsValue('{0:^20}', Directional.WEST)
  382. self.assertFormatIsValue('{0:>20}', Directional.WEST)
  383. self.assertFormatIsValue('{0:<20}', Directional.WEST)
  384. def test_hash(self):
  385. Season = self.Season
  386. dates = {}
  387. dates[Season.WINTER] = '1225'
  388. dates[Season.SPRING] = '0315'
  389. dates[Season.SUMMER] = '0704'
  390. dates[Season.AUTUMN] = '1031'
  391. self.assertEqual(dates[Season.AUTUMN], '1031')
  392. def test_enum_duplicates(self):
  393. _order_ = "SPRING SUMMER AUTUMN WINTER"
  394. class Season(Enum):
  395. SPRING = 1
  396. SUMMER = 2
  397. AUTUMN = FALL = 3
  398. WINTER = 4
  399. ANOTHER_SPRING = 1
  400. lst = list(Season)
  401. self.assertEqual(
  402. lst,
  403. [Season.SPRING, Season.SUMMER,
  404. Season.AUTUMN, Season.WINTER,
  405. ])
  406. self.assertTrue(Season.FALL is Season.AUTUMN)
  407. self.assertEqual(Season.FALL.value, 3)
  408. self.assertEqual(Season.AUTUMN.value, 3)
  409. self.assertTrue(Season(3) is Season.AUTUMN)
  410. self.assertTrue(Season(1) is Season.SPRING)
  411. self.assertEqual(Season.FALL.name, 'AUTUMN')
  412. self.assertEqual(
  413. set([k for k,v in Season.__members__.items() if v.name != k]),
  414. set(['FALL', 'ANOTHER_SPRING']),
  415. )
  416. if pyver >= 3.0:
  417. cls = vars()
  418. result = {'Enum':Enum}
  419. exec("""def test_duplicate_name(self):
  420. with self.assertRaises(TypeError):
  421. class Color(Enum):
  422. red = 1
  423. green = 2
  424. blue = 3
  425. red = 4
  426. with self.assertRaises(TypeError):
  427. class Color(Enum):
  428. red = 1
  429. green = 2
  430. blue = 3
  431. def red(self):
  432. return 'red'
  433. with self.assertRaises(TypeError):
  434. class Color(Enum):
  435. @property
  436. def red(self):
  437. return 'redder'
  438. red = 1
  439. green = 2
  440. blue = 3""",
  441. result)
  442. cls['test_duplicate_name'] = result['test_duplicate_name']
  443. def test_enum_with_value_name(self):
  444. class Huh(Enum):
  445. name = 1
  446. value = 2
  447. self.assertEqual(
  448. list(Huh),
  449. [Huh.name, Huh.value],
  450. )
  451. self.assertTrue(type(Huh.name) is Huh)
  452. self.assertEqual(Huh.name.name, 'name')
  453. self.assertEqual(Huh.name.value, 1)
  454. def test_intenum_from_scratch(self):
  455. class phy(int, Enum):
  456. pi = 3
  457. tau = 2 * pi
  458. self.assertTrue(phy.pi < phy.tau)
  459. def test_intenum_inherited(self):
  460. class IntEnum(int, Enum):
  461. pass
  462. class phy(IntEnum):
  463. pi = 3
  464. tau = 2 * pi
  465. self.assertTrue(phy.pi < phy.tau)
  466. def test_floatenum_from_scratch(self):
  467. class phy(float, Enum):
  468. pi = 3.1415926
  469. tau = 2 * pi
  470. self.assertTrue(phy.pi < phy.tau)
  471. def test_floatenum_inherited(self):
  472. class FloatEnum(float, Enum):
  473. pass
  474. class phy(FloatEnum):
  475. pi = 3.1415926
  476. tau = 2 * pi
  477. self.assertTrue(phy.pi < phy.tau)
  478. def test_strenum_from_scratch(self):
  479. class phy(str, Enum):
  480. pi = 'Pi'
  481. tau = 'Tau'
  482. self.assertTrue(phy.pi < phy.tau)
  483. def test_strenum_inherited(self):
  484. class StrEnum(str, Enum):
  485. pass
  486. class phy(StrEnum):
  487. pi = 'Pi'
  488. tau = 'Tau'
  489. self.assertTrue(phy.pi < phy.tau)
  490. def test_intenum(self):
  491. class WeekDay(IntEnum):
  492. SUNDAY = 1
  493. MONDAY = 2
  494. TUESDAY = 3
  495. WEDNESDAY = 4
  496. THURSDAY = 5
  497. FRIDAY = 6
  498. SATURDAY = 7
  499. self.assertEqual(['a', 'b', 'c'][WeekDay.MONDAY], 'c')
  500. self.assertEqual([i for i in range(WeekDay.TUESDAY)], [0, 1, 2])
  501. lst = list(WeekDay)
  502. self.assertEqual(len(lst), len(WeekDay))
  503. self.assertEqual(len(WeekDay), 7)
  504. target = 'SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY'
  505. target = target.split()
  506. for i, weekday in enumerate(target):
  507. i += 1
  508. e = WeekDay(i)
  509. self.assertEqual(e, i)
  510. self.assertEqual(int(e), i)
  511. self.assertEqual(e.name, weekday)
  512. self.assertTrue(e in WeekDay)
  513. self.assertEqual(lst.index(e)+1, i)
  514. self.assertTrue(0 < e < 8)
  515. self.assertTrue(type(e) is WeekDay)
  516. self.assertTrue(isinstance(e, int))
  517. self.assertTrue(isinstance(e, Enum))
  518. def test_intenum_duplicates(self):
  519. class WeekDay(IntEnum):
  520. __order__ = 'SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY'
  521. SUNDAY = 1
  522. MONDAY = 2
  523. TUESDAY = TEUSDAY = 3
  524. WEDNESDAY = 4
  525. THURSDAY = 5
  526. FRIDAY = 6
  527. SATURDAY = 7
  528. self.assertTrue(WeekDay.TEUSDAY is WeekDay.TUESDAY)
  529. self.assertEqual(WeekDay(3).name, 'TUESDAY')
  530. self.assertEqual([k for k,v in WeekDay.__members__.items()
  531. if v.name != k], ['TEUSDAY', ])
  532. def test_pickle_enum(self):
  533. if isinstance(Stooges, Exception):
  534. raise Stooges
  535. test_pickle_dump_load(self.assertTrue, Stooges.CURLY)
  536. test_pickle_dump_load(self.assertTrue, Stooges)
  537. def test_pickle_int(self):
  538. if isinstance(IntStooges, Exception):
  539. raise IntStooges
  540. test_pickle_dump_load(self.assertTrue, IntStooges.CURLY)
  541. test_pickle_dump_load(self.assertTrue, IntStooges)
  542. def test_pickle_float(self):
  543. if isinstance(FloatStooges, Exception):
  544. raise FloatStooges
  545. test_pickle_dump_load(self.assertTrue, FloatStooges.CURLY)
  546. test_pickle_dump_load(self.assertTrue, FloatStooges)
  547. def test_pickle_enum_function(self):
  548. if isinstance(Answer, Exception):
  549. raise Answer
  550. test_pickle_dump_load(self.assertTrue, Answer.him)
  551. test_pickle_dump_load(self.assertTrue, Answer)
  552. def test_pickle_enum_function_with_module(self):
  553. if isinstance(Question, Exception):
  554. raise Question
  555. test_pickle_dump_load(self.assertTrue, Question.who)
  556. test_pickle_dump_load(self.assertTrue, Question)
  557. if pyver == 3.4:
  558. def test_class_nested_enum_and_pickle_protocol_four(self):
  559. # would normally just have this directly in the class namespace
  560. class NestedEnum(Enum):
  561. twigs = 'common'
  562. shiny = 'rare'
  563. self.__class__.NestedEnum = NestedEnum
  564. self.NestedEnum.__qualname__ = '%s.NestedEnum' % self.__class__.__name__
  565. test_pickle_exception(
  566. self.assertRaises, PicklingError, self.NestedEnum.twigs,
  567. protocol=(0, 3))
  568. test_pickle_dump_load(self.assertTrue, self.NestedEnum.twigs,
  569. protocol=(4, HIGHEST_PROTOCOL))
  570. elif pyver == 3.5:
  571. def test_class_nested_enum_and_pickle_protocol_four(self):
  572. # would normally just have this directly in the class namespace
  573. class NestedEnum(Enum):
  574. twigs = 'common'
  575. shiny = 'rare'
  576. self.__class__.NestedEnum = NestedEnum
  577. self.NestedEnum.__qualname__ = '%s.NestedEnum' % self.__class__.__name__
  578. test_pickle_dump_load(self.assertTrue, self.NestedEnum.twigs,
  579. protocol=(0, HIGHEST_PROTOCOL))
  580. def test_exploding_pickle(self):
  581. BadPickle = Enum('BadPickle', 'dill sweet bread-n-butter')
  582. enum._make_class_unpicklable(BadPickle)
  583. globals()['BadPickle'] = BadPickle
  584. test_pickle_exception(self.assertRaises, TypeError, BadPickle.dill)
  585. test_pickle_exception(self.assertRaises, PicklingError, BadPickle)
  586. def test_string_enum(self):
  587. class SkillLevel(str, Enum):
  588. master = 'what is the sound of one hand clapping?'
  589. journeyman = 'why did the chicken cross the road?'
  590. apprentice = 'knock, knock!'
  591. self.assertEqual(SkillLevel.apprentice, 'knock, knock!')
  592. def test_getattr_getitem(self):
  593. class Period(Enum):
  594. morning = 1
  595. noon = 2
  596. evening = 3
  597. night = 4
  598. self.assertTrue(Period(2) is Period.noon)
  599. self.assertTrue(getattr(Period, 'night') is Period.night)
  600. self.assertTrue(Period['morning'] is Period.morning)
  601. def test_getattr_dunder(self):
  602. Season = self.Season
  603. self.assertTrue(getattr(Season, '__hash__'))
  604. def test_iteration_order(self):
  605. class Season(Enum):
  606. _order_ = 'SUMMER WINTER AUTUMN SPRING'
  607. SUMMER = 2
  608. WINTER = 4
  609. AUTUMN = 3
  610. SPRING = 1
  611. self.assertEqual(
  612. list(Season),
  613. [Season.SUMMER, Season.WINTER, Season.AUTUMN, Season.SPRING],
  614. )
  615. def test_iteration_order_reversed(self):
  616. self.assertEqual(
  617. list(reversed(self.Season)),
  618. [self.Season.WINTER, self.Season.AUTUMN, self.Season.SUMMER,
  619. self.Season.SPRING]
  620. )
  621. def test_iteration_order_with_unorderable_values(self):
  622. class Complex(Enum):
  623. a = complex(7, 9)
  624. b = complex(3.14, 2)
  625. c = complex(1, -1)
  626. d = complex(-77, 32)
  627. self.assertEqual(
  628. list(Complex),
  629. [Complex.a, Complex.b, Complex.c, Complex.d],
  630. )
  631. def test_programatic_function_string(self):
  632. SummerMonth = Enum('SummerMonth', 'june july august')
  633. lst = list(SummerMonth)
  634. self.assertEqual(len(lst), len(SummerMonth))
  635. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  636. self.assertEqual(
  637. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  638. lst,
  639. )
  640. for i, month in enumerate('june july august'.split()):
  641. i += 1
  642. e = SummerMonth(i)
  643. self.assertEqual(int(e.value), i)
  644. self.assertNotEqual(e, i)
  645. self.assertEqual(e.name, month)
  646. self.assertTrue(e in SummerMonth)
  647. self.assertTrue(type(e) is SummerMonth)
  648. def test_programatic_function_string_with_start(self):
  649. SummerMonth = Enum('SummerMonth', 'june july august', start=10)
  650. lst = list(SummerMonth)
  651. self.assertEqual(len(lst), len(SummerMonth))
  652. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  653. self.assertEqual(
  654. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  655. lst,
  656. )
  657. for i, month in enumerate('june july august'.split(), 10):
  658. e = SummerMonth(i)
  659. self.assertEqual(int(e.value), i)
  660. self.assertNotEqual(e, i)
  661. self.assertEqual(e.name, month)
  662. self.assertTrue(e in SummerMonth)
  663. self.assertTrue(type(e) is SummerMonth)
  664. def test_programatic_function_string_list(self):
  665. SummerMonth = Enum('SummerMonth', ['june', 'july', 'august'])
  666. lst = list(SummerMonth)
  667. self.assertEqual(len(lst), len(SummerMonth))
  668. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  669. self.assertEqual(
  670. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  671. lst,
  672. )
  673. for i, month in enumerate('june july august'.split()):
  674. i += 1
  675. e = SummerMonth(i)
  676. self.assertEqual(int(e.value), i)
  677. self.assertNotEqual(e, i)
  678. self.assertEqual(e.name, month)
  679. self.assertTrue(e in SummerMonth)
  680. self.assertTrue(type(e) is SummerMonth)
  681. def test_programatic_function_string_list_with_start(self):
  682. SummerMonth = Enum('SummerMonth', ['june', 'july', 'august'], start=20)
  683. lst = list(SummerMonth)
  684. self.assertEqual(len(lst), len(SummerMonth))
  685. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  686. self.assertEqual(
  687. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  688. lst,
  689. )
  690. for i, month in enumerate('june july august'.split(), 20):
  691. e = SummerMonth(i)
  692. self.assertEqual(int(e.value), i)
  693. self.assertNotEqual(e, i)
  694. self.assertEqual(e.name, month)
  695. self.assertTrue(e in SummerMonth)
  696. self.assertTrue(type(e) is SummerMonth)
  697. def test_programatic_function_iterable(self):
  698. SummerMonth = Enum(
  699. 'SummerMonth',
  700. (('june', 1), ('july', 2), ('august', 3))
  701. )
  702. lst = list(SummerMonth)
  703. self.assertEqual(len(lst), len(SummerMonth))
  704. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  705. self.assertEqual(
  706. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  707. lst,
  708. )
  709. for i, month in enumerate('june july august'.split()):
  710. i += 1
  711. e = SummerMonth(i)
  712. self.assertEqual(int(e.value), i)
  713. self.assertNotEqual(e, i)
  714. self.assertEqual(e.name, month)
  715. self.assertTrue(e in SummerMonth)
  716. self.assertTrue(type(e) is SummerMonth)
  717. def test_programatic_function_from_dict(self):
  718. SummerMonth = Enum(
  719. 'SummerMonth',
  720. dict((('june', 1), ('july', 2), ('august', 3)))
  721. )
  722. lst = list(SummerMonth)
  723. self.assertEqual(len(lst), len(SummerMonth))
  724. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  725. if pyver < 3.0:
  726. self.assertEqual(
  727. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  728. lst,
  729. )
  730. for i, month in enumerate('june july august'.split()):
  731. i += 1
  732. e = SummerMonth(i)
  733. self.assertEqual(int(e.value), i)
  734. self.assertNotEqual(e, i)
  735. self.assertEqual(e.name, month)
  736. self.assertTrue(e in SummerMonth)
  737. self.assertTrue(type(e) is SummerMonth)
  738. def test_programatic_function_type(self):
  739. SummerMonth = Enum('SummerMonth', 'june july august', type=int)
  740. lst = list(SummerMonth)
  741. self.assertEqual(len(lst), len(SummerMonth))
  742. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  743. self.assertEqual(
  744. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  745. lst,
  746. )
  747. for i, month in enumerate('june july august'.split()):
  748. i += 1
  749. e = SummerMonth(i)
  750. self.assertEqual(e, i)
  751. self.assertEqual(e.name, month)
  752. self.assertTrue(e in SummerMonth)
  753. self.assertTrue(type(e) is SummerMonth)
  754. def test_programatic_function_type_with_start(self):
  755. SummerMonth = Enum('SummerMonth', 'june july august', type=int, start=30)
  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(), 30):
  764. e = SummerMonth(i)
  765. self.assertEqual(e, i)
  766. self.assertEqual(e.name, month)
  767. self.assertTrue(e in SummerMonth)
  768. self.assertTrue(type(e) is SummerMonth)
  769. def test_programatic_function_type_from_subclass(self):
  770. SummerMonth = IntEnum('SummerMonth', 'june july august')
  771. lst = list(SummerMonth)
  772. self.assertEqual(len(lst), len(SummerMonth))
  773. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  774. self.assertEqual(
  775. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  776. lst,
  777. )
  778. for i, month in enumerate('june july august'.split()):
  779. i += 1
  780. e = SummerMonth(i)
  781. self.assertEqual(e, i)
  782. self.assertEqual(e.name, month)
  783. self.assertTrue(e in SummerMonth)
  784. self.assertTrue(type(e) is SummerMonth)
  785. def test_programatic_function_type_from_subclass_with_start(self):
  786. SummerMonth = IntEnum('SummerMonth', 'june july august', start=40)
  787. lst = list(SummerMonth)
  788. self.assertEqual(len(lst), len(SummerMonth))
  789. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  790. self.assertEqual(
  791. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  792. lst,
  793. )
  794. for i, month in enumerate('june july august'.split(), 40):
  795. e = SummerMonth(i)
  796. self.assertEqual(e, i)
  797. self.assertEqual(e.name, month)
  798. self.assertTrue(e in SummerMonth)
  799. self.assertTrue(type(e) is SummerMonth)
  800. def test_programatic_function_unicode(self):
  801. SummerMonth = Enum('SummerMonth', unicode('june july august'))
  802. lst = list(SummerMonth)
  803. self.assertEqual(len(lst), len(SummerMonth))
  804. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  805. self.assertEqual(
  806. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  807. lst,
  808. )
  809. for i, month in enumerate(unicode('june july august').split()):
  810. i += 1
  811. e = SummerMonth(i)
  812. self.assertEqual(int(e.value), i)
  813. self.assertNotEqual(e, i)
  814. self.assertEqual(e.name, month)
  815. self.assertTrue(e in SummerMonth)
  816. self.assertTrue(type(e) is SummerMonth)
  817. def test_programatic_function_unicode_list(self):
  818. SummerMonth = Enum('SummerMonth', [unicode('june'), unicode('july'), unicode('august')])
  819. lst = list(SummerMonth)
  820. self.assertEqual(len(lst), len(SummerMonth))
  821. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  822. self.assertEqual(
  823. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  824. lst,
  825. )
  826. for i, month in enumerate(unicode('june july august').split()):
  827. i += 1
  828. e = SummerMonth(i)
  829. self.assertEqual(int(e.value), i)
  830. self.assertNotEqual(e, i)
  831. self.assertEqual(e.name, month)
  832. self.assertTrue(e in SummerMonth)
  833. self.assertTrue(type(e) is SummerMonth)
  834. def test_programatic_function_unicode_iterable(self):
  835. SummerMonth = Enum(
  836. 'SummerMonth',
  837. ((unicode('june'), 1), (unicode('july'), 2), (unicode('august'), 3))
  838. )
  839. lst = list(SummerMonth)
  840. self.assertEqual(len(lst), len(SummerMonth))
  841. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  842. self.assertEqual(
  843. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  844. lst,
  845. )
  846. for i, month in enumerate(unicode('june july august').split()):
  847. i += 1
  848. e = SummerMonth(i)
  849. self.assertEqual(int(e.value), i)
  850. self.assertNotEqual(e, i)
  851. self.assertEqual(e.name, month)
  852. self.assertTrue(e in SummerMonth)
  853. self.assertTrue(type(e) is SummerMonth)
  854. def test_programatic_function_from_unicode_dict(self):
  855. SummerMonth = Enum(
  856. 'SummerMonth',
  857. dict(((unicode('june'), 1), (unicode('july'), 2), (unicode('august'), 3)))
  858. )
  859. lst = list(SummerMonth)
  860. self.assertEqual(len(lst), len(SummerMonth))
  861. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  862. if pyver < 3.0:
  863. self.assertEqual(
  864. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  865. lst,
  866. )
  867. for i, month in enumerate(unicode('june july august').split()):
  868. i += 1
  869. e = SummerMonth(i)
  870. self.assertEqual(int(e.value), i)
  871. self.assertNotEqual(e, i)
  872. self.assertEqual(e.name, month)
  873. self.assertTrue(e in SummerMonth)
  874. self.assertTrue(type(e) is SummerMonth)
  875. def test_programatic_function_unicode_type(self):
  876. SummerMonth = Enum('SummerMonth', unicode('june july august'), type=int)
  877. lst = list(SummerMonth)
  878. self.assertEqual(len(lst), len(SummerMonth))
  879. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  880. self.assertEqual(
  881. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  882. lst,
  883. )
  884. for i, month in enumerate(unicode('june july august').split()):
  885. i += 1
  886. e = SummerMonth(i)
  887. self.assertEqual(e, i)
  888. self.assertEqual(e.name, month)
  889. self.assertTrue(e in SummerMonth)
  890. self.assertTrue(type(e) is SummerMonth)
  891. def test_programatic_function_unicode_type_from_subclass(self):
  892. SummerMonth = IntEnum('SummerMonth', unicode('june july august'))
  893. lst = list(SummerMonth)
  894. self.assertEqual(len(lst), len(SummerMonth))
  895. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  896. self.assertEqual(
  897. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  898. lst,
  899. )
  900. for i, month in enumerate(unicode('june july august').split()):
  901. i += 1
  902. e = SummerMonth(i)
  903. self.assertEqual(e, i)
  904. self.assertEqual(e.name, month)
  905. self.assertTrue(e in SummerMonth)
  906. self.assertTrue(type(e) is SummerMonth)
  907. def test_programmatic_function_unicode_class(self):
  908. if pyver < 3.0:
  909. class_names = unicode('SummerMonth'), 'S\xfcmm\xe9rM\xf6nth'.decode('latin1')
  910. else:
  911. class_names = 'SummerMonth', 'S\xfcmm\xe9rM\xf6nth'
  912. for i, class_name in enumerate(class_names):
  913. if pyver < 3.0 and i == 1:
  914. self.assertRaises(TypeError, Enum, class_name, unicode('june july august'))
  915. else:
  916. SummerMonth = Enum(class_name, unicode('june july august'))
  917. lst = list(SummerMonth)
  918. self.assertEqual(len(lst), len(SummerMonth))
  919. self.assertEqual(len(SummerMonth), 3, SummerMonth)
  920. self.assertEqual(
  921. [SummerMonth.june, SummerMonth.july, SummerMonth.august],
  922. lst,
  923. )
  924. for i, month in enumerate(unicode('june july august').split()):
  925. i += 1
  926. e = SummerMonth(i)
  927. self.assertEqual(e.value, i)
  928. self.assertEqual(e.name, month)
  929. self.assertTrue(e in SummerMonth)
  930. self.assertTrue(type(e) is SummerMonth)
  931. def test_subclassing(self):
  932. if isinstance(Name, Exception):
  933. raise Name
  934. self.assertEqual(Name.BDFL, 'Guido van Rossum')
  935. self.assertTrue(Name.BDFL, Name('Guido van Rossum'))
  936. self.assertTrue(Name.BDFL is getattr(Name, 'BDFL'))
  937. test_pickle_dump_load(self.assertTrue, Name.BDFL)
  938. def test_extending(self):
  939. def bad_extension():
  940. class Color(Enum):
  941. red = 1
  942. green = 2
  943. blue = 3
  944. class MoreColor(Color):
  945. cyan = 4
  946. magenta = 5
  947. yellow = 6
  948. self.assertRaises(TypeError, bad_extension)
  949. def test_exclude_methods(self):
  950. class whatever(Enum):
  951. this = 'that'
  952. these = 'those'
  953. def really(self):
  954. return 'no, not %s' % self.value
  955. self.assertFalse(type(whatever.really) is whatever)
  956. self.assertEqual(whatever.this.really(), 'no, not that')
  957. def test_wrong_inheritance_order(self):
  958. def wrong_inherit():
  959. class Wrong(Enum, str):
  960. NotHere = 'error before this point'
  961. self.assertRaises(TypeError, wrong_inherit)
  962. def test_intenum_transitivity(self):
  963. class number(IntEnum):
  964. one = 1
  965. two = 2
  966. three = 3
  967. class numero(IntEnum):
  968. uno = 1
  969. dos = 2
  970. tres = 3
  971. self.assertEqual(number.one, numero.uno)
  972. self.assertEqual(number.two, numero.dos)
  973. self.assertEqual(number.three, numero.tres)
  974. def test_introspection(self):
  975. class Number(IntEnum):
  976. one = 100
  977. two = 200
  978. self.assertTrue(Number.one._member_type_ is int)
  979. self.assertTrue(Number._member_type_ is int)
  980. class String(str, Enum):
  981. yarn = 'soft'
  982. rope = 'rough'
  983. wire = 'hard'
  984. self.assertTrue(String.yarn._member_type_ is str)
  985. self.assertTrue(String._member_type_ is str)
  986. class Plain(Enum):
  987. vanilla = 'white'
  988. one = 1
  989. self.assertTrue(Plain.vanilla._member_type_ is object)
  990. self.assertTrue(Plain._member_type_ is object)
  991. def test_wrong_enum_in_call(self):
  992. class Monochrome(Enum):
  993. black = 0
  994. white = 1
  995. class Gender(Enum):
  996. male = 0
  997. female = 1
  998. self.assertRaises(ValueError, Monochrome, Gender.male)
  999. def test_wrong_enum_in_mixed_call(self):
  1000. class Monochrome(IntEnum):
  1001. black = 0
  1002. white = 1
  1003. class Gender(Enum):
  1004. male = 0
  1005. female = 1
  1006. self.assertRaises(ValueError, Monochrome, Gender.male)
  1007. def test_mixed_enum_in_call_1(self):
  1008. class Monochrome(IntEnum):
  1009. black = 0
  1010. white = 1
  1011. class Gender(IntEnum):
  1012. male = 0
  1013. female = 1
  1014. self.assertTrue(Monochrome(Gender.female) is Monochrome.white)
  1015. def test_mixed_enum_in_call_2(self):
  1016. class Monochrome(Enum):
  1017. black = 0
  1018. white = 1
  1019. class Gender(IntEnum):
  1020. male = 0
  1021. female = 1
  1022. self.assertTrue(Monochrome(Gender.male) is Monochrome.black)
  1023. def test_flufl_enum(self):
  1024. class Fluflnum(Enum):
  1025. def __int__(self):
  1026. return int(self.value)
  1027. class MailManOptions(Fluflnum):
  1028. option1 = 1
  1029. option2 = 2
  1030. option3 = 3
  1031. self.assertEqual(int(MailManOptions.option1), 1)
  1032. def test_no_such_enum_member(self):
  1033. class Color(Enum):
  1034. red = 1
  1035. green = 2
  1036. blue = 3
  1037. self.assertRaises(ValueError, Color, 4)
  1038. self.assertRaises(KeyError, Color.__getitem__, 'chartreuse')
  1039. def test_new_repr(self):
  1040. class Color(Enum):
  1041. red = 1
  1042. green = 2
  1043. blue = 3
  1044. def __repr__(self):
  1045. return "don't you just love shades of %s?" % self.name
  1046. self.assertEqual(
  1047. repr(Color.blue),
  1048. "don't you just love shades of blue?",
  1049. )
  1050. def test_inherited_repr(self):
  1051. class MyEnum(Enum):
  1052. def __repr__(self):
  1053. return "My name is %s." % self.name
  1054. class MyIntEnum(int, MyEnum):
  1055. this = 1
  1056. that = 2
  1057. theother = 3
  1058. self.assertEqual(repr(MyIntEnum.that), "My name is that.")
  1059. def test_multiple_mixin_mro(self):
  1060. class auto_enum(EnumMeta):
  1061. def __new__(metacls, cls, bases, classdict):
  1062. original_dict = classdict
  1063. classdict = enum._EnumDict()
  1064. for k, v in original_dict.items():
  1065. classdict[k] = v
  1066. temp = type(classdict)()
  1067. names = set(classdict._member_names)
  1068. i = 0
  1069. for k in classdict._member_names:
  1070. v = classdict[k]
  1071. if v == ():
  1072. v = i
  1073. else:
  1074. i = v
  1075. i += 1
  1076. temp[k] = v
  1077. for k, v in classdict.items():
  1078. if k not in names:
  1079. temp[k] = v
  1080. return super(auto_enum, metacls).__new__(
  1081. metacls, cls, bases, temp)
  1082. AutoNumberedEnum = auto_enum('AutoNumberedEnum', (Enum,), {})
  1083. AutoIntEnum = auto_enum('AutoIntEnum', (IntEnum,), {})
  1084. class TestAutoNumber(AutoNumberedEnum):
  1085. a = ()
  1086. b = 3
  1087. c = ()
  1088. class TestAutoInt(AutoIntEnum):
  1089. a = ()
  1090. b = 3
  1091. c = ()
  1092. def test_subclasses_with_getnewargs(self):
  1093. class NamedInt(int):
  1094. __qualname__ = 'NamedInt' # needed for pickle protocol 4
  1095. def __new__(cls, *args):
  1096. _args = args
  1097. if len(args) < 1:
  1098. raise TypeError("name and value must be specified")
  1099. name, args = args[0], args[1:]
  1100. self = int.__new__(cls, *args)
  1101. self._intname = name
  1102. self._args = _args
  1103. return self
  1104. def __getnewargs__(self):
  1105. return self._args
  1106. @property
  1107. def __name__(self):
  1108. return self._intname
  1109. def __repr__(self):
  1110. # repr() is updated to include the name and type info
  1111. return "%s(%r, %s)" % (type(self).__name__,
  1112. self.__name__,
  1113. int.__repr__(self))
  1114. def __str__(self):
  1115. # str() is unchanged, even if it relies on the repr() fallback
  1116. base = int
  1117. base_str = base.__str__
  1118. if base_str.__objclass__ is object:
  1119. return base.__repr__(self)
  1120. return base_str(self)
  1121. # for simplicity, we only define one operator that
  1122. # propagates expressions
  1123. def __add__(self, other):
  1124. temp = int(self) + int( other)
  1125. if isinstance(self, NamedInt) and isinstance(other, NamedInt):
  1126. return NamedInt(
  1127. '(%s + %s)' % (self.__name__, other.__name__),
  1128. temp )
  1129. else:
  1130. return temp
  1131. class NEI(NamedInt, Enum):
  1132. __qualname__ = 'NEI' # needed for pickle protocol 4
  1133. x = ('the-x', 1)
  1134. y = ('the-y', 2)
  1135. self.assertTrue(NEI.__new__ is Enum.__new__)
  1136. self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
  1137. globals()['NamedInt'] = NamedInt
  1138. globals()['NEI'] = NEI
  1139. NI5 = NamedInt('test', 5)
  1140. self.assertEqual(NI5, 5)
  1141. test_pickle_dump_load(self.assertTrue, NI5, 5)
  1142. self.assertEqual(NEI.y.value, 2)
  1143. test_pickle_dump_load(self.assertTrue, NEI.y)
  1144. if pyver >= 3.4:
  1145. def test_subclasses_with_getnewargs_ex(self):
  1146. class NamedInt(int):
  1147. __qualname__ = 'NamedInt' # needed for pickle protocol 4
  1148. def __new__(cls, *args):
  1149. _args = args
  1150. if len(args) < 2:
  1151. raise TypeError("name and value must be specified")
  1152. name, args = args[0], args[1:]
  1153. self = int.__new__(cls, *args)
  1154. self._intname = name
  1155. self._args = _args
  1156. return self
  1157. def __getnewargs_ex__(self):
  1158. return self._args, {}
  1159. @property
  1160. def __name__(self):
  1161. return self._intname
  1162. def __repr__(self):
  1163. # repr() is updated to include the name and type info
  1164. return "{}({!r}, {})".format(type(self).__name__,
  1165. self.__name__,
  1166. int.__repr__(self))
  1167. def __str__(self):
  1168. # str() is unchanged, even if it relies on the repr() fallback
  1169. base = int
  1170. base_str = base.__str__
  1171. if base_str.__objclass__ is object:
  1172. return base.__repr__(self)
  1173. return base_str(self)
  1174. # for simplicity, we only define one operator that
  1175. # propagates expressions
  1176. def __add__(self, other):
  1177. temp = int(self) + int( other)
  1178. if isinstance(self, NamedInt) and isinstance(other, NamedInt):
  1179. return NamedInt(
  1180. '({0} + {1})'.format(self.__name__, other.__name__),
  1181. temp )
  1182. else:
  1183. return temp
  1184. class NEI(NamedInt, Enum):
  1185. __qualname__ = 'NEI' # needed for pickle protocol 4
  1186. x = ('the-x', 1)
  1187. y = ('the-y', 2)
  1188. self.assertIs(NEI.__new__, Enum.__new__)
  1189. self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
  1190. globals()['NamedInt'] = NamedInt
  1191. globals()['NEI'] = NEI
  1192. NI5 = NamedInt('test', 5)
  1193. self.assertEqual(NI5, 5)
  1194. test_pickle_dump_load(self.assertEqual, NI5, 5, protocol=(4, HIGHEST_PROTOCOL))
  1195. self.assertEqual(NEI.y.value, 2)
  1196. test_pickle_dump_load(self.assertTrue, NEI.y, protocol=(4, HIGHEST_PROTOCOL))
  1197. def test_subclasses_with_reduce(self):
  1198. class NamedInt(int):
  1199. __qualname__ = 'NamedInt' # needed for pickle protocol 4
  1200. def __new__(cls, *args):
  1201. _args = args
  1202. if len(args) < 1:
  1203. raise TypeError("name and value must be specified")
  1204. name, args = args[0], args[1:]
  1205. self = int.__new__(cls, *args)
  1206. self._intname = name
  1207. self._args = _args
  1208. return self
  1209. def __reduce__(self):
  1210. return self.__class__, self._args
  1211. @property
  1212. def __name__(self):
  1213. return self._intname
  1214. def __repr__(self):
  1215. # repr() is updated to include the name and type info
  1216. return "%s(%r, %s)" % (type(self).__name__,
  1217. self.__name__,
  1218. int.__repr__(self))
  1219. def __str__(self):
  1220. # str() is unchanged, even if it relies on the repr() fallback
  1221. base = int
  1222. base_str = base.__str__
  1223. if base_str.__objclass__ is object:
  1224. return base.__repr__(self)
  1225. return base_str(self)
  1226. # for simplicity, we only define one operator that
  1227. # propagates expressions
  1228. def __add__(self, other):
  1229. temp = int(self) + int( other)
  1230. if isinstance(self, NamedInt) and isinstance(other, NamedInt):
  1231. return NamedInt(
  1232. '(%s + %s)' % (self.__name__, other.__name__),
  1233. temp )
  1234. else:
  1235. return temp
  1236. class NEI(NamedInt, Enum):
  1237. __qualname__ = 'NEI' # needed for pickle protocol 4
  1238. x = ('the-x', 1)
  1239. y = ('the-y', 2)
  1240. self.assertTrue(NEI.__new__ is Enum.__new__)
  1241. self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
  1242. globals()['NamedInt'] = NamedInt
  1243. globals()['NEI'] = NEI
  1244. NI5 = NamedInt('test', 5)
  1245. self.assertEqual(NI5, 5)
  1246. test_pickle_dump_load(self.assertEqual, NI5, 5)
  1247. self.assertEqual(NEI.y.value, 2)
  1248. test_pickle_dump_load(self.assertTrue, NEI.y)
  1249. def test_subclasses_with_reduce_ex(self):
  1250. class NamedInt(int):
  1251. __qualname__ = 'NamedInt' # needed for pickle protocol 4
  1252. def __new__(cls, *args):
  1253. _args = args
  1254. if len(args) < 1:
  1255. raise TypeError("name and value must be specified")
  1256. name, args = args[0], args[1:]
  1257. self = int.__new__(cls, *args)
  1258. self._intname = name
  1259. self._args = _args
  1260. return self
  1261. def __reduce_ex__(self, proto):
  1262. return self.__class__, self._args
  1263. @property
  1264. def __name__(self):
  1265. return self._intname
  1266. def __repr__(self):
  1267. # repr() is updated to include the name and type info
  1268. return "%s(%r, %s)" % (type(self).__name__,
  1269. self.__name__,
  1270. int.__repr__(self))
  1271. def __str__(self):
  1272. # str() is unchanged, even if it relies on the repr() fallback
  1273. base = int
  1274. base_str = base.__str__
  1275. if base_str.__objclass__ is object:
  1276. return base.__repr__(self)
  1277. return base_str(self)
  1278. # for simplicity, we only define one operator that
  1279. # propagates expressions
  1280. def __add__(self, other):
  1281. temp = int(self) + int( other)
  1282. if isinstance(self, NamedInt) and isinstance(other, NamedInt):
  1283. return NamedInt(
  1284. '(%s + %s)' % (self.__name__, other.__name__),
  1285. temp )
  1286. else:
  1287. return temp
  1288. class NEI(NamedInt, Enum):
  1289. __qualname__ = 'NEI' # needed for pickle protocol 4
  1290. x = ('the-x', 1)
  1291. y = ('the-y', 2)
  1292. self.assertTrue(NEI.__new__ is Enum.__new__)
  1293. self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
  1294. globals()['NamedInt'] = NamedInt
  1295. globals()['NEI'] = NEI
  1296. NI5 = NamedInt('test', 5)
  1297. self.assertEqual(NI5, 5)
  1298. test_pickle_dump_load(self.assertEqual, NI5, 5)
  1299. self.assertEqual(NEI.y.value, 2)
  1300. test_pickle_dump_load(self.assertTrue, NEI.y)
  1301. def test_subclasses_without_direct_pickle_support(self):
  1302. class NamedInt(int):
  1303. __qualname__ = 'NamedInt'
  1304. def __new__(cls, *args):
  1305. _args = args
  1306. name, args = args[0], args[1:]
  1307. if len(args) == 0:
  1308. raise TypeError("name and value must be specified")
  1309. self = int.__new__(cls, *args)
  1310. self._intname = name
  1311. self._args = _args
  1312. return self
  1313. @property
  1314. def __name__(self):
  1315. return self._intname
  1316. def __repr__(self):
  1317. # repr() is updated to include the name and type info
  1318. return "%s(%r, %s)" % (type(self).__name__,
  1319. self.__name__,
  1320. int.__repr__(self))
  1321. def __str__(self):
  1322. # str() is unchanged, even if it relies on the repr() fallback
  1323. base = int
  1324. base_str = base.__str__
  1325. if base_str.__objclass__ is object:
  1326. return base.__repr__(self)
  1327. return base_str(self)
  1328. # for simplicity, we only define one operator that
  1329. # propagates expressions
  1330. def __add__(self, other):
  1331. temp = int(self) + int( other)
  1332. if isinstance(self, NamedInt) and isinstance(other, NamedInt):
  1333. return NamedInt(
  1334. '(%s + %s)' % (self.__name__, other.__name__),
  1335. temp )
  1336. else:
  1337. return temp
  1338. class NEI(NamedInt, Enum):
  1339. __qualname__ = 'NEI'
  1340. x = ('the-x', 1)
  1341. y = ('the-y', 2)
  1342. self.assertTrue(NEI.__new__ is Enum.__new__)
  1343. self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
  1344. globals()['NamedInt'] = NamedInt
  1345. globals()['NEI'] = NEI
  1346. NI5 = NamedInt('test', 5)
  1347. self.assertEqual(NI5, 5)
  1348. self.assertEqual(NEI.y.value, 2)
  1349. test_pickle_exception(self.assertRaises, TypeError, NEI.x)
  1350. test_pickle_exception(self.assertRaises, PicklingError, NEI)
  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[0], args[1:]
  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 "%s(%r, %s)" % (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. '(%s + %s)' % (self.__name__, other.__name__),
  1385. temp )
  1386. else:
  1387. return temp
  1388. class NEI(NamedInt, Enum):
  1389. __qualname__ = 'NEI'
  1390. x = ('the-x', 1)
  1391. y = ('the-y', 2)
  1392. def __reduce_ex__(self, proto):
  1393. return getattr, (self.__class__, self._name_)
  1394. self.assertTrue(NEI.__new__ is Enum.__new__)
  1395. self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
  1396. globals()['NamedInt'] = NamedInt
  1397. globals()['NEI'] = NEI
  1398. NI5 = NamedInt('test', 5)
  1399. self.assertEqual(NI5, 5)
  1400. self.assertEqual(NEI.y.value, 2)
  1401. test_pickle_dump_load(self.assertTrue, NEI.y)
  1402. test_pickle_dump_load(self.assertTrue, NEI)
  1403. def test_tuple_subclass(self):
  1404. class SomeTuple(tuple, Enum):
  1405. __qualname__ = 'SomeTuple'
  1406. first = (1, 'for the money')
  1407. second = (2, 'for the show')
  1408. third = (3, 'for the music')
  1409. self.assertTrue(type(SomeTuple.first) is SomeTuple)
  1410. self.assertTrue(isinstance(SomeTuple.second, tuple))
  1411. self.assertEqual(SomeTuple.third, (3, 'for the music'))
  1412. globals()['SomeTuple'] = SomeTuple
  1413. test_pickle_dump_load(self.assertTrue, SomeTuple.first)
  1414. def test_duplicate_values_give_unique_enum_items(self):
  1415. class AutoNumber(Enum):
  1416. __order__ = 'enum_m enum_d enum_y'
  1417. enum_m = ()
  1418. enum_d = ()
  1419. enum_y = ()
  1420. def __new__(cls):
  1421. value = len(cls.__members__) + 1
  1422. obj = object.__new__(cls)
  1423. obj._value_ = value
  1424. return obj
  1425. def __int__(self):
  1426. return int(self._value_)
  1427. self.assertEqual(int(AutoNumber.enum_d), 2)
  1428. self.assertEqual(AutoNumber.enum_y.value, 3)
  1429. self.assertTrue(AutoNumber(1) is AutoNumber.enum_m)
  1430. self.assertEqual(
  1431. list(AutoNumber),
  1432. [AutoNumber.enum_m, AutoNumber.enum_d, AutoNumber.enum_y],
  1433. )
  1434. def test_inherited_new_from_enhanced_enum(self):
  1435. class AutoNumber2(Enum):
  1436. def __new__(cls):
  1437. value = len(cls.__members__) + 1
  1438. obj = object.__new__(cls)
  1439. obj._value_ = value
  1440. return obj
  1441. def __int__(self):
  1442. return int(self._value_)
  1443. class Color(AutoNumber2):
  1444. _order_ = 'red green blue'
  1445. red = ()
  1446. green = ()
  1447. blue = ()
  1448. self.assertEqual(len(Color), 3, "wrong number of elements: %d (should be %d)" % (len(Color), 3))
  1449. self.assertEqual(list(Color), [Color.red, Color.green, Color.blue])
  1450. if pyver >= 3.0:
  1451. self.assertEqual(list(map(int, Color)), [1, 2, 3])
  1452. def test_inherited_new_from_mixed_enum(self):
  1453. class AutoNumber3(IntEnum):
  1454. def __new__(cls):
  1455. value = len(cls.__members__) + 1
  1456. obj = int.__new__(cls, value)
  1457. obj._value_ = value
  1458. return obj
  1459. class Color(AutoNumber3):
  1460. red = ()
  1461. green = ()
  1462. blue = ()
  1463. self.assertEqual(len(Color), 3, "wrong number of elements: %d (should be %d)" % (len(Color), 3))
  1464. Color.red
  1465. Color.green
  1466. Color.blue
  1467. def test_equality(self):
  1468. class AlwaysEqual:
  1469. def __eq__(self, other):
  1470. return True
  1471. class OrdinaryEnum(Enum):
  1472. a = 1
  1473. self.assertEqual(AlwaysEqual(), OrdinaryEnum.a)
  1474. self.assertEqual(OrdinaryEnum.a, AlwaysEqual())
  1475. def test_ordered_mixin(self):
  1476. class OrderedEnum(Enum):
  1477. def __ge__(self, other):
  1478. if self.__class__ is other.__class__:
  1479. return self._value_ >= other._value_
  1480. return NotImplemented
  1481. def __gt__(self, other):
  1482. if self.__class__ is other.__class__:
  1483. return self._value_ > other._value_
  1484. return NotImplemented
  1485. def __le__(self, other):
  1486. if self.__class__ is other.__class__:
  1487. return self._value_ <= other._value_
  1488. return NotImplemented
  1489. def __lt__(self, other):
  1490. if self.__class__ is other.__class__:
  1491. return self._value_ < other._value_
  1492. return NotImplemented
  1493. class Grade(OrderedEnum):
  1494. __order__ = 'A B C D F'
  1495. A = 5
  1496. B = 4
  1497. C = 3
  1498. D = 2
  1499. F = 1
  1500. self.assertEqual(list(Grade), [Grade.A, Grade.B, Grade.C, Grade.D, Grade.F])
  1501. self.assertTrue(Grade.A > Grade.B)
  1502. self.assertTrue(Grade.F <= Grade.C)
  1503. self.assertTrue(Grade.D < Grade.A)
  1504. self.assertTrue(Grade.B >= Grade.B)
  1505. def test_extending2(self):
  1506. def bad_extension():
  1507. class Shade(Enum):
  1508. def shade(self):
  1509. print(self.name)
  1510. class Color(Shade):
  1511. red = 1
  1512. green = 2
  1513. blue = 3
  1514. class MoreColor(Color):
  1515. cyan = 4
  1516. magenta = 5
  1517. yellow = 6
  1518. self.assertRaises(TypeError, bad_extension)
  1519. def test_extending3(self):
  1520. class Shade(Enum):
  1521. def shade(self):
  1522. return self.name
  1523. class Color(Shade):
  1524. def hex(self):
  1525. return '%s hexlified!' % self.value
  1526. class MoreColor(Color):
  1527. cyan = 4
  1528. magenta = 5
  1529. yellow = 6
  1530. self.assertEqual(MoreColor.magenta.hex(), '5 hexlified!')
  1531. def test_no_duplicates(self):
  1532. def bad_duplicates():
  1533. class UniqueEnum(Enum):
  1534. def __init__(self, *args):
  1535. cls = self.__class__
  1536. if any(self.value == e.value for e in cls):
  1537. a = self.name
  1538. e = cls(self.value).name
  1539. raise ValueError(
  1540. "aliases not allowed in UniqueEnum: %r --> %r"
  1541. % (a, e)
  1542. )
  1543. class Color(UniqueEnum):
  1544. red = 1
  1545. green = 2
  1546. blue = 3
  1547. class Color(UniqueEnum):
  1548. red = 1
  1549. green = 2
  1550. blue = 3
  1551. grene = 2
  1552. self.assertRaises(ValueError, bad_duplicates)
  1553. def test_init(self):
  1554. class Planet(Enum):
  1555. MERCURY = (3.303e+23, 2.4397e6)
  1556. VENUS = (4.869e+24, 6.0518e6)
  1557. EARTH = (5.976e+24, 6.37814e6)
  1558. MARS = (6.421e+23, 3.3972e6)
  1559. JUPITER = (1.9e+27, 7.1492e7)
  1560. SATURN = (5.688e+26, 6.0268e7)
  1561. URANUS = (8.686e+25, 2.5559e7)
  1562. NEPTUNE = (1.024e+26, 2.4746e7)
  1563. def __init__(self, mass, radius):
  1564. self.mass = mass # in kilograms
  1565. self.radius = radius # in meters
  1566. @property
  1567. def surface_gravity(self):
  1568. # universal gravitational constant (m3 kg-1 s-2)
  1569. G = 6.67300E-11
  1570. return G * self.mass / (self.radius * self.radius)
  1571. self.assertEqual(round(Planet.EARTH.surface_gravity, 2), 9.80)
  1572. self.assertEqual(Planet.EARTH.value, (5.976e+24, 6.37814e6))
  1573. def test_nonhash_value(self):
  1574. class AutoNumberInAList(Enum):
  1575. def __new__(cls):
  1576. value = [len(cls.__members__) + 1]
  1577. obj = object.__new__(cls)
  1578. obj._value_ = value
  1579. return obj
  1580. class ColorInAList(AutoNumberInAList):
  1581. _order_ = 'red green blue'
  1582. red = ()
  1583. green = ()
  1584. blue = ()
  1585. self.assertEqual(list(ColorInAList), [ColorInAList.red, ColorInAList.green, ColorInAList.blue])
  1586. self.assertEqual(ColorInAList.red.value, [1])
  1587. self.assertEqual(ColorInAList([1]), ColorInAList.red)
  1588. def test_conflicting_types_resolved_in_new(self):
  1589. class LabelledIntEnum(int, Enum):
  1590. def __new__(cls, *args):
  1591. value, label = args
  1592. obj = int.__new__(cls, value)
  1593. obj.label = label
  1594. obj._value_ = value
  1595. return obj
  1596. class LabelledList(LabelledIntEnum):
  1597. unprocessed = (1, "Unprocessed")
  1598. payment_complete = (2, "Payment Complete")
  1599. self.assertEqual(list(LabelledList), [LabelledList.unprocessed, LabelledList.payment_complete])
  1600. self.assertEqual(LabelledList.unprocessed, 1)
  1601. self.assertEqual(LabelledList(1), LabelledList.unprocessed)
  1602. def test_empty_with_functional_api(self):
  1603. empty = enum.IntEnum('Foo', {})
  1604. self.assertEqual(len(empty), 0)
  1605. class TestUnique(unittest.TestCase):
  1606. """2.4 doesn't allow class decorators, use function syntax."""
  1607. def test_unique_clean(self):
  1608. class Clean(Enum):
  1609. one = 1
  1610. two = 'dos'
  1611. tres = 4.0
  1612. unique(Clean)
  1613. class Cleaner(IntEnum):
  1614. single = 1
  1615. double = 2
  1616. triple = 3
  1617. unique(Cleaner)
  1618. def test_unique_dirty(self):
  1619. try:
  1620. class Dirty(Enum):
  1621. __order__ = 'one two tres'
  1622. one = 1
  1623. two = 'dos'
  1624. tres = 1
  1625. unique(Dirty)
  1626. except ValueError:
  1627. exc = sys.exc_info()[1]
  1628. message = exc.args[0]
  1629. self.assertTrue('tres -> one' in message)
  1630. try:
  1631. class Dirtier(IntEnum):
  1632. _order_ = 'single double triple turkey'
  1633. single = 1
  1634. double = 1
  1635. triple = 3
  1636. turkey = 3
  1637. unique(Dirtier)
  1638. except ValueError:
  1639. exc = sys.exc_info()[1]
  1640. message = exc.args[0]
  1641. self.assertTrue('double -> single' in message)
  1642. self.assertTrue('turkey -> triple' in message)
  1643. class TestMe(unittest.TestCase):
  1644. pass
  1645. if __name__ == '__main__':
  1646. unittest.main()