diff --git a/test_typedcols.py b/test_typedcols.py index d6149114ea3dbd7355d35522d0499bc0f58e05e3..9e73062e5aeb2620027eaf96be6c3ec9edb3ea72 100755 --- a/test_typedcols.py +++ b/test_typedcols.py @@ -4,7 +4,7 @@ # Copyright (c) 2016, CESNET, z. s. p. o. # Use of this source is governed by an ISC license, see LICENSE file. -from typedcols import TypedDict, OpenTypedDict, TypedList, KeyNotAllowed, KeysRequired, Discard, Any +from typedcols import TypedDict, TypedList, KeyNotAllowed, KeysRequired, Discard, Any from sys import version_info import unittest @@ -135,19 +135,6 @@ class TestTypedDict(unittest.TestCase): ]) -class TestOpenTypedDict(TestTypedDict): - - def setUp(self): - open_address_dict = OpenTypedDict(typedef=address_typedef.copy(), allow_unknown=True) - - open_person_typedef = person_typedef.copy() - open_person_typedef["address"] = open_address_dict - - open_person_dict = OpenTypedDict(typedef=open_person_typedef) - - self.person = open_person_dict(person_init_data) - - class IntList(TypedList): item_type = int diff --git a/typedcols.py b/typedcols.py index 34efcddd1026fe7c069b76dc0ccc063e08cb7bfb..a87f34111dc8a752b2865a2b6bdd9200ba582d1e 100644 --- a/typedcols.py +++ b/typedcols.py @@ -10,7 +10,7 @@ Defines TypedDict and TypedList, which enforce inserted types based on simple type definition. """ -__version__ = '0.1.12' +__version__ = '0.1.13' __author__ = 'Pavel Kácha <pavel.kacha@cesnet.cz>' import collections @@ -61,7 +61,7 @@ class TypedDictMetaclass(abc.ABCMeta): dictify_typedef(cls.typedef) -class TypedDictBase(collections.MutableMapping): +class TypedDict(collections.MutableMapping): """ Dictionary type abstract class, which supports checking of inserted types, based on simple type definition. @@ -151,7 +151,7 @@ class TypedDictBase(collections.MutableMapping): for key, tdef in self.typedef.items(): if tdef.get("required", False) and not key in self.data: missing = missing + ((key,),) - elif recursive and (isinstance(tdef["type"], TypedDictBase) or issubclass(tdef["type"], TypedDictBase)): + elif recursive and issubclass(tdef["type"], TypedDict): try: self.data[key].checkRequired(recursive) except KeysRequired as e: @@ -219,70 +219,7 @@ class TypedDictBase(collections.MutableMapping): # Py 2 requires metaclassing by __metaclass__ attribute, whereas Py 3 # needs metaclass argument. What actually happens is the following, # so we will do it explicitly, to be compatible with both versions. -TypedDict = TypedDictMetaclass("TypedDict", (TypedDictBase,), {}) - - -class TypedefSetter(object): - """ Setter for OpenTypedDict.typedef value, which forces typedef canonicalisation. - Implemented as setter only class, as it does not intercept and slow down read - access. - """ - - def __set__(self, obj, value): - dictify_typedef(value) - obj.__dict__["typedef"] = value - - -class OpenTypedDict(TypedDictBase): - """ Dictionary type class, which supports checking of inserted types, based on - simple type definition, which must be provided in constructor and is changeable - by assigning instance.typedef variable. - - Note however that changing already populated OpenTypedDict's typedef to - incompatible definition may lead to undefined results and data inconsistent - with definition. - """ - - def __init__(self, init_data=None, typedef=None, allow_unknown=False, dict_class=dict): - """ init_data: initial values - - typedef: dictionary with keys and their type definitions. Type definition - may be simple callable (int, string, check_func, - AnotherTypedDict), or dict with the following members: - "type": - type enforcing callable. If callable returns, raises - or is Discard, key will be silently discarded - "default": - new TypedDict subclass will be initialized with keys - with this value; deleted keys will also revert to it - "required": - bool, checkRequired method will report the key if not present - "description": - string, explaining field type in human readable terms - (will be used in exception explanations) - Type enforcing callable must take one argument, and return value, - coerced to expected type. Coercion may even be conversion, for example - arbitrary date string, converted to DateTime. - - allow_unknown: boolean, specifies whether dictionary allows unknown keys, - that means keys, which are not defined in 'typedef' - - dict_class: class or factory for underlying dict implementation - """ - self.allow_unknown = allow_unknown - self.dict_class = dict_class - self.typedef = typedef or {} - super(OpenTypedDict, self).__init__(init_data) - - typedef = TypedefSetter() - - def __call__(self, data): - """ Instances are made callable so they can be used in nested "type" - definitions. Note however that these classes are mutable, so - assigning new values replaces old ones. - """ - super(OpenTypedDict, self).__init__(data) - return self +TypedDict = TypedDictMetaclass("TypedDict", (TypedDict,), {}) class TypedList(collections.MutableSequence):