class TypedDict(OrderedDict):
    def typemap(cls):
        return ()

    typemap = classmethod(typemap)

    def __init__(self, initializer={}):
        self.__types = OrderedDict(self.typemap())
        for t in self.__types.values():
            if t not in validators and not hasattr(t, "validator"):
                raise RuntimeError("no validator for type %s" % (t,))
        ## initialize all items defined by typemap
        complete_init = OrderedDict(initializer)
        for key, value in self.__types.items():
            if key not in initializer:
                complete_init[key] = None
        super(TypedDict, self).__init__(complete_init)

    def __setitem__(self, key, value):
        ## validate key, new keys not allowed
        t = self.__types[key]
        ## validate value
        if value is not None:
            try:
                validator = validators[t]
            except KeyError:
                validator = t.validator
            value = validator(value)
        super(TypedDict, self).__setitem__(key, value)

    def types(self):
        return OrderedDict(self.__types)

    def friendly_update(self, other):
        for key in other.keys():
            try:
                self[key] = other[key]
            except KeyError:
                pass
class TypedDict(OrderedDict):
    def typemap(cls):
        return ()

    typemap = classmethod(typemap)

    def __init__(self, initializer={}):
        self.__types = OrderedDict(self.typemap())
        for t in self.__types.values():
            if t not in validators and not hasattr(t, 'validator'):
                raise RuntimeError('no validator for type %s' % (t, ))
        ## initialize all items defined by typemap
        complete_init = OrderedDict(initializer)
        for key, value in self.__types.items():
            if key not in initializer:
                complete_init[key] = None
        super(TypedDict, self).__init__(complete_init)

    def __setitem__(self, key, value):
        ## validate key, new keys not allowed
        t = self.__types[key]
        ## validate value
        if value is not None:
            try:
                validator = validators[t]
            except KeyError:
                validator = t.validator
            value = validator(value)
        super(TypedDict, self).__setitem__(key, value)

    def types(self):
        return OrderedDict(self.__types)

    def friendly_update(self, other):
        for key in other.keys():
            try:
                self[key] = other[key]
            except KeyError:
                pass