def __setitem__(self, key, value):
        """Set value corresponding to key. If key is a tuple, interpret it as
        a sequence of keys in a tree of nested dicts.

        Parameters
        ----------
        key : str or tuple of str
          Dict key
        value : any
          Dict value corresponding to key
        """

        # If key is a tuple, interpret it as a sequence of keys in a
        # tree of nested dicts and retrieve parent node in tree
        kc = key
        sd = self
        if isinstance(key, tuple):
            kc = key[-1]
            sd = self.__class__.getparent(self, key)
        # If value is not a dict, or if it is dict but also a
        # ConstrainedDict (meaning that it has already been
        # constructed, possibly as a derived class), or if it is a
        # dict but there is no current entry in self for the
        # corresponding key, then the value is inserted via parent
        # class __setitem__. Otherwise the value is itself a dict that
        # must be processed recursively via the update method.
        if not isinstance(value, dict) or \
           isinstance(value, ConstrainedDict) or kc not in sd:
            vc = value
            # If value is a dict but not a ConstrainedDict (if it is a
            # ConstrainedDict instance, it has already been
            # constructed, possibly as a derived class), call
            # constructor to instantiate a ConstrainedDict object
            # which becomes the value actually associated with the key
            if isinstance(value, dict) and \
               not isinstance(value, ConstrainedDict):
                # ConstrainedDict constructor is called instead of the
                # constructor of the derived class because it is
                # undesirable to force the derived class constructor to
                # have the same interface. This implies that only the root
                # node will have derived class type, and all others will
                # be of type ConstrainedDict. Since it is required that
                # all nodes use the derived class defaults class
                # attribute, it is necessary to maintain an object dflts
                # attribute that is initialised from the defaults class
                # attribute and passed down the node tree on construction.
                vc = ConstrainedDict(vc, sd.pth + (kc,), self.dflt)
            # Check that the current key and value are valid with respect
            # to the defaults tree. Relevant exceptions are caught and
            # re-raised so that the stack trace originates from this
            # method.
            try:
                sd.check(kc, vc)
            except (UnknownKeyError, InvalidValueError) as e:
                raise e
            # Call base class __setitem__ to insert key, value pair
            super(ConstrainedDict, sd).__setitem__(kc, vc)
        else:
            # Call update to handle subtree update
            sd[kc].update(value)
def __setitem__ ( self , key , value ) : kc = key sd = self if isinstance ( key , tuple ) : kc = key [ - 1 ] sd = self . __class__ . getparent ( self , key ) if not isinstance ( value , dict ) or isinstance ( value , ConstrainedDict ) or kc not in sd : vc = value if isinstance ( value , dict ) and not isinstance ( value , ConstrainedDict ) : vc = ConstrainedDict ( vc , sd . pth + ( kc , ) , self . dflt ) try : sd . check ( kc , vc ) except ( UnknownKeyError , InvalidValueError ) as e : raise e super ( ConstrainedDict , sd ) . __setitem__ ( kc , vc ) else : sd [ kc ] . update ( value )
Set value corresponding to key. If key is a tuple, interpret it as
        a sequence of keys in a tree of nested dicts.

        Parameters
        ----------
        key : str or tuple of str
          Dict key
        value : any
          Dict value corresponding to key