Define a subtype which blocks a list of methods.

    @param prefix: The subtype name prefix.  This is prepended to the
                   base type name.  This convention is baked in for
                   API consistency.

    @param base: The base type to derive from.

    @param blockednames: A list of method name strings.  All of these
                         will be blocked.

    @param clsdict: None or a dict which will be modified to become the
                    subtype class dict.

    @return: The new subtype.

    @raise: OverwriteError - If clsdict contains an entry in blockednames.

def define_constrained_subtype(prefix, base, blockednames, clsdict=None):
    """
    Define a subtype which blocks a list of methods.

    @param prefix: The subtype name prefix.  This is prepended to the
                   base type name.  This convention is baked in for
                   API consistency.

    @param base: The base type to derive from.

    @param blockednames: A list of method name strings.  All of these
                         will be blocked.

    @param clsdict: None or a dict which will be modified to become the
                    subtype class dict.

    @return: The new subtype.

    @raise: OverwriteError - If clsdict contains an entry in blockednames.
    """
    name = prefix + base.__name__

    clsdict = clsdict or {}

    doc = clsdict.get('__doc__', '')
    doc = 'An {} extension of {}.\n{}'.format(prefix, base.__name__, doc)
    clsdict['__doc__'] = doc

    setitem_without_overwrite(
        clsdict,
        'get_blocked_method_names',
        lambda self: iter(blockednames),
    )

    for bname in blockednames:
        setitem_without_overwrite(
            clsdict,
            bname,
            ConstraintError.block(getattr(base, bname)),
        )

    return type(name, (base,), clsdict)