From 6a6bd5b5b708b6a564611afef868fe0b9c60ee2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20K=C3=A1cha?= <ph@cesnet.cz>
Date: Wed, 1 Nov 2017 15:45:01 +0100
Subject: [PATCH] Removed OpenTypedDict support. Would need more TypedDict
 methods decoupling to avoid too much state keeping issues; also makes
 class/instance distinction too obscure to get users to use it correctly

---
 test_typedcols.py | 15 +---------
 typedcols.py      | 71 +++--------------------------------------------
 2 files changed, 5 insertions(+), 81 deletions(-)

diff --git a/test_typedcols.py b/test_typedcols.py
index d614911..9e73062 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 34efcdd..a87f341 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):
-- 
GitLab