comparison env/lib/python3.7/site-packages/aenum/test_v3.py @ 0:26e78fe6e8c4 draft

"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author shellac
date Sat, 02 May 2020 07:14:21 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:26e78fe6e8c4
1 from aenum import Enum, IntEnum, Flag, UniqueEnum, AutoEnum, NamedTuple, TupleSize, AutoValue, AutoNumber, NoAlias, Unique, MultiValue
2 from aenum import AutoNumberEnum, OrderedEnum, unique, skip, extend_enum
3
4 from collections import OrderedDict
5 from datetime import timedelta
6 from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL
7 from unittest import TestCase, main
8
9 import sys
10 pyver = float('%s.%s' % sys.version_info[:2])
11
12 class MagicAutoNumberEnum(Enum, settings=AutoNumber):
13 pass
14
15 class TestEnumV3(TestCase):
16
17 def setUp(self):
18 class Season(Enum):
19 SPRING = 1
20 SUMMER = 2
21 AUTUMN = 3
22 WINTER = 4
23 self.Season = Season
24
25 class Konstants(float, Enum):
26 E = 2.7182818
27 PI = 3.1415926
28 TAU = 2 * PI
29 self.Konstants = Konstants
30
31 class Grades(IntEnum):
32 A = 5
33 B = 4
34 C = 3
35 D = 2
36 F = 0
37 self.Grades = Grades
38
39 class Directional(str, Enum):
40 EAST = 'east'
41 WEST = 'west'
42 NORTH = 'north'
43 SOUTH = 'south'
44 self.Directional = Directional
45
46 from datetime import date
47 class Holiday(date, Enum):
48 NEW_YEAR = 2013, 1, 1
49 IDES_OF_MARCH = 2013, 3, 15
50 self.Holiday = Holiday
51
52 def test_auto_init(self):
53 class Planet(Enum, init='mass radius'):
54 MERCURY = (3.303e+23, 2.4397e6)
55 VENUS = (4.869e+24, 6.0518e6)
56 EARTH = (5.976e+24, 6.37814e6)
57 MARS = (6.421e+23, 3.3972e6)
58 JUPITER = (1.9e+27, 7.1492e7)
59 SATURN = (5.688e+26, 6.0268e7)
60 URANUS = (8.686e+25, 2.5559e7)
61 NEPTUNE = (1.024e+26, 2.4746e7)
62 @property
63 def surface_gravity(self):
64 # universal gravitational constant (m3 kg-1 s-2)
65 G = 6.67300E-11
66 return G * self.mass / (self.radius * self.radius)
67 self.assertEqual(round(Planet.EARTH.surface_gravity, 2), 9.80)
68 self.assertEqual(Planet.EARTH.value, (5.976e+24, 6.37814e6))
69
70 def test_auto_init_with_value(self):
71 class Color(Enum, init='value, rgb'):
72 RED = 1, (1, 0, 0)
73 BLUE = 2, (0, 1, 0)
74 GREEN = 3, (0, 0, 1)
75 self.assertEqual(Color.RED.value, 1)
76 self.assertEqual(Color.BLUE.value, 2)
77 self.assertEqual(Color.GREEN.value, 3)
78 self.assertEqual(Color.RED.rgb, (1, 0, 0))
79 self.assertEqual(Color.BLUE.rgb, (0, 1, 0))
80 self.assertEqual(Color.GREEN.rgb, (0, 0, 1))
81
82 def test_auto_turns_off(self):
83 with self.assertRaises(NameError):
84 class Color(Enum, settings=AutoValue):
85 red
86 green
87 blue
88 def hello(self):
89 print('Hello! My serial is %s.' % self.value)
90 rose
91 with self.assertRaises(NameError):
92 class Color(Enum, settings=AutoValue):
93 red
94 green
95 blue
96 def __init__(self, *args):
97 pass
98 rose
99
100 def test_magic(self):
101 class Color(Enum, settings=AutoValue):
102 red, green, blue
103 self.assertEqual(list(Color), [Color.red, Color.green, Color.blue])
104 self.assertEqual(Color.red.value, 1)
105
106 def test_ignore_not_overridden(self):
107 with self.assertRaisesRegex(TypeError, 'object is not callable'):
108 class Color(Flag):
109 _ignore_ = 'irrelevent'
110 _settings_ = AutoValue
111 @property
112 def shade(self):
113 print('I am light', self.name.lower())
114
115 def test_magic_start(self):
116 class Color(Enum, start=0):
117 red, green, blue
118 self.assertEqual(list(Color), [Color.red, Color.green, Color.blue])
119 self.assertEqual(Color.red.value, 0)
120
121 def test_magic_on_and_off(self):
122 class Color(Enum):
123 _auto_on_
124 red
125 green
126 _auto_off_
127 @property
128 def cap_name(self) -> str:
129 return self.name.title()
130 _auto_on_
131 blue
132 self.assertEqual(len(Color), 3)
133 self.assertEqual(list(Color), [Color.red, Color.green, Color.blue])
134
135 def test_dir_on_class(self):
136 Season = self.Season
137 self.assertEqual(
138 set(dir(Season)),
139 set(['__class__', '__doc__', '__members__', '__module__',
140 'SPRING', 'SUMMER', 'AUTUMN', 'WINTER']),
141 )
142
143 def test_dir_on_item(self):
144 Season = self.Season
145 self.assertEqual(
146 set(dir(Season.WINTER)),
147 set(['__class__', '__doc__', '__module__', 'name', 'value', 'values']),
148 )
149
150 def test_dir_with_added_behavior(self):
151 class Test(Enum):
152 this = 'that'
153 these = 'those'
154 def wowser(self):
155 return ("Wowser! I'm %s!" % self.name)
156 self.assertEqual(
157 set(dir(Test)),
158 set(['__class__', '__doc__', '__members__', '__module__', 'this', 'these']),
159 )
160 self.assertEqual(
161 set(dir(Test.this)),
162 set(['__class__', '__doc__', '__module__', 'name', 'value', 'values', 'wowser']),
163 )
164
165 def test_dir_on_sub_with_behavior_on_super(self):
166 # see issue22506
167 class SuperEnum(Enum):
168 def invisible(self):
169 return "did you see me?"
170 class SubEnum(SuperEnum):
171 sample = 5
172 self.assertEqual(
173 set(dir(SubEnum.sample)),
174 set(['__class__', '__doc__', '__module__', 'name', 'value', 'values', 'invisible']),
175 )
176
177 def test_members_are_always_ordered(self):
178 class AlwaysOrdered(Enum):
179 first = 1
180 second = 2
181 third = 3
182 self.assertTrue(type(AlwaysOrdered.__members__) is OrderedDict)
183
184 def test_comparisons(self):
185 def bad_compare():
186 Season.SPRING > 4
187 Season = self.Season
188 self.assertNotEqual(Season.SPRING, 1)
189 self.assertRaises(TypeError, bad_compare)
190
191 class Part(Enum):
192 SPRING = 1
193 CLIP = 2
194 BARREL = 3
195
196 self.assertNotEqual(Season.SPRING, Part.SPRING)
197 def bad_compare():
198 Season.SPRING < Part.CLIP
199 self.assertRaises(TypeError, bad_compare)
200
201 def test_duplicate_name(self):
202 with self.assertRaises(TypeError):
203 class Color1(Enum):
204 red = 1
205 green = 2
206 blue = 3
207 red = 4
208
209 with self.assertRaises(TypeError):
210 class Color2(Enum):
211 red = 1
212 green = 2
213 blue = 3
214 def red(self):
215 return 'red'
216
217 with self.assertRaises(TypeError):
218 class Color3(Enum):
219 @property
220 def red(self):
221 return 'redder'
222 red = 1
223 green = 2
224 blue = 3
225
226 def test_duplicate_value_with_unique(self):
227 with self.assertRaises(ValueError):
228 class Color(Enum, settings=Unique):
229 red = 1
230 green = 2
231 blue = 3
232 rojo = 1
233
234 def test_duplicate_value_with_noalias(self):
235 class Color(Enum, settings=NoAlias):
236 red = 1
237 green = 2
238 blue = 3
239 rojo = 1
240 self.assertFalse(Color.red is Color.rojo)
241 self.assertEqual(Color.red.value, 1)
242 self.assertEqual(Color.rojo.value, 1)
243 self.assertEqual(len(Color), 4)
244 self.assertEqual(list(Color), [Color.red, Color.green, Color.blue, Color.rojo])
245
246 def test_noalias_value_lookup(self):
247 class Color(Enum, settings=NoAlias):
248 red = 1
249 green = 2
250 blue = 3
251 rojo = 1
252 self.assertRaises(TypeError, Color, 2)
253
254 def test_multivalue(self):
255 class Color(Enum, settings=MultiValue):
256 red = 1, 'red'
257 green = 2, 'green'
258 blue = 3, 'blue'
259 self.assertEqual(Color.red.value, 1)
260 self.assertIs(Color('green'), Color.green)
261 self.assertEqual(Color.blue.values, (3, 'blue'))
262
263 def test_multivalue_with_duplicate_values(self):
264 with self.assertRaises(ValueError):
265 class Color(Enum, settings=MultiValue):
266 red = 1, 'red'
267 green = 2, 'green'
268 blue = 3, 'blue', 'red'
269
270 def test_multivalue_with_duplicate_values_and_noalias(self):
271 with self.assertRaises(TypeError):
272 class Color(Enum, settings=(MultiValue, NoAlias)):
273 red = 1, 'red'
274 green = 2, 'green'
275 blue = 3, 'blue', 'red'
276
277 def test_multivalue_and_auto(self):
278 class Color(Enum, settings=(MultiValue, AutoValue)):
279 red
280 green = 3, 'green'
281 blue
282 self.assertEqual(Color.red.value, 1)
283 self.assertEqual(Color.green.value, 3)
284 self.assertEqual(Color.blue.value, 4)
285 self.assertIs(Color('green'), Color.green)
286 self.assertIs(Color['green'], Color.green)
287
288 def test_auto_and_init(self):
289 class Field(IntEnum, settings=AutoNumber, init='__doc__'):
290 TYPE = "Char, Date, Logical, etc."
291 START = "Field offset in record"
292 self.assertEqual(Field.TYPE, 1)
293 self.assertEqual(Field.START, 2)
294 self.assertEqual(Field.TYPE.__doc__, 'Char, Date, Logical, etc.')
295 self.assertEqual(Field.START.__doc__, 'Field offset in record')
296 self.assertFalse(hasattr(Field, '_order_'))
297
298 def test_auto_and_start(self):
299 class Field(IntEnum, init='__doc__', start=0):
300 TYPE = "Char, Date, Logical, etc."
301 START = "Field offset in record"
302 self.assertEqual(Field.TYPE, 0)
303 self.assertEqual(Field.START, 1)
304 self.assertEqual(Field.TYPE.__doc__, 'Char, Date, Logical, etc.')
305 self.assertEqual(Field.START.__doc__, 'Field offset in record')
306
307 def test_auto_and_init_and_some_values(self):
308 class Field(IntEnum, init='__doc__', settings=AutoNumber):
309 TYPE = "Char, Date, Logical, etc."
310 START = "Field offset in record"
311 BLAH = 5, "test blah"
312 BELCH = 'test belch'
313 self.assertEqual(Field.TYPE, 1)
314 self.assertEqual(Field.START, 2)
315 self.assertEqual(Field.BLAH, 5)
316 self.assertEqual(Field.BELCH, 6)
317 self.assertEqual(Field.TYPE.__doc__, 'Char, Date, Logical, etc.')
318 self.assertEqual(Field.START.__doc__, 'Field offset in record')
319 self.assertEqual(Field.BLAH.__doc__, 'test blah')
320 self.assertEqual(Field.BELCH.__doc__, 'test belch')
321
322 def test_autonumber_sans_init(self):
323 class Color(MagicAutoNumberEnum):
324 red = ()
325 green = ()
326 blue = ()
327 self.assertEqual(list(Color), [Color.red, Color.green, Color.blue])
328 self.assertEqual([m.value for m in Color], [1, 2, 3])
329 self.assertEqual([m.name for m in Color], ['red', 'green', 'blue'])
330
331 def test_autonumber_with_irregular_values(self):
332 class Point(MagicAutoNumberEnum, init='x y'):
333 first = 7, 9
334 second = 3, 11, 13
335 self.assertEqual(Point.first.value, 1)
336 self.assertEqual(Point.first.x, 7)
337 self.assertEqual(Point.first.y, 9)
338 self.assertEqual(Point.second.value, 3)
339 self.assertEqual(Point.second.x, 11)
340 self.assertEqual(Point.second.y, 13)
341 with self.assertRaisesRegex(TypeError, 'number of fields provided do not match init'):
342 class Color(MagicAutoNumberEnum, init='__doc__'):
343 red = ()
344 green = 'red'
345 blue = ()
346 with self.assertRaisesRegex(TypeError, 'number of fields provided do not match init'):
347 class Color(MagicAutoNumberEnum, init='__doc__ x y'):
348 red = 'red', 7, 9
349 green = 'green', 8
350 blue = 'blue', 11, 13
351 with self.assertRaisesRegex(TypeError, 'number of fields provided do not match init'):
352 class Color(MagicAutoNumberEnum, init='__doc__ x y'):
353 red = 'red', 7, 9
354 green = 8, 'green'
355 blue = 'blue', 11, 13
356
357 def test_autonumber_and_tuple(self):
358 class Color(MagicAutoNumberEnum):
359 red = ()
360 green = ()
361 blue = ()
362 self.assertEqual(Color.blue.value, 3)
363
364 def test_autonumber_and_property(self):
365 with self.assertRaises(TypeError):
366 class Color(MagicAutoNumberEnum):
367 _ignore_ = ()
368 red = ()
369 green = ()
370 blue = ()
371 @property
372 def cap_name(self) -> str:
373 return self.name.title()
374
375 def test_autoenum(self):
376 class Color(AutoEnum):
377 red
378 green
379 blue
380 self.assertEqual(list(Color), [Color.red, Color.green, Color.blue])
381 self.assertEqual([m.value for m in Color], [1, 2, 3])
382 self.assertEqual([m.name for m in Color], ['red', 'green', 'blue'])
383
384 def test_autoenum_with_str(self):
385 class Color(AutoEnum):
386 def _generate_next_value_(name, start, count, last_values):
387 return name
388 red
389 green
390 blue
391 self.assertEqual(list(Color), [Color.red, Color.green, Color.blue])
392 self.assertEqual([m.value for m in Color], ['red', 'green', 'blue'])
393 self.assertEqual([m.name for m in Color], ['red', 'green', 'blue'])
394
395 def test_autoenum_and_default_ignore(self):
396 class Color(AutoEnum):
397 red
398 green
399 blue
400 @property
401 def cap_name(self):
402 return self.name.title()
403 self.assertEqual(Color.blue.cap_name, 'Blue')
404
405 def test_autonumber_and_overridden_ignore(self):
406 with self.assertRaises(TypeError):
407 class Color(MagicAutoNumberEnum):
408 _ignore_ = 'staticmethod'
409 red
410 green
411 blue
412 @property
413 def cap_name(self) -> str:
414 return self.name.title()
415
416 def test_autonumber_and_multiple_assignment(self):
417 class Color(MagicAutoNumberEnum):
418 _ignore_ = 'property'
419 red
420 green
421 blue = cyan
422 @property
423 def cap_name(self) -> str:
424 return self.name.title()
425 self.assertEqual(Color.blue.cap_name, 'Cyan')
426
427 def test_combine_new_settings_with_old_settings(self):
428 class Auto(Enum, settings=Unique):
429 pass
430 with self.assertRaises(ValueError):
431 class AutoUnique(Auto, settings=AutoValue):
432 BLAH
433 BLUH
434 ICK = 1
435
436 def test_timedelta(self):
437 class Period(timedelta, Enum):
438 '''
439 different lengths of time
440 '''
441 _init_ = 'value period'
442 _settings_ = NoAlias
443 _ignore_ = 'Period i'
444 Period = vars()
445 for i in range(31):
446 Period['day_%d' % i] = i, 'day'
447 for i in range(15):
448 Period['week_%d' % i] = i*7, 'week'
449 for i in range(12):
450 Period['month_%d' % i] = i*30, 'month'
451 OneDay = day_1
452 OneWeek = week_1
453 self.assertFalse(hasattr(Period, '_ignore_'))
454 self.assertFalse(hasattr(Period, 'Period'))
455 self.assertFalse(hasattr(Period, 'i'))
456 self.assertTrue(isinstance(Period.day_1, timedelta))
457
458 def test_extend_enum_plain(self):
459 class Color(UniqueEnum):
460 red = 1
461 green = 2
462 blue = 3
463 extend_enum(Color, 'brown', 4)
464 self.assertEqual(Color.brown.name, 'brown')
465 self.assertEqual(Color.brown.value, 4)
466 self.assertTrue(Color.brown in Color)
467 self.assertEqual(len(Color), 4)
468
469 def test_extend_enum_shadow(self):
470 class Color(UniqueEnum):
471 red = 1
472 green = 2
473 blue = 3
474 extend_enum(Color, 'value', 4)
475 self.assertEqual(Color.value.name, 'value')
476 self.assertEqual(Color.value.value, 4)
477 self.assertTrue(Color.value in Color)
478 self.assertEqual(len(Color), 4)
479 self.assertEqual(Color.red.value, 1)
480
481 def test_extend_enum_generate(self):
482 class Foo(AutoEnum):
483 def _generate_next_value_(name, start, count, values, *args, **kwds):
484 return name
485 a
486 b
487 #
488 extend_enum(Foo, 'c')
489 self.assertEqual(Foo.a.value, 'a')
490 self.assertEqual(Foo.b.value, 'b')
491 self.assertEqual(Foo.c.value, 'c')
492
493 def test_extend_enum_unique_with_duplicate(self):
494 with self.assertRaises(ValueError):
495 class Color(Enum, settings=Unique):
496 red = 1
497 green = 2
498 blue = 3
499 extend_enum(Color, 'value', 1)
500
501 def test_extend_enum_multivalue_with_duplicate(self):
502 with self.assertRaises(ValueError):
503 class Color(Enum, settings=MultiValue):
504 red = 1, 'rojo'
505 green = 2, 'verde'
506 blue = 3, 'azul'
507 extend_enum(Color, 'value', 2)
508
509 def test_extend_enum_noalias_with_duplicate(self):
510 class Color(Enum, settings=NoAlias):
511 red = 1
512 green = 2
513 blue = 3
514 extend_enum(Color, 'value', 3, )
515 self.assertRaises(TypeError, Color, 3)
516 self.assertFalse(Color.value is Color.blue)
517 self.assertTrue(Color.value.value, 3)
518
519 def test_no_duplicates(self):
520 def bad_duplicates():
521 class Color(UniqueEnum):
522 red = 1
523 green = 2
524 blue = 3
525 class Color(UniqueEnum):
526 red = 1
527 green = 2
528 blue = 3
529 grene = 2
530 self.assertRaises(ValueError, bad_duplicates)
531
532 def test_no_duplicates_kinda(self):
533 class Silly(UniqueEnum):
534 one = 1
535 two = 'dos'
536 name = 3
537 class Sillier(IntEnum, UniqueEnum):
538 single = 1
539 name = 2
540 triple = 3
541 value = 4
542
543 def test_auto_number(self):
544 class Color(Enum, settings=AutoValue):
545 red
546 blue
547 green
548
549 self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
550 self.assertEqual(Color.red.value, 1)
551 self.assertEqual(Color.blue.value, 2)
552 self.assertEqual(Color.green.value, 3)
553
554 def test_auto_name(self):
555 class Color(Enum, settings=AutoValue):
556 def _generate_next_value_(name, start, count, last):
557 return name
558 red
559 blue
560 green
561
562 self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
563 self.assertEqual(Color.red.value, 'red')
564 self.assertEqual(Color.blue.value, 'blue')
565 self.assertEqual(Color.green.value, 'green')
566
567 def test_auto_name_inherit(self):
568 class AutoNameEnum(Enum):
569 def _generate_next_value_(name, start, count, last):
570 return name
571 class Color(AutoNameEnum, settings=AutoValue):
572 red
573 blue
574 green
575
576 self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
577 self.assertEqual(Color.red.value, 'red')
578 self.assertEqual(Color.blue.value, 'blue')
579 self.assertEqual(Color.green.value, 'green')
580
581 def test_auto_garbage(self):
582 class Color(Enum):
583 _settings_ = AutoValue
584 red = 'red'
585 blue
586 self.assertEqual(Color.blue.value, 1)
587
588 def test_auto_garbage_corrected(self):
589 class Color(Enum, settings=AutoValue):
590 red = 'red'
591 blue = 2
592 green
593
594 self.assertEqual(list(Color), [Color.red, Color.blue, Color.green])
595 self.assertEqual(Color.red.value, 'red')
596 self.assertEqual(Color.blue.value, 2)
597 self.assertEqual(Color.green.value, 3)
598
599 def test_duplicate_auto(self):
600 class Dupes(Enum, settings=AutoValue):
601 first = primero
602 second
603 third
604 self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes))
605
606 def test_order_as_function(self):
607 # first with _init_
608 class TestSequence(Enum):
609 _init_ = 'value, sequence'
610 _order_ = lambda member: member.sequence
611 item_id = 'An$(1,6)', 0 # Item Code
612 company_id = 'An$(7,2)', 1 # Company Code
613 warehouse_no = 'An$(9,4)', 2 # Warehouse Number
614 company = 'Hn$(13,6)', 3 # 4 SPACES + COMPANY
615 key_type = 'Cn$(19,3)', 4 # Key Type = '1**'
616 available = 'Zn$(1,1)', 5 # Available?
617 contract_item = 'Bn(2,1)', 6 # Contract Item?
618 sales_category = 'Fn', 7 # Sales Category
619 gl_category = 'Rn$(5,1)', 8 # G/L Category
620 warehouse_category = 'Sn$(6,1)', 9 # Warehouse Category
621 inv_units = 'Qn$(7,2)', 10 # Inv Units
622 for i, member in enumerate(TestSequence):
623 self.assertEqual(i, member.sequence)
624 ts = TestSequence
625 self.assertEqual(ts.item_id.name, 'item_id')
626 self.assertEqual(ts.item_id.value, 'An$(1,6)')
627 self.assertEqual(ts.item_id.sequence, 0)
628 self.assertEqual(ts.company_id.name, 'company_id')
629 self.assertEqual(ts.company_id.value, 'An$(7,2)')
630 self.assertEqual(ts.company_id.sequence, 1)
631 self.assertEqual(ts.warehouse_no.name, 'warehouse_no')
632 self.assertEqual(ts.warehouse_no.value, 'An$(9,4)')
633 self.assertEqual(ts.warehouse_no.sequence, 2)
634 self.assertEqual(ts.company.name, 'company')
635 self.assertEqual(ts.company.value, 'Hn$(13,6)')
636 self.assertEqual(ts.company.sequence, 3)
637 self.assertEqual(ts.key_type.name, 'key_type')
638 self.assertEqual(ts.key_type.value, 'Cn$(19,3)')
639 self.assertEqual(ts.key_type.sequence, 4)
640 self.assertEqual(ts.available.name, 'available')
641 self.assertEqual(ts.available.value, 'Zn$(1,1)')
642 self.assertEqual(ts.available.sequence, 5)
643 self.assertEqual(ts.contract_item.name, 'contract_item')
644 self.assertEqual(ts.contract_item.value, 'Bn(2,1)')
645 self.assertEqual(ts.contract_item.sequence, 6)
646 self.assertEqual(ts.sales_category.name, 'sales_category')
647 self.assertEqual(ts.sales_category.value, 'Fn')
648 self.assertEqual(ts.sales_category.sequence, 7)
649 self.assertEqual(ts.gl_category.name, 'gl_category')
650 self.assertEqual(ts.gl_category.value, 'Rn$(5,1)')
651 self.assertEqual(ts.gl_category.sequence, 8)
652 self.assertEqual(ts.warehouse_category.name, 'warehouse_category')
653 self.assertEqual(ts.warehouse_category.value, 'Sn$(6,1)')
654 self.assertEqual(ts.warehouse_category.sequence, 9)
655 self.assertEqual(ts.inv_units.name, 'inv_units')
656 self.assertEqual(ts.inv_units.value, 'Qn$(7,2)')
657 self.assertEqual(ts.inv_units.sequence, 10)
658 # and then without
659 class TestSequence(Enum):
660 _order_ = lambda member: member.value[1]
661 item_id = 'An$(1,6)', 0 # Item Code
662 company_id = 'An$(7,2)', 1 # Company Code
663 warehouse_no = 'An$(9,4)', 2 # Warehouse Number
664 company = 'Hn$(13,6)', 3 # 4 SPACES + COMPANY
665 key_type = 'Cn$(19,3)', 4 # Key Type = '1**'
666 available = 'Zn$(1,1)', 5 # Available?
667 contract_item = 'Bn(2,1)', 6 # Contract Item?
668 sales_category = 'Fn', 7 # Sales Category
669 gl_category = 'Rn$(5,1)', 8 # G/L Category
670 warehouse_category = 'Sn$(6,1)', 9 # Warehouse Category
671 inv_units = 'Qn$(7,2)', 10 # Inv Units
672 for i, member in enumerate(TestSequence):
673 self.assertEqual(i, member.value[1])
674 ts = TestSequence
675 self.assertEqual(ts.item_id.name, 'item_id')
676 self.assertEqual(ts.item_id.value, ('An$(1,6)', 0))
677 self.assertEqual(ts.company_id.name, 'company_id')
678 self.assertEqual(ts.company_id.value, ('An$(7,2)', 1))
679 self.assertEqual(ts.warehouse_no.name, 'warehouse_no')
680 self.assertEqual(ts.warehouse_no.value, ('An$(9,4)', 2))
681 self.assertEqual(ts.company.name, 'company')
682 self.assertEqual(ts.company.value, ('Hn$(13,6)', 3))
683 self.assertEqual(ts.key_type.name, 'key_type')
684 self.assertEqual(ts.key_type.value, ('Cn$(19,3)', 4))
685 self.assertEqual(ts.available.name, 'available')
686 self.assertEqual(ts.available.value, ('Zn$(1,1)', 5))
687 self.assertEqual(ts.contract_item.name, 'contract_item')
688 self.assertEqual(ts.contract_item.value, ('Bn(2,1)', 6))
689 self.assertEqual(ts.sales_category.name, 'sales_category')
690 self.assertEqual(ts.sales_category.value, ('Fn', 7))
691 self.assertEqual(ts.gl_category.name, 'gl_category')
692 self.assertEqual(ts.gl_category.value, ('Rn$(5,1)', 8))
693 self.assertEqual(ts.warehouse_category.name, 'warehouse_category')
694 self.assertEqual(ts.warehouse_category.value, ('Sn$(6,1)', 9))
695 self.assertEqual(ts.inv_units.name, 'inv_units')
696 self.assertEqual(ts.inv_units.value, ('Qn$(7,2)', 10))
697 # then with _init_ but without value
698 with self.assertRaises(TypeError):
699 class TestSequence(Enum):
700 _init_ = 'sequence'
701 _order_ = lambda member: member.sequence
702 item_id = 'An$(1,6)', 0 # Item Code
703 company_id = 'An$(7,2)', 1 # Company Code
704 warehouse_no = 'An$(9,4)', 2 # Warehouse Number
705 company = 'Hn$(13,6)', 3 # 4 SPACES + COMPANY
706 key_type = 'Cn$(19,3)', 4 # Key Type = '1**'
707 available = 'Zn$(1,1)', 5 # Available?
708 contract_item = 'Bn(2,1)', 6 # Contract Item?
709 sales_category = 'Fn', 7 # Sales Category
710 gl_category = 'Rn$(5,1)', 8 # G/L Category
711 warehouse_category = 'Sn$(6,1)', 9 # Warehouse Category
712 inv_units = 'Qn$(7,2)', 10 # Inv Units
713 # finally, out of order so Python 3 barfs
714 with self.assertRaises(TypeError):
715 class TestSequence(Enum):
716 _init_ = 'sequence'
717 _order_ = lambda member: member.sequence
718 item_id = 'An$(1,6)', 0 # Item Code
719 warehouse_no = 'An$(9,4)', 2 # Warehouse Number
720 company = 'Hn$(13,6)', 3 # 4 SPACES + COMPANY
721 company_id = 'An$(7,2)', 1 # Company Code
722 inv_units = 'Qn$(7,2)', 10 # Inv Units
723 available = 'Zn$(1,1)', 5 # Available?
724 contract_item = 'Bn(2,1)', 6 # Contract Item?
725 sales_category = 'Fn', 7 # Sales Category
726 key_type = 'Cn$(19,3)', 4 # Key Type = '1**'
727 gl_category = 'Rn$(5,1)', 8 # G/L Category
728 warehouse_category = 'Sn$(6,1)', 9 # Warehouse Category
729
730 if pyver >= 3.3:
731 def test_missing(self):
732 class Color(Enum):
733 red = 1
734 green = 2
735 blue = 3
736 @classmethod
737 def _missing_(cls, item):
738 if item == 'three':
739 return cls.blue
740 elif item == 'bad return':
741 # trigger internal error
742 return 5
743 elif item == 'error out':
744 raise ZeroDivisionError
745 else:
746 # trigger not found
747 return None
748 self.assertIs(Color('three'), Color.blue)
749 self.assertRaises(ValueError, Color, 7)
750 try:
751 Color('bad return')
752 except TypeError as exc:
753 self.assertTrue(isinstance(exc.__context__, ValueError))
754 else:
755 raise Exception('Exception not raised.')
756 try:
757 Color('error out')
758 except ZeroDivisionError as exc:
759 self.assertTrue(isinstance(exc.__context__, ValueError))
760 else:
761 raise Exception('Exception not raised.')
762
763 def test_enum_of_types(self):
764 """Support using Enum to refer to types deliberately."""
765 class MyTypes(Enum):
766 i = int
767 f = float
768 s = str
769 self.assertEqual(MyTypes.i.value, int)
770 self.assertEqual(MyTypes.f.value, float)
771 self.assertEqual(MyTypes.s.value, str)
772 class Foo:
773 pass
774 class Bar:
775 pass
776 class MyTypes2(Enum):
777 a = Foo
778 b = Bar
779 self.assertEqual(MyTypes2.a.value, Foo)
780 self.assertEqual(MyTypes2.b.value, Bar)
781 class SpamEnumNotInner:
782 pass
783 class SpamEnum(Enum):
784 spam = SpamEnumNotInner
785 self.assertEqual(SpamEnum.spam.value, SpamEnumNotInner)
786
787 def test_nested_classes_in_enum_do_not_create_members(self):
788 """Support locally-defined nested classes."""
789 # manually set __qualname__ to remove testing framework noise
790 class Outer(Enum):
791 __qualname__ = "Outer"
792 a = 1
793 b = 2
794 class Inner(Enum):
795 __qualname__ = "Outer.Inner"
796 foo = 10
797 bar = 11
798 self.assertTrue(isinstance(Outer.Inner, type))
799 self.assertEqual(Outer.a.value, 1)
800 self.assertEqual(Outer.Inner.foo.value, 10)
801 self.assertEqual(
802 list(Outer.Inner),
803 [Outer.Inner.foo, Outer.Inner.bar],
804 )
805 self.assertEqual(
806 list(Outer),
807 [Outer.a, Outer.b],
808 )
809
810 if pyver == 3.4:
811 def test_class_nested_enum_and_pickle_protocol_four(self):
812 # would normally just have this directly in the class namespace
813 class NestedEnum(Enum):
814 twigs = 'common'
815 shiny = 'rare'
816
817 self.__class__.NestedEnum = NestedEnum
818 self.NestedEnum.__qualname__ = '%s.NestedEnum' % self.__class__.__name__
819 test_pickle_exception(
820 self.assertRaises, PicklingError, self.NestedEnum.twigs,
821 protocol=(0, 3))
822 test_pickle_dump_load(self.assertTrue, self.NestedEnum.twigs,
823 protocol=(4, HIGHEST_PROTOCOL))
824
825 elif pyver >= 3.5:
826 def test_class_nested_enum_and_pickle_protocol_four(self):
827 # would normally just have this directly in the class namespace
828 class NestedEnum(Enum):
829 twigs = 'common'
830 shiny = 'rare'
831
832 self.__class__.NestedEnum = NestedEnum
833 self.NestedEnum.__qualname__ = '%s.NestedEnum' % self.__class__.__name__
834 test_pickle_dump_load(self.assertTrue, self.NestedEnum.twigs,
835 protocol=(0, HIGHEST_PROTOCOL))
836
837 if pyver >= 3.4:
838 def test_enum_injection(self):
839 class Color(Enum):
840 _order_ = 'BLACK WHITE'
841 BLACK = Color('black', '#000')
842 WHITE = Color('white', '#fff')
843
844 def __init__(self, label, hex):
845 self.label = label
846 self.hex = hex
847
848 self.assertEqual([Color.BLACK, Color.WHITE], list(Color))
849 self.assertEqual(Color.WHITE.hex, '#fff')
850 self.assertEqual(Color.BLACK.label, 'black')
851
852 def test_subclasses_with_getnewargs_ex(self):
853 class NamedInt(int):
854 __qualname__ = 'NamedInt' # needed for pickle protocol 4
855 def __new__(cls, *args):
856 _args = args
857 if len(args) < 2:
858 raise TypeError("name and value must be specified")
859 name, args = args[0], args[1:]
860 self = int.__new__(cls, *args)
861 self._intname = name
862 self._args = _args
863 return self
864 def __getnewargs_ex__(self):
865 return self._args, {}
866 @property
867 def __name__(self):
868 return self._intname
869 def __repr__(self):
870 # repr() is updated to include the name and type info
871 return "{}({!r}, {})".format(type(self).__name__,
872 self.__name__,
873 int.__repr__(self))
874 def __str__(self):
875 # str() is unchanged, even if it relies on the repr() fallback
876 base = int
877 base_str = base.__str__
878 if base_str.__objclass__ is object:
879 return base.__repr__(self)
880 return base_str(self)
881 # for simplicity, we only define one operator that
882 # propagates expressions
883 def __add__(self, other):
884 temp = int(self) + int( other)
885 if isinstance(self, NamedInt) and isinstance(other, NamedInt):
886 return NamedInt(
887 '({0} + {1})'.format(self.__name__, other.__name__),
888 temp )
889 else:
890 return temp
891
892 class NEI(NamedInt, Enum):
893 __qualname__ = 'NEI' # needed for pickle protocol 4
894 x = ('the-x', 1)
895 y = ('the-y', 2)
896
897
898 self.assertIs(NEI.__new__, Enum.__new__)
899 self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
900 globals()['NamedInt'] = NamedInt
901 globals()['NEI'] = NEI
902 NI5 = NamedInt('test', 5)
903 self.assertEqual(NI5, 5)
904 test_pickle_dump_load(self.assertEqual, NI5, 5, protocol=(4, HIGHEST_PROTOCOL))
905 self.assertEqual(NEI.y.value, 2)
906 test_pickle_dump_load(self.assertTrue, NEI.y, protocol=(4, HIGHEST_PROTOCOL))
907
908
909 class TestOrderV3(TestCase):
910
911 def test_same_members(self):
912 class Color(Enum):
913 _order_ = 'red green blue'
914 red = 1
915 green = 2
916 blue = 3
917
918 def test_same_members_with_aliases(self):
919 class Color(Enum):
920 _order_ = 'red green blue'
921 red = 1
922 green = 2
923 blue = 3
924 verde = green
925
926 def test_same_members_wrong_order(self):
927 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
928 class Color(Enum):
929 _order_ = 'red green blue'
930 red = 1
931 blue = 3
932 green = 2
933
934 def test_order_has_extra_members(self):
935 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
936 class Color(Enum):
937 _order_ = 'red green blue purple'
938 red = 1
939 green = 2
940 blue = 3
941
942 def test_order_has_extra_members_with_aliases(self):
943 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
944 class Color(Enum):
945 _order_ = 'red green blue purple'
946 red = 1
947 green = 2
948 blue = 3
949 verde = green
950
951 def test_enum_has_extra_members(self):
952 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
953 class Color(Enum):
954 _order_ = 'red green blue'
955 red = 1
956 green = 2
957 blue = 3
958 purple = 4
959
960 def test_enum_has_extra_members_with_aliases(self):
961 with self.assertRaisesRegex(TypeError, 'member order does not match _order_'):
962 class Color(Enum):
963 _order_ = 'red green blue'
964 red = 1
965 green = 2
966 blue = 3
967 purple = 4
968 verde = green
969
970
971 class TestNamedTupleV3(TestCase):
972
973 def test_fixed_size(self):
974 class Book(NamedTuple, size=TupleSize.fixed):
975 title = 0
976 author = 1
977 genre = 2
978 b = Book('Teckla', 'Steven Brust', 'fantasy')
979 self.assertTrue('Teckla' in b)
980 self.assertTrue('Steven Brust' in b)
981 self.assertTrue('fantasy' in b)
982 self.assertEqual(b.title, 'Teckla')
983 self.assertEqual(b.author, 'Steven Brust')
984 self.assertRaises(TypeError, Book, 'Teckla', 'Steven Brust')
985 self.assertRaises(TypeError, Book, 'Teckla')
986
987 def test_minimum_size(self):
988 class Book(NamedTuple, size=TupleSize.minimum):
989 title = 0
990 author = 1
991 b = Book('Teckla', 'Steven Brust', 'fantasy')
992 self.assertTrue('Teckla' in b)
993 self.assertTrue('Steven Brust' in b)
994 self.assertTrue('fantasy' in b)
995 self.assertEqual(b.title, 'Teckla')
996 self.assertEqual(b.author, 'Steven Brust')
997 self.assertEqual(b[2], 'fantasy')
998 b = Book('Teckla', 'Steven Brust')
999 self.assertTrue('Teckla' in b)
1000 self.assertTrue('Steven Brust' in b)
1001 self.assertEqual(b.title, 'Teckla')
1002 self.assertEqual(b.author, 'Steven Brust')
1003 self.assertRaises(TypeError, Book, 'Teckla')
1004
1005 def test_variable_size(self):
1006 class Book(NamedTuple, size=TupleSize.variable):
1007 title = 0
1008 author = 1
1009 genre = 2
1010 b = Book('Teckla', 'Steven Brust', 'fantasy')
1011 self.assertTrue('Teckla' in b)
1012 self.assertTrue('Steven Brust' in b)
1013 self.assertTrue('fantasy' in b)
1014 self.assertEqual(b.title, 'Teckla')
1015 self.assertEqual(b.author, 'Steven Brust')
1016 self.assertEqual(b.genre, 'fantasy')
1017 b = Book('Teckla', 'Steven Brust')
1018 self.assertTrue('Teckla' in b)
1019 self.assertTrue('Steven Brust' in b)
1020 self.assertEqual(b.title, 'Teckla')
1021 self.assertEqual(b.author, 'Steven Brust')
1022 self.assertRaises(AttributeError, getattr, b, 'genre')
1023 self.assertRaises(TypeError, Book, title='Teckla', genre='fantasy')
1024 self.assertRaises(TypeError, Book, author='Steven Brust')
1025
1026
1027 if __name__ == '__main__':
1028 main()