Enum usage to restrict class attribute values I am using enums in python3 for the first time but unsure if I am using them correctly.

I want to restrict the 'allowed values' for a class attribute ArticleMetadata.article_type to those defined within an ArticleTypes Enum class.

Here's my code:

from enum import Enum

class ArticleMetadata(object):

    ArticleTypes = Enum('ArticleTypes', 'original modified', module=__name__)

    def is_in_enum(self, value, Enum):
        """Verify that a value is contained within a defined Enum object.

        Raises:
            ValueError: If the value is not contained within the defined Enum.
        """
        if value in Enum.__members__:
            return True
        else:
            raise ValueError("Value {0} not in Enum list.".format(value))

    def __init__(self, **kwargs):
        """Set class attributes."""

        self.article_type = (kwargs['article_type'] if 'article_type' in kwargs.keys()
                              and self.is_in_enum(kwargs['article_type'], self.ArticleTypes)
                              else None
                              )


Usage

&gt; foo = ArticleMetadata(article_type='original')
&gt; foo.article_type
'original'
&gt; bar = ArticleMetadata(article_type='invalid')
*** ValueError: Value invalid not in Enum list.


This code works, but having to write an is_in_enum method seems clunky, and I would have thought that this functionality would be natively part of enums somehow?? 

Also, no errors are raised if I later run foo.article_type = 'invalid', which doesn't seem right!

Am I missing a common usage pattern?
You get no benefit for raising an error in is_in_enum. It's actually a hindrance.
I'd expect to use that function as followed:

if foo.is_in_enum(key):
    # do something
else:
    # do something


However, to correctly use your function I'd have to use:

try:
    foo.is_in_enum(key)
except ValueError:
    # do something
else:
    # do something


Instead just change it to return your if statement.
You can use **kwargs with keyword arguments. Use that instead.


And so I'd use:

from enum import Enum


class ArticleMetadata(object):
    ArticleTypes = Enum('ArticleTypes', 'original modified', module=__name__)

    def in_enum(self, value, Enum):
        """Verify that a value is contained within a defined Enum object."""
        return value in Enum.__members__

    def __init__(self, article_type=None, **kwargs):
        """Set class attributes."""
        if article_type is None or not self.in_enum(article_type, self.ArticleTypes):
            raise ValueError("Value {} not in Enum list.".format(article_type))
        self.article_type = article_type