def _sort_nodes(G: nx.MultiDiGraph, osmid: int) -> list[int]:
    """
    Topologically sort the nodes of an OSM way.

    Parameters
    ----------
    G
        The graph representing the OSM way.
    osmid
        The OSM way ID.

    Returns
    -------
    ordered_nodes
        The way's node IDs in topologically sorted order.
    """
    try:
        ordered_nodes = list(nx.topological_sort(G))

    except nx.NetworkXUnfeasible:
        # if it couldn't topologically sort the nodes, the way probably
        # contains a cycle. try removing an edge to break the cycle. first,
        # look for multiple edges emanating from the same source node
        insert_before = True
        edges = [
            edge
            for source in [node for node, degree in G.out_degree() if degree > 1]
            for edge in G.out_edges(source, keys=True)
        ]

        # if none found, then look for multiple edges pointing at the same
        # target node instead
        if len(edges) == 0:
            insert_before = False
            edges = [
                edge
                for target in [node for node, degree in G.in_degree() if degree > 1]
                for edge in G.in_edges(target, keys=True)
            ]

            # if still none, then take the first edge of the way: the entire
            # way could just be a cycle in which each node appears once
            if len(edges) == 0:
                edges = [next(iter(G.edges))]

        # remove one edge at a time and, if the graph remains connected, exit
        # the loop and check if we are able to topologically sort the nodes
        for edge in edges:
            G_ = G.copy()
            G_.remove_edge(*edge)
            if nx.is_weakly_connected(G_):
                break

        try:
            ordered_nodes = list(nx.topological_sort(G_))

            # re-insert (before or after its neighbor as needed) the duplicate
            # source or target node from the edge we removed
            dupe_node = edge[0] if insert_before else edge[1]
            neighbor = edge[1] if insert_before else edge[0]
            position = ordered_nodes.index(neighbor)
            position = position if insert_before else position + 1
            ordered_nodes.insert(position, dupe_node)

        except nx.NetworkXUnfeasible:
            # if it failed again, this way probably contains multiple cycles,
            # so remove a cycle then try to sort the nodes again, recursively.
            # note this is destructive and will be missing in the saved data.
            G_ = G.copy()
            G_.remove_edges_from(nx.find_cycle(G_))
            G_ = truncate.largest_component(G_)
            ordered_nodes = _sort_nodes(G_, osmid)
            msg = f"Had to remove a cycle from way {osmid!r} for topological sort"
            utils.log(msg, level=lg.WARNING)

    return ordered_nodes

    Topologically sort the nodes of an OSM way.

    Parameters
    ----------
    G
        The graph representing the OSM way.
    osmid
        The OSM way ID.

    Returns
    -------
    ordered_nodes
        The way's node IDs in topologically sorted order.
    
osmnx/_osm_xml.py