def sort_tables_and_constraints(
        tables, filter_fn=None, extra_dependencies=None):
    """sort a collection of :class:`.Table`  / :class:`.ForeignKeyConstraint`
    objects.

    This is a dependency-ordered sort which will emit tuples of
    ``(Table, [ForeignKeyConstraint, ...])`` such that each
    :class:`.Table` follows its dependent :class:`.Table` objects.
    Remaining :class:`.ForeignKeyConstraint` objects that are separate due to
    dependency rules not satisifed by the sort are emitted afterwards
    as ``(None, [ForeignKeyConstraint ...])``.

    Tables are dependent on another based on the presence of
    :class:`.ForeignKeyConstraint` objects, explicit dependencies
    added by :meth:`.Table.add_is_dependent_on`, as well as dependencies
    stated here using the :paramref:`~.sort_tables_and_constraints.skip_fn`
    and/or :paramref:`~.sort_tables_and_constraints.extra_dependencies`
    parameters.

    :param tables: a sequence of :class:`.Table` objects.

    :param filter_fn: optional callable which will be passed a
     :class:`.ForeignKeyConstraint` object, and returns a value based on
     whether this constraint should definitely be included or excluded as
     an inline constraint, or neither.   If it returns False, the constraint
     will definitely be included as a dependency that cannot be subject
     to ALTER; if True, it will **only** be included as an ALTER result at
     the end.   Returning None means the constraint is included in the
     table-based result unless it is detected as part of a dependency cycle.

    :param extra_dependencies: a sequence of 2-tuples of tables which will
     also be considered as dependent on each other.

    .. versionadded:: 1.0.0

    .. seealso::

        :func:`.sort_tables`


    """

    fixed_dependencies = set()
    mutable_dependencies = set()

    if extra_dependencies is not None:
        fixed_dependencies.update(extra_dependencies)

    remaining_fkcs = set()
    for table in tables:
        for fkc in table.foreign_key_constraints:
            if fkc.use_alter is True:
                remaining_fkcs.add(fkc)
                continue

            if filter_fn:
                filtered = filter_fn(fkc)

                if filtered is True:
                    remaining_fkcs.add(fkc)
                    continue

            dependent_on = fkc.referred_table
            if dependent_on is not table:
                mutable_dependencies.add((dependent_on, table))

        fixed_dependencies.update(
            (parent, table) for parent in table._extra_dependencies
        )

    try:
        candidate_sort = list(
            topological.sort(
                fixed_dependencies.union(mutable_dependencies), tables,
                deterministic_order=True
            )
        )
    except exc.CircularDependencyError as err:
        for edge in err.edges:
            if mutable_dependencies in edge:
                table = edge[1]
                can_remove = [
                    fkc for fkc in table.foreign_key_constraints
                    if filter_fn is None or filter_fn(fkc) is not False]
                remaining_fkcs.update(can_remove)
                for fkc in can_remove:
                    dependent_on = fkc.referred_table
                    if dependent_on is not table:
                        mutable_dependencies.discard((dependent_on, table))
        candidate_sort = list(
            topological.sort(
                fixed_dependencies.union(mutable_dependencies), tables,
                deterministic_order=True
            )
        )

    return [
        (table, table.foreign_key_constraints.difference(remaining_fkcs))
        for table in candidate_sort
    ] + [(None, list(remaining_fkcs))]
dataset/ETHPy150Open zzzeek/sqlalchemy/lib/sqlalchemy/sql/ddl.py/sort_tables_and_constraints/swapped operands of `in`