I am thinking we want three user-facing functions to perform the permutation. They could be named like:
permute_undirected_edges
permute_directed_edges
permute_bipartite_edges
I think this would be clearest for the user. You could remove the confusing allow_self_loop from permute_bipartite_edges. allow_antiparallel would only be an option for permute_directed_edges. Also permute_undirected_edges could mix sources or targets when swapping to achieve greater potential permutations?
@zietzm, do you think this makes sense?