import inspect
from django.utils.encoding import force_bytes, python_2_unicode_compatible
from enum import Enum as BaseEnum, EnumMeta as BaseEnumMeta
import six


class EnumMeta(BaseEnumMeta):
    def __new__(cls, name, bases, attrs):
        Labels = attrs.get('Labels')

        if Labels is not None and inspect.isclass(Labels):
            del attrs['Labels']

        obj = BaseEnumMeta.__new__(cls, name, bases, attrs)
        for m in obj:
            try:
                m.label = getattr(Labels, m.name)
            except AttributeError:
                m.label = m.name.replace('_', ' ').title()

        return obj


@python_2_unicode_compatible
class Enum(six.with_metaclass(EnumMeta, BaseEnum)):
    @classmethod
    def choices(cls):
        """
        Returns a list formatted for use as field choices.
        (See https://docs.djangoproject.com/en/dev/ref/models/fields/#choices)
        """
        return tuple((m.value, m.label) for m in cls)

    def __str__(self):
        """
        Show our label when Django uses the Enum for displaying in a view
        """
        return force_bytes(self.label)

import inspect
from django.utils.encoding import force_bytes, python_2_unicode_compatible
from enum import Enum as BaseEnum, EnumMeta as BaseEnumMeta
import six


class EnumMeta(BaseEnumMeta):
    def __new__(cls, name, bases, attrs):
        Labels = attrs.get('Labels')

        if Labels is not None and inspect.isclass(Labels):
            del attrs['Labels']
            if hasattr(attrs, '_member_names'):
                attrs._member_names.remove('Labels')

        obj = BaseEnumMeta.__new__(cls, name, bases, attrs)
        for m in obj:
            try:
                m.label = getattr(Labels, m.name)
            except AttributeError:
                m.label = m.name.replace('_', ' ').title()

        return obj


@python_2_unicode_compatible
class Enum(six.with_metaclass(EnumMeta, BaseEnum)):
    @classmethod
    def choices(cls):
        """
        Returns a list formatted for use as field choices.
        (See https://docs.djangoproject.com/en/dev/ref/models/fields/#choices)
        """
        return tuple((m.value, m.label) for m in cls)

    def __str__(self):
        """
        Show our label when Django uses the Enum for displaying in a view
        """
        return force_bytes(self.label)

Fix 'Labels' class in Python 3.
Fix 'Labels' class in Python 3.

In Python 3, the attrs dict will already be an _EnumDict, which has a
separate list of member names (in Python 2, it is still a plain dict at this
point).
