merge
This commit is contained in:
commit
264683ef0a
|
@ -463,6 +463,12 @@ Some rules:
|
||||||
3. When another data type is mixed in, the :attr:`value` attribute is *not the
|
3. When another data type is mixed in, the :attr:`value` attribute is *not the
|
||||||
same* as the enum member itself, although it is equivalant and will compare
|
same* as the enum member itself, although it is equivalant and will compare
|
||||||
equal.
|
equal.
|
||||||
|
4. %-style formatting: `%s` and `%r` call :class:`Enum`'s :meth:`__str__` and
|
||||||
|
:meth:`__repr__` respectively; other codes (such as `%i` or `%h` for
|
||||||
|
IntEnum) treat the enum member as its mixed-in type.
|
||||||
|
5. :class:`str`.:meth:`__format__` (or :func:`format`) will use the mixed-in
|
||||||
|
type's :meth:`__format__`. If the :class:`Enum`'s :func:`str` or
|
||||||
|
:func:`repr` is desired use the `!s` or `!r` :class:`str` format codes.
|
||||||
|
|
||||||
|
|
||||||
Interesting examples
|
Interesting examples
|
||||||
|
|
18
Lib/enum.py
18
Lib/enum.py
|
@ -50,7 +50,6 @@ def _make_class_unpicklable(cls):
|
||||||
cls.__reduce__ = _break_on_call_reduce
|
cls.__reduce__ = _break_on_call_reduce
|
||||||
cls.__module__ = '<unknown>'
|
cls.__module__ = '<unknown>'
|
||||||
|
|
||||||
|
|
||||||
class _EnumDict(dict):
|
class _EnumDict(dict):
|
||||||
"""Keeps track of definition order of the enum items.
|
"""Keeps track of definition order of the enum items.
|
||||||
|
|
||||||
|
@ -182,7 +181,7 @@ class EnumMeta(type):
|
||||||
|
|
||||||
# double check that repr and friends are not the mixin's or various
|
# double check that repr and friends are not the mixin's or various
|
||||||
# things break (such as pickle)
|
# things break (such as pickle)
|
||||||
for name in ('__repr__', '__str__', '__getnewargs__'):
|
for name in ('__repr__', '__str__', '__format__', '__getnewargs__'):
|
||||||
class_method = getattr(enum_class, name)
|
class_method = getattr(enum_class, name)
|
||||||
obj_method = getattr(member_type, name, None)
|
obj_method = getattr(member_type, name, None)
|
||||||
enum_method = getattr(first_enum, name, None)
|
enum_method = getattr(first_enum, name, None)
|
||||||
|
@ -441,6 +440,21 @@ class Enum(metaclass=EnumMeta):
|
||||||
return self is other
|
return self is other
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
|
def __format__(self, format_spec):
|
||||||
|
# mixed-in Enums should use the mixed-in type's __format__, otherwise
|
||||||
|
# we can get strange results with the Enum name showing up instead of
|
||||||
|
# the value
|
||||||
|
|
||||||
|
# pure Enum branch
|
||||||
|
if self._member_type_ is object:
|
||||||
|
cls = str
|
||||||
|
val = str(self)
|
||||||
|
# mix-in branch
|
||||||
|
else:
|
||||||
|
cls = self._member_type_
|
||||||
|
val = self.value
|
||||||
|
return cls.__format__(val, format_spec)
|
||||||
|
|
||||||
def __getnewargs__(self):
|
def __getnewargs__(self):
|
||||||
return (self._value_, )
|
return (self._value_, )
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,33 @@ class TestEnum(unittest.TestCase):
|
||||||
WINTER = 4
|
WINTER = 4
|
||||||
self.Season = Season
|
self.Season = Season
|
||||||
|
|
||||||
|
class Konstants(float, Enum):
|
||||||
|
E = 2.7182818
|
||||||
|
PI = 3.1415926
|
||||||
|
TAU = 2 * PI
|
||||||
|
self.Konstants = Konstants
|
||||||
|
|
||||||
|
class Grades(IntEnum):
|
||||||
|
A = 5
|
||||||
|
B = 4
|
||||||
|
C = 3
|
||||||
|
D = 2
|
||||||
|
F = 0
|
||||||
|
self.Grades = Grades
|
||||||
|
|
||||||
|
class Directional(str, Enum):
|
||||||
|
EAST = 'east'
|
||||||
|
WEST = 'west'
|
||||||
|
NORTH = 'north'
|
||||||
|
SOUTH = 'south'
|
||||||
|
self.Directional = Directional
|
||||||
|
|
||||||
|
from datetime import date
|
||||||
|
class Holiday(date, Enum):
|
||||||
|
NEW_YEAR = 2013, 1, 1
|
||||||
|
IDES_OF_MARCH = 2013, 3, 15
|
||||||
|
self.Holiday = Holiday
|
||||||
|
|
||||||
def test_dir_on_class(self):
|
def test_dir_on_class(self):
|
||||||
Season = self.Season
|
Season = self.Season
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
@ -207,6 +234,77 @@ class TestEnum(unittest.TestCase):
|
||||||
self.assertIs(type(Huh.name), Huh)
|
self.assertIs(type(Huh.name), Huh)
|
||||||
self.assertEqual(Huh.name.name, 'name')
|
self.assertEqual(Huh.name.name, 'name')
|
||||||
self.assertEqual(Huh.name.value, 1)
|
self.assertEqual(Huh.name.value, 1)
|
||||||
|
|
||||||
|
def test_format_enum(self):
|
||||||
|
Season = self.Season
|
||||||
|
self.assertEqual('{}'.format(Season.SPRING),
|
||||||
|
'{}'.format(str(Season.SPRING)))
|
||||||
|
self.assertEqual( '{:}'.format(Season.SPRING),
|
||||||
|
'{:}'.format(str(Season.SPRING)))
|
||||||
|
self.assertEqual('{:20}'.format(Season.SPRING),
|
||||||
|
'{:20}'.format(str(Season.SPRING)))
|
||||||
|
self.assertEqual('{:^20}'.format(Season.SPRING),
|
||||||
|
'{:^20}'.format(str(Season.SPRING)))
|
||||||
|
self.assertEqual('{:>20}'.format(Season.SPRING),
|
||||||
|
'{:>20}'.format(str(Season.SPRING)))
|
||||||
|
self.assertEqual('{:<20}'.format(Season.SPRING),
|
||||||
|
'{:<20}'.format(str(Season.SPRING)))
|
||||||
|
|
||||||
|
def test_format_enum_custom(self):
|
||||||
|
class TestFloat(float, Enum):
|
||||||
|
one = 1.0
|
||||||
|
two = 2.0
|
||||||
|
def __format__(self, spec):
|
||||||
|
return 'TestFloat success!'
|
||||||
|
self.assertEqual('{}'.format(TestFloat.one), 'TestFloat success!')
|
||||||
|
|
||||||
|
def assertFormatIsValue(self, spec, member):
|
||||||
|
self.assertEqual(spec.format(member), spec.format(member.value))
|
||||||
|
|
||||||
|
def test_format_enum_date(self):
|
||||||
|
Holiday = self.Holiday
|
||||||
|
self.assertFormatIsValue('{}', Holiday.IDES_OF_MARCH)
|
||||||
|
self.assertFormatIsValue('{:}', Holiday.IDES_OF_MARCH)
|
||||||
|
self.assertFormatIsValue('{:20}', Holiday.IDES_OF_MARCH)
|
||||||
|
self.assertFormatIsValue('{:^20}', Holiday.IDES_OF_MARCH)
|
||||||
|
self.assertFormatIsValue('{:>20}', Holiday.IDES_OF_MARCH)
|
||||||
|
self.assertFormatIsValue('{:<20}', Holiday.IDES_OF_MARCH)
|
||||||
|
self.assertFormatIsValue('{:%Y %m}', Holiday.IDES_OF_MARCH)
|
||||||
|
self.assertFormatIsValue('{:%Y %m %M:00}', Holiday.IDES_OF_MARCH)
|
||||||
|
|
||||||
|
def test_format_enum_float(self):
|
||||||
|
Konstants = self.Konstants
|
||||||
|
self.assertFormatIsValue('{}', Konstants.TAU)
|
||||||
|
self.assertFormatIsValue('{:}', Konstants.TAU)
|
||||||
|
self.assertFormatIsValue('{:20}', Konstants.TAU)
|
||||||
|
self.assertFormatIsValue('{:^20}', Konstants.TAU)
|
||||||
|
self.assertFormatIsValue('{:>20}', Konstants.TAU)
|
||||||
|
self.assertFormatIsValue('{:<20}', Konstants.TAU)
|
||||||
|
self.assertFormatIsValue('{:n}', Konstants.TAU)
|
||||||
|
self.assertFormatIsValue('{:5.2}', Konstants.TAU)
|
||||||
|
self.assertFormatIsValue('{:f}', Konstants.TAU)
|
||||||
|
|
||||||
|
def test_format_enum_int(self):
|
||||||
|
Grades = self.Grades
|
||||||
|
self.assertFormatIsValue('{}', Grades.C)
|
||||||
|
self.assertFormatIsValue('{:}', Grades.C)
|
||||||
|
self.assertFormatIsValue('{:20}', Grades.C)
|
||||||
|
self.assertFormatIsValue('{:^20}', Grades.C)
|
||||||
|
self.assertFormatIsValue('{:>20}', Grades.C)
|
||||||
|
self.assertFormatIsValue('{:<20}', Grades.C)
|
||||||
|
self.assertFormatIsValue('{:+}', Grades.C)
|
||||||
|
self.assertFormatIsValue('{:08X}', Grades.C)
|
||||||
|
self.assertFormatIsValue('{:b}', Grades.C)
|
||||||
|
|
||||||
|
def test_format_enum_str(self):
|
||||||
|
Directional = self.Directional
|
||||||
|
self.assertFormatIsValue('{}', Directional.WEST)
|
||||||
|
self.assertFormatIsValue('{:}', Directional.WEST)
|
||||||
|
self.assertFormatIsValue('{:20}', Directional.WEST)
|
||||||
|
self.assertFormatIsValue('{:^20}', Directional.WEST)
|
||||||
|
self.assertFormatIsValue('{:>20}', Directional.WEST)
|
||||||
|
self.assertFormatIsValue('{:<20}', Directional.WEST)
|
||||||
|
|
||||||
def test_hash(self):
|
def test_hash(self):
|
||||||
Season = self.Season
|
Season = self.Season
|
||||||
dates = {}
|
dates = {}
|
||||||
|
@ -232,7 +330,7 @@ class TestEnum(unittest.TestCase):
|
||||||
|
|
||||||
def test_floatenum_from_scratch(self):
|
def test_floatenum_from_scratch(self):
|
||||||
class phy(float, Enum):
|
class phy(float, Enum):
|
||||||
pi = 3.141596
|
pi = 3.1415926
|
||||||
tau = 2 * pi
|
tau = 2 * pi
|
||||||
self.assertTrue(phy.pi < phy.tau)
|
self.assertTrue(phy.pi < phy.tau)
|
||||||
|
|
||||||
|
@ -240,7 +338,7 @@ class TestEnum(unittest.TestCase):
|
||||||
class FloatEnum(float, Enum):
|
class FloatEnum(float, Enum):
|
||||||
pass
|
pass
|
||||||
class phy(FloatEnum):
|
class phy(FloatEnum):
|
||||||
pi = 3.141596
|
pi = 3.1415926
|
||||||
tau = 2 * pi
|
tau = 2 * pi
|
||||||
self.assertTrue(phy.pi < phy.tau)
|
self.assertTrue(phy.pi < phy.tau)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue