from abc import ABCMeta
from abc import abstractmethod
from django import forms


class _BaseEnumField(forms.TypedChoiceField):
    __metaclass__ = ABCMeta

    def __init__(self, enum, *args, **kwargs):
        self.enum = enum
        kwargs.setdefault('empty_value', None)

        if 'choices' in kwargs:
            raise ValueError('Cannot explicitly supply choices to enum fields.')
        if 'coerce' in kwargs:
            raise ValueError('Cannot explicitly supply coercion function to enum fields.')

        kwargs['choices'] = self.get_choices()
        kwargs['coerce'] = self.coerce_value
        super(_BaseEnumField, self).__init__(*args, **kwargs)

    @abstractmethod
    def get_choices(self):
        pass

    @abstractmethod
    def coerce_value(self, val):
        pass


class CanonicalEnumField(_BaseEnumField):
    """
    Uses the RichEnum/OrderedRichEnum canonical_name as form field values
    """

    def get_choices(self):
        return self.enum.choices()

    def coerce_value(self, name):
        return self.enum.from_canonical(name)


class IndexEnumField(_BaseEnumField):
    """
    Uses the OrderedRichEnum index as form field values
    """

    def get_choices(self):
        return self.enum.choices(value_field='index')

    def coerce_value(self, index):
        return self.enum.from_index(int(index))

from abc import ABCMeta
from abc import abstractmethod
from django import forms


class _BaseEnumField(forms.TypedChoiceField):
    __metaclass__ = ABCMeta

    def __init__(self, enum, *args, **kwargs):
        self.enum = enum
        kwargs.setdefault('empty_value', None)

        if 'choices' in kwargs:
            raise ValueError('Cannot explicitly supply choices to enum fields.')
        if 'coerce' in kwargs:
            raise ValueError('Cannot explicitly supply coercion function to enum fields.')

        kwargs['choices'] = self.get_choices()
        kwargs['coerce'] = self.coerce_value
        super(_BaseEnumField, self).__init__(*args, **kwargs)

    @abstractmethod
    def get_choices(self):
        pass

    @abstractmethod
    def coerce_value(self, val):
        pass

    def run_validators(self, value):
        # These have to be from a set, so it's hard for me to imagine a useful
        # custom validator.
        # The run_validators method in the superclass checks the value against
        # None, [], {}, etc, which causes warnings in the RichEnum.__eq__
        # method... arguably we shouldn't warn in those cases, but for now we
        # do.
        pass


class CanonicalEnumField(_BaseEnumField):
    """
    Uses the RichEnum/OrderedRichEnum canonical_name as form field values
    """

    def get_choices(self):
        return self.enum.choices()

    def coerce_value(self, name):
        return self.enum.from_canonical(name)


class IndexEnumField(_BaseEnumField):
    """
    Uses the OrderedRichEnum index as form field values
    """

    def get_choices(self):
        return self.enum.choices(value_field='index')

    def coerce_value(self, index):
        return self.enum.from_index(int(index))

Make run_validators method a no-op
_BaseEnumField: Make run_validators method a no-op

See the comment in this commit-- I can't see value in allowing custom
validators on EnumFields and the implementation in the superclass causes
warnings in RichEnum.__eq__.

Arguably those warnings aren't useful (warning against []/falsy compare).
In that case, we can revert this when they're silenced.

Alternatively, if we need the warnings and need this functionality, we'd have
re-implement the method in the superclass without said check, or live with
warnings every time a form containing an EnumField is validated, which sucks.

  from abc import ABCMeta
  from abc import abstractmethod
  from django import forms
  
  
  class _BaseEnumField(forms.TypedChoiceField):
      __metaclass__ = ABCMeta
  
      def __init__(self, enum, *args, **kwargs):
          self.enum = enum
          kwargs.setdefault('empty_value', None)
  
          if 'choices' in kwargs:
              raise ValueError('Cannot explicitly supply choices to enum fields.')
          if 'coerce' in kwargs:
              raise ValueError('Cannot explicitly supply coercion function to enum fields.')
  
          kwargs['choices'] = self.get_choices()
          kwargs['coerce'] = self.coerce_value
          super(_BaseEnumField, self).__init__(*args, **kwargs)
  
      @abstractmethod
      def get_choices(self):
          pass
  
      @abstractmethod
      def coerce_value(self, val):
          pass
  
+     def run_validators(self, value):
+         # These have to be from a set, so it's hard for me to imagine a useful
+         # custom validator.
+         # The run_validators method in the superclass checks the value against
+         # None, [], {}, etc, which causes warnings in the RichEnum.__eq__
+         # method... arguably we shouldn't warn in those cases, but for now we
+         # do.
+         pass
+ 
  
  class CanonicalEnumField(_BaseEnumField):
      """
      Uses the RichEnum/OrderedRichEnum canonical_name as form field values
      """
  
      def get_choices(self):
          return self.enum.choices()
  
      def coerce_value(self, name):
          return self.enum.from_canonical(name)
  
  
  class IndexEnumField(_BaseEnumField):
      """
      Uses the OrderedRichEnum index as form field values
      """
  
      def get_choices(self):
          return self.enum.choices(value_field='index')
  
      def coerce_value(self, index):
          return self.enum.from_index(int(index))
  
Make run_validators method a no-op
## Code Before:
from abc import ABCMeta
from abc import abstractmethod
from django import forms


class _BaseEnumField(forms.TypedChoiceField):
    __metaclass__ = ABCMeta

    def __init__(self, enum, *args, **kwargs):
        self.enum = enum
        kwargs.setdefault('empty_value', None)

        if 'choices' in kwargs:
            raise ValueError('Cannot explicitly supply choices to enum fields.')
        if 'coerce' in kwargs:
            raise ValueError('Cannot explicitly supply coercion function to enum fields.')

        kwargs['choices'] = self.get_choices()
        kwargs['coerce'] = self.coerce_value
        super(_BaseEnumField, self).__init__(*args, **kwargs)

    @abstractmethod
    def get_choices(self):
        pass

    @abstractmethod
    def coerce_value(self, val):
        pass


class CanonicalEnumField(_BaseEnumField):
    """
    Uses the RichEnum/OrderedRichEnum canonical_name as form field values
    """

    def get_choices(self):
        return self.enum.choices()

    def coerce_value(self, name):
        return self.enum.from_canonical(name)


class IndexEnumField(_BaseEnumField):
    """
    Uses the OrderedRichEnum index as form field values
    """

    def get_choices(self):
        return self.enum.choices(value_field='index')

    def coerce_value(self, index):
        return self.enum.from_index(int(index))

## Instruction:
Make run_validators method a no-op
## Code After:
from abc import ABCMeta
from abc import abstractmethod
from django import forms


class _BaseEnumField(forms.TypedChoiceField):
    __metaclass__ = ABCMeta

    def __init__(self, enum, *args, **kwargs):
        self.enum = enum
        kwargs.setdefault('empty_value', None)

        if 'choices' in kwargs:
            raise ValueError('Cannot explicitly supply choices to enum fields.')
        if 'coerce' in kwargs:
            raise ValueError('Cannot explicitly supply coercion function to enum fields.')

        kwargs['choices'] = self.get_choices()
        kwargs['coerce'] = self.coerce_value
        super(_BaseEnumField, self).__init__(*args, **kwargs)

    @abstractmethod
    def get_choices(self):
        pass

    @abstractmethod
    def coerce_value(self, val):
        pass

    def run_validators(self, value):
        # These have to be from a set, so it's hard for me to imagine a useful
        # custom validator.
        # The run_validators method in the superclass checks the value against
        # None, [], {}, etc, which causes warnings in the RichEnum.__eq__
        # method... arguably we shouldn't warn in those cases, but for now we
        # do.
        pass


class CanonicalEnumField(_BaseEnumField):
    """
    Uses the RichEnum/OrderedRichEnum canonical_name as form field values
    """

    def get_choices(self):
        return self.enum.choices()

    def coerce_value(self, name):
        return self.enum.from_canonical(name)


class IndexEnumField(_BaseEnumField):
    """
    Uses the OrderedRichEnum index as form field values
    """

    def get_choices(self):
        return self.enum.choices(value_field='index')

    def coerce_value(self, index):
        return self.enum.from_index(int(index))
