def validate_constraints(
    ftype=None,
    embedded_doc_type=None,
    subfield=None,
    read_only=None,
    info_keys=None,
    created_after=None,
):
    """Validates the given field constraints.

    Args:
        ftype (None): an optional field type or iterable of types to enforce.
            Must be subclass(es) of :class:`Field`
        embedded_doc_type (None): an optional embedded document type or
            iterable of types to enforce. Must be subclass(es) of
            :class:`fiftyone.core.odm.BaseEmbeddedDocument`
        subfield (None): an optional subfield type or iterable of subfield
            types to enforce. Must be subclass(es) of :class:`Field`
        read_only (None): whether to optionally enforce that the field is
            read-only (True) or not read-only (False)
        info_keys (None): an optional key or list of keys that must be in the
            field's ``info`` dict
        created_after (None): an optional ``datetime`` specifying a minimum
            creation date

    Returns:
        True/False whether any constraints were provided

    Raises:
        ValueError: if the constraints are not valid
    """
    has_contraints = False

    if ftype is not None:
        has_contraints = True

        if etau.is_container(ftype):
            ftype = tuple(ftype)
        else:
            ftype = (ftype,)

        for _ftype in ftype:
            if not issubclass(_ftype, Field):
                raise ValueError(
                    "Field type %s is not a subclass of %s" % (_ftype, Field)
                )

    if embedded_doc_type is not None:
        has_contraints = True

        if etau.is_container(embedded_doc_type):
            embedded_doc_type = tuple(embedded_doc_type)
        else:
            embedded_doc_type = (embedded_doc_type,)

        for _embedded_doc_type in embedded_doc_type:
            if not issubclass(_embedded_doc_type, foo.BaseEmbeddedDocument):
                raise ValueError(
                    "Embedded doc type %s is not a subclass of %s"
                    % (_embedded_doc_type, foo.BaseEmbeddedDocument)
                )

    if subfield is not None:
        has_contraints = True

        if etau.is_container(subfield):
            subfield = tuple(subfield)
        else:
            subfield = (subfield,)

        for _subfield in subfield:
            if not issubclass(_subfield, Field):
                raise ValueError(
                    "Subfield type %s is not a subclass of %s"
                    % (_subfield, Field)
                )

    if read_only is not None:
        has_contraints = True

        if not isinstance(read_only, bool):
            raise ValueError("read_only must be a boolean")

    if info_keys is not None:
        has_contraints = True
        if not isinstance(info_keys, (list, str)):
            raise ValueError("info_keys must be a single or a list of str's")

    if created_after is not None:
        has_contraints = True
        if not isinstance(created_after, datetime):
            raise ValueError("created_after must be a datetime")

    return has_contraints
Validates the given field constraints.

    Args:
        ftype (None): an optional field type or iterable of types to enforce.
            Must be subclass(es) of :class:`Field`
        embedded_doc_type (None): an optional embedded document type or
            iterable of types to enforce. Must be subclass(es) of
            :class:`fiftyone.core.odm.BaseEmbeddedDocument`
        subfield (None): an optional subfield type or iterable of subfield
            types to enforce. Must be subclass(es) of :class:`Field`
        read_only (None): whether to optionally enforce that the field is
            read-only (True) or not read-only (False)
        info_keys (None): an optional key or list of keys that must be in the
            field's ``info`` dict
        created_after (None): an optional ``datetime`` specifying a minimum
            creation date

    Returns:
        True/False whether any constraints were provided

    Raises:
        ValueError: if the constraints are not valid
    
fiftyone/core/fields.py