ยปCore Development>Code coverage>Lib/test/test_enum.py

Python code coverage for Lib/test/test_enum.py

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