diff options
Diffstat (limited to 'Lib/test/test_enum.py')
-rw-r--r-- | Lib/test/test_enum.py | 777 |
1 files changed, 773 insertions, 4 deletions
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 630b155e5b..e97ef947b1 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -3,9 +3,10 @@ import inspect import pydoc import unittest from collections import OrderedDict -from enum import Enum, IntEnum, EnumMeta, unique +from enum import Enum, IntEnum, EnumMeta, Flag, IntFlag, unique, auto from io import StringIO from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL +from test import support # for pickle tests try: @@ -32,6 +33,14 @@ try: except Exception as exc: FloatStooges = exc +try: + class FlagStooges(Flag): + LARRY = 1 + CURLY = 2 + MOE = 3 +except Exception as exc: + FlagStooges = exc + # for pickle test and subclass tests try: class StrEnum(str, Enum): @@ -60,9 +69,9 @@ except Exception as exc: # for doctests try: class Fruit(Enum): - tomato = 1 - banana = 2 - cherry = 3 + TOMATO = 1 + BANANA = 2 + CHERRY = 3 except Exception: pass @@ -104,6 +113,7 @@ class TestHelpers(unittest.TestCase): '__', '___', '____', '_____',): self.assertFalse(enum._is_dunder(s)) +# tests class TestEnum(unittest.TestCase): @@ -283,6 +293,28 @@ class TestEnum(unittest.TestCase): class Wrong(Enum): _any_name_ = 9 + def test_bool(self): + # plain Enum members are always True + class Logic(Enum): + true = True + false = False + self.assertTrue(Logic.true) + self.assertTrue(Logic.false) + # unless overridden + class RealLogic(Enum): + true = True + false = False + def __bool__(self): + return bool(self._value_) + self.assertTrue(RealLogic.true) + self.assertFalse(RealLogic.false) + # mixed Enums depend on mixed-in type + class IntLogic(int, Enum): + true = 1 + false = 0 + self.assertTrue(IntLogic.true) + self.assertFalse(IntLogic.false) + def test_contains(self): Season = self.Season self.assertIn(Season.AUTUMN, Season) @@ -1547,6 +1579,701 @@ class TestEnum(unittest.TestCase): self.assertEqual(LabelledList.unprocessed, 1) self.assertEqual(LabelledList(1), LabelledList.unprocessed) + def test_auto_number(self): + class Color(Enum): + red = auto() + blue = auto() + green = auto() + + self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) + self.assertEqual(Color.red.value, 1) + self.assertEqual(Color.blue.value, 2) + self.assertEqual(Color.green.value, 3) + + def test_auto_name(self): + class Color(Enum): + def _generate_next_value_(name, start, count, last): + return name + red = auto() + blue = auto() + green = auto() + + self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) + self.assertEqual(Color.red.value, 'red') + self.assertEqual(Color.blue.value, 'blue') + self.assertEqual(Color.green.value, 'green') + + def test_auto_name_inherit(self): + class AutoNameEnum(Enum): + def _generate_next_value_(name, start, count, last): + return name + class Color(AutoNameEnum): + red = auto() + blue = auto() + green = auto() + + self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) + self.assertEqual(Color.red.value, 'red') + self.assertEqual(Color.blue.value, 'blue') + self.assertEqual(Color.green.value, 'green') + + def test_auto_garbage(self): + class Color(Enum): + red = 'red' + blue = auto() + self.assertEqual(Color.blue.value, 1) + + def test_auto_garbage_corrected(self): + class Color(Enum): + red = 'red' + blue = 2 + green = auto() + + self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) + self.assertEqual(Color.red.value, 'red') + self.assertEqual(Color.blue.value, 2) + self.assertEqual(Color.green.value, 3) + + def test_duplicate_auto(self): + class Dupes(Enum): + first = primero = auto() + second = auto() + third = auto() + self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes)) + + +class TestOrder(unittest.TestCase): + + def test_same_members(self): + class Color(Enum): + _order_ = 'red green blue' + red = 1 + green = 2 + blue = 3 + + def test_same_members_with_aliases(self): + class Color(Enum): + _order_ = 'red green blue' + red = 1 + green = 2 + blue = 3 + verde = green + + def test_same_members_wrong_order(self): + with self.assertRaisesRegex(TypeError, 'member order does not match _order_'): + class Color(Enum): + _order_ = 'red green blue' + red = 1 + blue = 3 + green = 2 + + def test_order_has_extra_members(self): + with self.assertRaisesRegex(TypeError, 'member order does not match _order_'): + class Color(Enum): + _order_ = 'red green blue purple' + red = 1 + green = 2 + blue = 3 + + def test_order_has_extra_members_with_aliases(self): + with self.assertRaisesRegex(TypeError, 'member order does not match _order_'): + class Color(Enum): + _order_ = 'red green blue purple' + red = 1 + green = 2 + blue = 3 + verde = green + + def test_enum_has_extra_members(self): + with self.assertRaisesRegex(TypeError, 'member order does not match _order_'): + class Color(Enum): + _order_ = 'red green blue' + red = 1 + green = 2 + blue = 3 + purple = 4 + + def test_enum_has_extra_members_with_aliases(self): + with self.assertRaisesRegex(TypeError, 'member order does not match _order_'): + class Color(Enum): + _order_ = 'red green blue' + red = 1 + green = 2 + blue = 3 + purple = 4 + verde = green + + +class TestFlag(unittest.TestCase): + """Tests of the Flags.""" + + class Perm(Flag): + R, W, X = 4, 2, 1 + + class Open(Flag): + RO = 0 + WO = 1 + RW = 2 + AC = 3 + CE = 1<<19 + + def test_str(self): + Perm = self.Perm + self.assertEqual(str(Perm.R), 'Perm.R') + self.assertEqual(str(Perm.W), 'Perm.W') + self.assertEqual(str(Perm.X), 'Perm.X') + self.assertEqual(str(Perm.R | Perm.W), 'Perm.R|W') + self.assertEqual(str(Perm.R | Perm.W | Perm.X), 'Perm.R|W|X') + self.assertEqual(str(Perm(0)), 'Perm.0') + self.assertEqual(str(~Perm.R), 'Perm.W|X') + self.assertEqual(str(~Perm.W), 'Perm.R|X') + self.assertEqual(str(~Perm.X), 'Perm.R|W') + self.assertEqual(str(~(Perm.R | Perm.W)), 'Perm.X') + self.assertEqual(str(~(Perm.R | Perm.W | Perm.X)), 'Perm.0') + self.assertEqual(str(Perm(~0)), 'Perm.R|W|X') + + Open = self.Open + self.assertEqual(str(Open.RO), 'Open.RO') + self.assertEqual(str(Open.WO), 'Open.WO') + self.assertEqual(str(Open.AC), 'Open.AC') + self.assertEqual(str(Open.RO | Open.CE), 'Open.CE') + self.assertEqual(str(Open.WO | Open.CE), 'Open.CE|WO') + self.assertEqual(str(~Open.RO), 'Open.CE|AC|RW|WO') + self.assertEqual(str(~Open.WO), 'Open.CE|RW') + self.assertEqual(str(~Open.AC), 'Open.CE') + self.assertEqual(str(~(Open.RO | Open.CE)), 'Open.AC') + self.assertEqual(str(~(Open.WO | Open.CE)), 'Open.RW') + + def test_repr(self): + Perm = self.Perm + self.assertEqual(repr(Perm.R), '<Perm.R: 4>') + self.assertEqual(repr(Perm.W), '<Perm.W: 2>') + self.assertEqual(repr(Perm.X), '<Perm.X: 1>') + self.assertEqual(repr(Perm.R | Perm.W), '<Perm.R|W: 6>') + self.assertEqual(repr(Perm.R | Perm.W | Perm.X), '<Perm.R|W|X: 7>') + self.assertEqual(repr(Perm(0)), '<Perm.0: 0>') + self.assertEqual(repr(~Perm.R), '<Perm.W|X: 3>') + self.assertEqual(repr(~Perm.W), '<Perm.R|X: 5>') + self.assertEqual(repr(~Perm.X), '<Perm.R|W: 6>') + self.assertEqual(repr(~(Perm.R | Perm.W)), '<Perm.X: 1>') + self.assertEqual(repr(~(Perm.R | Perm.W | Perm.X)), '<Perm.0: 0>') + self.assertEqual(repr(Perm(~0)), '<Perm.R|W|X: 7>') + + Open = self.Open + self.assertEqual(repr(Open.RO), '<Open.RO: 0>') + self.assertEqual(repr(Open.WO), '<Open.WO: 1>') + self.assertEqual(repr(Open.AC), '<Open.AC: 3>') + self.assertEqual(repr(Open.RO | Open.CE), '<Open.CE: 524288>') + self.assertEqual(repr(Open.WO | Open.CE), '<Open.CE|WO: 524289>') + self.assertEqual(repr(~Open.RO), '<Open.CE|AC|RW|WO: 524291>') + self.assertEqual(repr(~Open.WO), '<Open.CE|RW: 524290>') + self.assertEqual(repr(~Open.AC), '<Open.CE: 524288>') + self.assertEqual(repr(~(Open.RO | Open.CE)), '<Open.AC: 3>') + self.assertEqual(repr(~(Open.WO | Open.CE)), '<Open.RW: 2>') + + def test_or(self): + Perm = self.Perm + for i in Perm: + for j in Perm: + self.assertEqual((i | j), Perm(i.value | j.value)) + self.assertEqual((i | j).value, i.value | j.value) + self.assertIs(type(i | j), Perm) + for i in Perm: + self.assertIs(i | i, i) + Open = self.Open + self.assertIs(Open.RO | Open.CE, Open.CE) + + def test_and(self): + Perm = self.Perm + RW = Perm.R | Perm.W + RX = Perm.R | Perm.X + WX = Perm.W | Perm.X + RWX = Perm.R | Perm.W | Perm.X + values = list(Perm) + [RW, RX, WX, RWX, Perm(0)] + for i in values: + for j in values: + self.assertEqual((i & j).value, i.value & j.value) + self.assertIs(type(i & j), Perm) + for i in Perm: + self.assertIs(i & i, i) + self.assertIs(i & RWX, i) + self.assertIs(RWX & i, i) + Open = self.Open + self.assertIs(Open.RO & Open.CE, Open.RO) + + def test_xor(self): + Perm = self.Perm + for i in Perm: + for j in Perm: + self.assertEqual((i ^ j).value, i.value ^ j.value) + self.assertIs(type(i ^ j), Perm) + for i in Perm: + self.assertIs(i ^ Perm(0), i) + self.assertIs(Perm(0) ^ i, i) + Open = self.Open + self.assertIs(Open.RO ^ Open.CE, Open.CE) + self.assertIs(Open.CE ^ Open.CE, Open.RO) + + def test_invert(self): + Perm = self.Perm + RW = Perm.R | Perm.W + RX = Perm.R | Perm.X + WX = Perm.W | Perm.X + RWX = Perm.R | Perm.W | Perm.X + values = list(Perm) + [RW, RX, WX, RWX, Perm(0)] + for i in values: + self.assertIs(type(~i), Perm) + self.assertEqual(~~i, i) + for i in Perm: + self.assertIs(~~i, i) + Open = self.Open + self.assertIs(Open.WO & ~Open.WO, Open.RO) + self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE) + + def test_bool(self): + Perm = self.Perm + for f in Perm: + self.assertTrue(f) + Open = self.Open + for f in Open: + self.assertEqual(bool(f.value), bool(f)) + + def test_programatic_function_string(self): + Perm = Flag('Perm', 'R W X') + lst = list(Perm) + self.assertEqual(len(lst), len(Perm)) + self.assertEqual(len(Perm), 3, Perm) + self.assertEqual(lst, [Perm.R, Perm.W, Perm.X]) + for i, n in enumerate('R W X'.split()): + v = 1<<i + e = Perm(v) + self.assertEqual(e.value, v) + self.assertEqual(type(e.value), int) + self.assertEqual(e.name, n) + self.assertIn(e, Perm) + self.assertIs(type(e), Perm) + + def test_programatic_function_string_with_start(self): + Perm = Flag('Perm', 'R W X', start=8) + lst = list(Perm) + self.assertEqual(len(lst), len(Perm)) + self.assertEqual(len(Perm), 3, Perm) + self.assertEqual(lst, [Perm.R, Perm.W, Perm.X]) + for i, n in enumerate('R W X'.split()): + v = 8<<i + e = Perm(v) + self.assertEqual(e.value, v) + self.assertEqual(type(e.value), int) + self.assertEqual(e.name, n) + self.assertIn(e, Perm) + self.assertIs(type(e), Perm) + + def test_programatic_function_string_list(self): + Perm = Flag('Perm', ['R', 'W', 'X']) + lst = list(Perm) + self.assertEqual(len(lst), len(Perm)) + self.assertEqual(len(Perm), 3, Perm) + self.assertEqual(lst, [Perm.R, Perm.W, Perm.X]) + for i, n in enumerate('R W X'.split()): + v = 1<<i + e = Perm(v) + self.assertEqual(e.value, v) + self.assertEqual(type(e.value), int) + self.assertEqual(e.name, n) + self.assertIn(e, Perm) + self.assertIs(type(e), Perm) + + def test_programatic_function_iterable(self): + Perm = Flag('Perm', (('R', 2), ('W', 8), ('X', 32))) + lst = list(Perm) + self.assertEqual(len(lst), len(Perm)) + self.assertEqual(len(Perm), 3, Perm) + self.assertEqual(lst, [Perm.R, Perm.W, Perm.X]) + for i, n in enumerate('R W X'.split()): + v = 1<<(2*i+1) + e = Perm(v) + self.assertEqual(e.value, v) + self.assertEqual(type(e.value), int) + self.assertEqual(e.name, n) + self.assertIn(e, Perm) + self.assertIs(type(e), Perm) + + def test_programatic_function_from_dict(self): + Perm = Flag('Perm', OrderedDict((('R', 2), ('W', 8), ('X', 32)))) + lst = list(Perm) + self.assertEqual(len(lst), len(Perm)) + self.assertEqual(len(Perm), 3, Perm) + self.assertEqual(lst, [Perm.R, Perm.W, Perm.X]) + for i, n in enumerate('R W X'.split()): + v = 1<<(2*i+1) + e = Perm(v) + self.assertEqual(e.value, v) + self.assertEqual(type(e.value), int) + self.assertEqual(e.name, n) + self.assertIn(e, Perm) + self.assertIs(type(e), Perm) + + def test_pickle(self): + if isinstance(FlagStooges, Exception): + raise FlagStooges + test_pickle_dump_load(self.assertIs, FlagStooges.CURLY|FlagStooges.MOE) + test_pickle_dump_load(self.assertIs, FlagStooges) + + def test_containment(self): + Perm = self.Perm + R, W, X = Perm + RW = R | W + RX = R | X + WX = W | X + RWX = R | W | X + self.assertTrue(R in RW) + self.assertTrue(R in RX) + self.assertTrue(R in RWX) + self.assertTrue(W in RW) + self.assertTrue(W in WX) + self.assertTrue(W in RWX) + self.assertTrue(X in RX) + self.assertTrue(X in WX) + self.assertTrue(X in RWX) + self.assertFalse(R in WX) + self.assertFalse(W in RX) + self.assertFalse(X in RW) + + def test_auto_number(self): + class Color(Flag): + red = auto() + blue = auto() + green = auto() + + self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) + self.assertEqual(Color.red.value, 1) + self.assertEqual(Color.blue.value, 2) + self.assertEqual(Color.green.value, 4) + + def test_auto_number_garbage(self): + with self.assertRaisesRegex(TypeError, 'Invalid Flag value: .not an int.'): + class Color(Flag): + red = 'not an int' + blue = auto() + + def test_cascading_failure(self): + class Bizarre(Flag): + c = 3 + d = 4 + f = 6 + # Bizarre.c | Bizarre.d + self.assertRaisesRegex(ValueError, "5 is not a valid Bizarre", Bizarre, 5) + self.assertRaisesRegex(ValueError, "5 is not a valid Bizarre", Bizarre, 5) + self.assertRaisesRegex(ValueError, "2 is not a valid Bizarre", Bizarre, 2) + self.assertRaisesRegex(ValueError, "2 is not a valid Bizarre", Bizarre, 2) + self.assertRaisesRegex(ValueError, "1 is not a valid Bizarre", Bizarre, 1) + self.assertRaisesRegex(ValueError, "1 is not a valid Bizarre", Bizarre, 1) + + def test_duplicate_auto(self): + class Dupes(Enum): + first = primero = auto() + second = auto() + third = auto() + self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes)) + + def test_bizarre(self): + class Bizarre(Flag): + b = 3 + c = 4 + d = 6 + self.assertEqual(repr(Bizarre(7)), '<Bizarre.d|c|b: 7>') + + +class TestIntFlag(unittest.TestCase): + """Tests of the IntFlags.""" + + class Perm(IntFlag): + X = 1 << 0 + W = 1 << 1 + R = 1 << 2 + + class Open(IntFlag): + RO = 0 + WO = 1 + RW = 2 + AC = 3 + CE = 1<<19 + + def test_type(self): + Perm = self.Perm + Open = self.Open + for f in Perm: + self.assertTrue(isinstance(f, Perm)) + self.assertEqual(f, f.value) + self.assertTrue(isinstance(Perm.W | Perm.X, Perm)) + self.assertEqual(Perm.W | Perm.X, 3) + for f in Open: + self.assertTrue(isinstance(f, Open)) + self.assertEqual(f, f.value) + self.assertTrue(isinstance(Open.WO | Open.RW, Open)) + self.assertEqual(Open.WO | Open.RW, 3) + + + def test_str(self): + Perm = self.Perm + self.assertEqual(str(Perm.R), 'Perm.R') + self.assertEqual(str(Perm.W), 'Perm.W') + self.assertEqual(str(Perm.X), 'Perm.X') + self.assertEqual(str(Perm.R | Perm.W), 'Perm.R|W') + self.assertEqual(str(Perm.R | Perm.W | Perm.X), 'Perm.R|W|X') + self.assertEqual(str(Perm.R | 8), 'Perm.8|R') + self.assertEqual(str(Perm(0)), 'Perm.0') + self.assertEqual(str(Perm(8)), 'Perm.8') + self.assertEqual(str(~Perm.R), 'Perm.W|X') + self.assertEqual(str(~Perm.W), 'Perm.R|X') + self.assertEqual(str(~Perm.X), 'Perm.R|W') + self.assertEqual(str(~(Perm.R | Perm.W)), 'Perm.X') + self.assertEqual(str(~(Perm.R | Perm.W | Perm.X)), 'Perm.-8') + self.assertEqual(str(~(Perm.R | 8)), 'Perm.W|X') + self.assertEqual(str(Perm(~0)), 'Perm.R|W|X') + self.assertEqual(str(Perm(~8)), 'Perm.R|W|X') + + Open = self.Open + self.assertEqual(str(Open.RO), 'Open.RO') + self.assertEqual(str(Open.WO), 'Open.WO') + self.assertEqual(str(Open.AC), 'Open.AC') + self.assertEqual(str(Open.RO | Open.CE), 'Open.CE') + self.assertEqual(str(Open.WO | Open.CE), 'Open.CE|WO') + self.assertEqual(str(Open(4)), 'Open.4') + self.assertEqual(str(~Open.RO), 'Open.CE|AC|RW|WO') + self.assertEqual(str(~Open.WO), 'Open.CE|RW') + self.assertEqual(str(~Open.AC), 'Open.CE') + self.assertEqual(str(~(Open.RO | Open.CE)), 'Open.AC|RW|WO') + self.assertEqual(str(~(Open.WO | Open.CE)), 'Open.RW') + self.assertEqual(str(Open(~4)), 'Open.CE|AC|RW|WO') + + def test_repr(self): + Perm = self.Perm + self.assertEqual(repr(Perm.R), '<Perm.R: 4>') + self.assertEqual(repr(Perm.W), '<Perm.W: 2>') + self.assertEqual(repr(Perm.X), '<Perm.X: 1>') + self.assertEqual(repr(Perm.R | Perm.W), '<Perm.R|W: 6>') + self.assertEqual(repr(Perm.R | Perm.W | Perm.X), '<Perm.R|W|X: 7>') + self.assertEqual(repr(Perm.R | 8), '<Perm.8|R: 12>') + self.assertEqual(repr(Perm(0)), '<Perm.0: 0>') + self.assertEqual(repr(Perm(8)), '<Perm.8: 8>') + self.assertEqual(repr(~Perm.R), '<Perm.W|X: -5>') + self.assertEqual(repr(~Perm.W), '<Perm.R|X: -3>') + self.assertEqual(repr(~Perm.X), '<Perm.R|W: -2>') + self.assertEqual(repr(~(Perm.R | Perm.W)), '<Perm.X: -7>') + self.assertEqual(repr(~(Perm.R | Perm.W | Perm.X)), '<Perm.-8: -8>') + self.assertEqual(repr(~(Perm.R | 8)), '<Perm.W|X: -13>') + self.assertEqual(repr(Perm(~0)), '<Perm.R|W|X: -1>') + self.assertEqual(repr(Perm(~8)), '<Perm.R|W|X: -9>') + + Open = self.Open + self.assertEqual(repr(Open.RO), '<Open.RO: 0>') + self.assertEqual(repr(Open.WO), '<Open.WO: 1>') + self.assertEqual(repr(Open.AC), '<Open.AC: 3>') + self.assertEqual(repr(Open.RO | Open.CE), '<Open.CE: 524288>') + self.assertEqual(repr(Open.WO | Open.CE), '<Open.CE|WO: 524289>') + self.assertEqual(repr(Open(4)), '<Open.4: 4>') + self.assertEqual(repr(~Open.RO), '<Open.CE|AC|RW|WO: -1>') + self.assertEqual(repr(~Open.WO), '<Open.CE|RW: -2>') + self.assertEqual(repr(~Open.AC), '<Open.CE: -4>') + self.assertEqual(repr(~(Open.RO | Open.CE)), '<Open.AC|RW|WO: -524289>') + self.assertEqual(repr(~(Open.WO | Open.CE)), '<Open.RW: -524290>') + self.assertEqual(repr(Open(~4)), '<Open.CE|AC|RW|WO: -5>') + + def test_or(self): + Perm = self.Perm + for i in Perm: + for j in Perm: + self.assertEqual(i | j, i.value | j.value) + self.assertEqual((i | j).value, i.value | j.value) + self.assertIs(type(i | j), Perm) + for j in range(8): + self.assertEqual(i | j, i.value | j) + self.assertEqual((i | j).value, i.value | j) + self.assertIs(type(i | j), Perm) + self.assertEqual(j | i, j | i.value) + self.assertEqual((j | i).value, j | i.value) + self.assertIs(type(j | i), Perm) + for i in Perm: + self.assertIs(i | i, i) + self.assertIs(i | 0, i) + self.assertIs(0 | i, i) + Open = self.Open + self.assertIs(Open.RO | Open.CE, Open.CE) + + def test_and(self): + Perm = self.Perm + RW = Perm.R | Perm.W + RX = Perm.R | Perm.X + WX = Perm.W | Perm.X + RWX = Perm.R | Perm.W | Perm.X + values = list(Perm) + [RW, RX, WX, RWX, Perm(0)] + for i in values: + for j in values: + self.assertEqual(i & j, i.value & j.value, 'i is %r, j is %r' % (i, j)) + self.assertEqual((i & j).value, i.value & j.value, 'i is %r, j is %r' % (i, j)) + self.assertIs(type(i & j), Perm, 'i is %r, j is %r' % (i, j)) + for j in range(8): + self.assertEqual(i & j, i.value & j) + self.assertEqual((i & j).value, i.value & j) + self.assertIs(type(i & j), Perm) + self.assertEqual(j & i, j & i.value) + self.assertEqual((j & i).value, j & i.value) + self.assertIs(type(j & i), Perm) + for i in Perm: + self.assertIs(i & i, i) + self.assertIs(i & 7, i) + self.assertIs(7 & i, i) + Open = self.Open + self.assertIs(Open.RO & Open.CE, Open.RO) + + def test_xor(self): + Perm = self.Perm + for i in Perm: + for j in Perm: + self.assertEqual(i ^ j, i.value ^ j.value) + self.assertEqual((i ^ j).value, i.value ^ j.value) + self.assertIs(type(i ^ j), Perm) + for j in range(8): + self.assertEqual(i ^ j, i.value ^ j) + self.assertEqual((i ^ j).value, i.value ^ j) + self.assertIs(type(i ^ j), Perm) + self.assertEqual(j ^ i, j ^ i.value) + self.assertEqual((j ^ i).value, j ^ i.value) + self.assertIs(type(j ^ i), Perm) + for i in Perm: + self.assertIs(i ^ 0, i) + self.assertIs(0 ^ i, i) + Open = self.Open + self.assertIs(Open.RO ^ Open.CE, Open.CE) + self.assertIs(Open.CE ^ Open.CE, Open.RO) + + def test_invert(self): + Perm = self.Perm + RW = Perm.R | Perm.W + RX = Perm.R | Perm.X + WX = Perm.W | Perm.X + RWX = Perm.R | Perm.W | Perm.X + values = list(Perm) + [RW, RX, WX, RWX, Perm(0)] + for i in values: + self.assertEqual(~i, ~i.value) + self.assertEqual((~i).value, ~i.value) + self.assertIs(type(~i), Perm) + self.assertEqual(~~i, i) + for i in Perm: + self.assertIs(~~i, i) + Open = self.Open + self.assertIs(Open.WO & ~Open.WO, Open.RO) + self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE) + + def test_programatic_function_string(self): + Perm = IntFlag('Perm', 'R W X') + lst = list(Perm) + self.assertEqual(len(lst), len(Perm)) + self.assertEqual(len(Perm), 3, Perm) + self.assertEqual(lst, [Perm.R, Perm.W, Perm.X]) + for i, n in enumerate('R W X'.split()): + v = 1<<i + e = Perm(v) + self.assertEqual(e.value, v) + self.assertEqual(type(e.value), int) + self.assertEqual(e, v) + self.assertEqual(e.name, n) + self.assertIn(e, Perm) + self.assertIs(type(e), Perm) + + def test_programatic_function_string_with_start(self): + Perm = IntFlag('Perm', 'R W X', start=8) + lst = list(Perm) + self.assertEqual(len(lst), len(Perm)) + self.assertEqual(len(Perm), 3, Perm) + self.assertEqual(lst, [Perm.R, Perm.W, Perm.X]) + for i, n in enumerate('R W X'.split()): + v = 8<<i + e = Perm(v) + self.assertEqual(e.value, v) + self.assertEqual(type(e.value), int) + self.assertEqual(e, v) + self.assertEqual(e.name, n) + self.assertIn(e, Perm) + self.assertIs(type(e), Perm) + + def test_programatic_function_string_list(self): + Perm = IntFlag('Perm', ['R', 'W', 'X']) + lst = list(Perm) + self.assertEqual(len(lst), len(Perm)) + self.assertEqual(len(Perm), 3, Perm) + self.assertEqual(lst, [Perm.R, Perm.W, Perm.X]) + for i, n in enumerate('R W X'.split()): + v = 1<<i + e = Perm(v) + self.assertEqual(e.value, v) + self.assertEqual(type(e.value), int) + self.assertEqual(e, v) + self.assertEqual(e.name, n) + self.assertIn(e, Perm) + self.assertIs(type(e), Perm) + + def test_programatic_function_iterable(self): + Perm = IntFlag('Perm', (('R', 2), ('W', 8), ('X', 32))) + lst = list(Perm) + self.assertEqual(len(lst), len(Perm)) + self.assertEqual(len(Perm), 3, Perm) + self.assertEqual(lst, [Perm.R, Perm.W, Perm.X]) + for i, n in enumerate('R W X'.split()): + v = 1<<(2*i+1) + e = Perm(v) + self.assertEqual(e.value, v) + self.assertEqual(type(e.value), int) + self.assertEqual(e, v) + self.assertEqual(e.name, n) + self.assertIn(e, Perm) + self.assertIs(type(e), Perm) + + def test_programatic_function_from_dict(self): + Perm = IntFlag('Perm', OrderedDict((('R', 2), ('W', 8), ('X', 32)))) + lst = list(Perm) + self.assertEqual(len(lst), len(Perm)) + self.assertEqual(len(Perm), 3, Perm) + self.assertEqual(lst, [Perm.R, Perm.W, Perm.X]) + for i, n in enumerate('R W X'.split()): + v = 1<<(2*i+1) + e = Perm(v) + self.assertEqual(e.value, v) + self.assertEqual(type(e.value), int) + self.assertEqual(e, v) + self.assertEqual(e.name, n) + self.assertIn(e, Perm) + self.assertIs(type(e), Perm) + + + def test_containment(self): + Perm = self.Perm + R, W, X = Perm + RW = R | W + RX = R | X + WX = W | X + RWX = R | W | X + self.assertTrue(R in RW) + self.assertTrue(R in RX) + self.assertTrue(R in RWX) + self.assertTrue(W in RW) + self.assertTrue(W in WX) + self.assertTrue(W in RWX) + self.assertTrue(X in RX) + self.assertTrue(X in WX) + self.assertTrue(X in RWX) + self.assertFalse(R in WX) + self.assertFalse(W in RX) + self.assertFalse(X in RW) + + def test_bool(self): + Perm = self.Perm + for f in Perm: + self.assertTrue(f) + Open = self.Open + for f in Open: + self.assertEqual(bool(f.value), bool(f)) class TestUnique(unittest.TestCase): @@ -1739,5 +2466,47 @@ class TestStdLib(unittest.TestCase): if failed: self.fail("result does not equal expected, see print above") + +class MiscTestCase(unittest.TestCase): + def test__all__(self): + support.check__all__(self, enum) + + +# These are unordered here on purpose to ensure that declaration order +# makes no difference. +CONVERT_TEST_NAME_D = 5 +CONVERT_TEST_NAME_C = 5 +CONVERT_TEST_NAME_B = 5 +CONVERT_TEST_NAME_A = 5 # This one should sort first. +CONVERT_TEST_NAME_E = 5 +CONVERT_TEST_NAME_F = 5 + +class TestIntEnumConvert(unittest.TestCase): + def test_convert_value_lookup_priority(self): + test_type = enum.IntEnum._convert( + 'UnittestConvert', 'test.test_enum', + filter=lambda x: x.startswith('CONVERT_TEST_')) + # We don't want the reverse lookup value to vary when there are + # multiple possible names for a given value. It should always + # report the first lexigraphical name in that case. + self.assertEqual(test_type(5).name, 'CONVERT_TEST_NAME_A') + + def test_convert(self): + test_type = enum.IntEnum._convert( + 'UnittestConvert', 'test.test_enum', + filter=lambda x: x.startswith('CONVERT_TEST_')) + # Ensure that test_type has all of the desired names and values. + self.assertEqual(test_type.CONVERT_TEST_NAME_F, + test_type.CONVERT_TEST_NAME_A) + self.assertEqual(test_type.CONVERT_TEST_NAME_B, 5) + self.assertEqual(test_type.CONVERT_TEST_NAME_C, 5) + self.assertEqual(test_type.CONVERT_TEST_NAME_D, 5) + self.assertEqual(test_type.CONVERT_TEST_NAME_E, 5) + # Ensure that test_type only picked up names matching the filter. + self.assertEqual([name for name in dir(test_type) + if name[0:2] not in ('CO', '__')], + [], msg='Names other than CONVERT_TEST_* found.') + + if __name__ == '__main__': unittest.main() |