From 5b3d7af62ee85c24a4f34069d337fd96bbb9a853 Mon Sep 17 00:00:00 2001 From: Sergei Trofimov Date: Fri, 23 Jun 2017 17:34:17 +0100 Subject: [PATCH] types: make enum levels serializable Add to/from_pod implementations to level, so that it may be serialized properly. In order to make sure that serialization is a reversible operation, ensure that the level value is numeric. --- tests/test_utils.py | 19 ++++++++++++++++++- wa/utils/types.py | 19 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 59aae0ac..270beaa4 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -20,7 +20,9 @@ from unittest import TestCase from nose.tools import raises, assert_equal, assert_not_equal, assert_in, assert_not_in from nose.tools import assert_true, assert_false -from wa.utils.types import list_or_integer, list_or_bool, caseless_string, arguments, prioritylist +from wa.utils.types import (list_or_integer, list_or_bool, caseless_string, + arguments, prioritylist, enum, level) + class TestPriorityList(TestCase): @@ -91,3 +93,18 @@ class TestPriorityList(TestCase): assert_equal(list(pl), ['a', 'b','y', 'x', 'm', 'n']) pl.add_after('z', 'm') assert_equal(list(pl), ['a', 'b', 'y', 'x', 'm', 'z', 'n']) + + +class TestEnumLevel(TestCase): + + def test_serialize_level(self): + l = level('test', 1) + s = l.to_pod() + l2 = level.from_pod(s) + assert_equal(l, l2) + + def test_deserialize_enum(self): + e = enum(['one', 'two', 'three']) + s = e.one.to_pod() + l = e.from_pod(s) + assert_equal(l, e.one) diff --git a/wa/utils/types.py b/wa/utils/types.py index 032bac29..27177a3e 100644 --- a/wa/utils/types.py +++ b/wa/utils/types.py @@ -488,9 +488,17 @@ class level(object): """ + @staticmethod + def from_pod(pod): + name, value_part = pod.split('(') + return level(name, numeric(value_part.rstrip(')'))) + def __init__(self, name, value): self.name = caseless_string(name) - self.value = value + self.value = numeric(value) + + def to_pod(self): + return repr(self) def __str__(self): return self.name @@ -545,6 +553,15 @@ def enum(args, start=0, step=1): class Enum(object): + @classmethod + def from_pod(cls, pod): + lv = level.from_pod(pod) + for enum_level in cls.values: + if enum_level == lv: + return enum_level + msg = 'Unexpected value "{}" for enum.' + raise ValueError(msg.format(pod)) + def __new__(cls, name): for attr_name in dir(cls): if attr_name.startswith('__'):