def definitions_match(definition_objects, expected_descriptor):
    """
    Return whether Definition objects have expected properties.

    The order of the definitions, and their sources, may appear in any order.

    expected_descriptor is a shorthand format, consisting of a list or tuple
    `(definition_string, sources)` where `sources` may be a single string for a
    single source, or a list of strings for multiple sources.
    """

    # We want to do set comparisons. But to put things inside sets, we have to
    # first make them hashable by freezing them.
    comparable_actual = set(
        (defn.text, frozenset(c.abbrv for c in defn.citations.all()))
        for defn in definition_objects
    )
    comparable_expected = set(
        (e[0], frozenset(e[1] if isinstance(e[1], list) else [e[1]]))
        for e in expected_descriptor
    )

    return comparable_actual == comparable_expected