Skip to content

Commit

Permalink
Merge pull request #38 from ysmu/master
Browse files Browse the repository at this point in the history
Add support for Enums.
  • Loading branch information
sampsyo committed May 11, 2018
2 parents cf61b13 + bb2a86b commit 60d5c0f
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
28 changes: 26 additions & 2 deletions confuse.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
"""
from __future__ import division, absolute_import, print_function

try:
import enum
SUPPORTS_ENUM = True
except ImportError:
SUPPORTS_ENUM = False

import argparse
import optparse
import platform
Expand Down Expand Up @@ -1223,17 +1229,32 @@ def __init__(self, choices):
If `choices` is a map, then the corresponding value is emitted.
Otherwise, the value itself is emitted.
If `choices` is a `Enum`, then the enum entry with the value is
emitted.
"""
self.choices = choices

def convert(self, value, view):
"""Ensure that the value is among the choices (and remap if the
choices are a mapping).
"""
if (SUPPORTS_ENUM and isinstance(self.choices, type) and
issubclass(self.choices, enum.Enum)):
try:
return self.choices(value)
except ValueError:
self.fail(
u'must be one of {0!r}, not {1!r}'.format(
[c.value for c in self.choices], value
),
view
)

if value not in self.choices:
self.fail(
u'must be one of {0}, not {1}'.format(
repr(list(self.choices)), repr(value)
u'must be one of {0!r}, not {1!r}'.format(
list(self.choices), value
),
view
)
Expand Down Expand Up @@ -1526,6 +1547,9 @@ def as_template(value):
elif isinstance(value, set):
# convert to list to avoid hash related problems
return Choice(list(value))
elif (SUPPORTS_ENUM and isinstance(value, type) and
issubclass(value, enum.Enum)):
return Choice(value)
elif isinstance(value, list):
return OneOf(value)
elif value is float:
Expand Down
12 changes: 12 additions & 0 deletions test/test_valid.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
from __future__ import division, absolute_import, print_function

try:
import enum
SUPPORTS_ENUM = True
except ImportError:
SUPPORTS_ENUM = False

import confuse
import os
import collections
Expand Down Expand Up @@ -142,6 +148,12 @@ def test_set_as_template(self):
typ = confuse.as_template(set())
self.assertIsInstance(typ, confuse.Choice)

@unittest.skipUnless(SUPPORTS_ENUM,
"enum not supported in this version of Python.")
def test_enum_type_as_template(self):
typ = confuse.as_template(enum.Enum)
self.assertIsInstance(typ, confuse.Choice)

def test_float_type_as_tempalte(self):
typ = confuse.as_template(float)
self.assertIsInstance(typ, confuse.Number)
Expand Down
26 changes: 26 additions & 0 deletions test/test_validation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
from __future__ import division, absolute_import, print_function

try:
import enum
SUPPORTS_ENUM = True
except ImportError:
SUPPORTS_ENUM = False

import confuse
import os
import unittest
Expand Down Expand Up @@ -74,6 +80,26 @@ def test_as_choice_with_dict(self):
})
self.assertEqual(res, 'baz')

@unittest.skipUnless(SUPPORTS_ENUM,
"enum not supported in this version of Python.")
def test_as_choice_with_enum(self):
class Foobar(enum.Enum):
Foo = 'bar'

config = _root({'foo': Foobar.Foo.value})
res = config['foo'].as_choice(Foobar)
self.assertEqual(res, Foobar.Foo)

@unittest.skipUnless(SUPPORTS_ENUM,
"enum not supported in this version of Python.")
def test_as_choice_with_enum_error(self):
class Foobar(enum.Enum):
Foo = 'bar'

config = _root({'foo': 'foo'})
with self.assertRaises(confuse.ConfigValueError):
config['foo'].as_choice(Foobar)

def test_as_number_float(self):
config = _root({'f': 1.0})
config['f'].as_number()
Expand Down

0 comments on commit 60d5c0f

Please sign in to comment.