def sort_rings(index_rings: List[List[Tuple[(int, int)]]], vertices: npt.NDArray[np.float32]) -> SortedRingType:
    'Sorts a list of index-rings.\n\n    Takes a list of unsorted index rings and sorts them into\n    "exterior" and "interior" components. Any doubly-nested rings\n    are considered exterior rings.\n\n    Parameters\n    ----------\n    index_rings : List[List[Tuple[int, int]]]\n        Unosorted list of list of mesh edges as specified by end node\n        indexs of each edge.\n    vertices : npt.NDArray[np.float32]\n        2D ``n x 2`` array of node coordinate couples.\n\n    Returns\n    -------\n    SortedRingType\n        Dictionary of information aboout polygon boundaries extracted\n        based on the input\n\n    Notes\n    -----\n    The return value is a mapping of ring index to dictionary\n    containing exterior and interior linear ring information as\n    numpy array\n    This function is not currently used, instead a different faster\n    approach is used for boundary and polygon calculation from\n    elements.\n    '
    areas = []
    for index_ring in index_rings:
        (e0, e1) = [list(t) for t in zip(*index_ring)]
        areas.append(float(Polygon(vertices[e0, :]).area))
    idx = areas.index(np.max(areas))
    exterior = index_rings.pop(idx)
    areas.pop(idx)
    _id = 0
    _index_rings = {}
    _index_rings[_id] = {'exterior': np.asarray(exterior), 'interiors': []}
    (e0, e1) = [list(t) for t in zip(*exterior)]
    path = Path(vertices[(e0 + [e0[0]]), :], closed=True)
    while (len(index_rings) > 0):
        potential_interiors = []
        for (i, index_ring) in enumerate(index_rings):
            (e0, e1) = [list(t) for t in zip(*index_ring)]
            if path.contains_point(vertices[e0[0], :]):
                potential_interiors.append(i)
        real_interiors = []
        for (i, p_interior) in reversed(list(enumerate(potential_interiors))):
            _p_interior = index_rings[p_interior]
            check = [index_rings[k] for (j, k) in reversed(list(enumerate(potential_interiors))) if (i != j)]
            has_parent = False
            for _path in check:
                (e0, e1) = [list(t) for t in zip(*_path)]
                _path = Path(vertices[(e0 + [e0[0]]), :], closed=True)
                if _path.contains_point(vertices[_p_interior[0][0], :]):
                    has_parent = True
            if (not has_parent):
                real_interiors.append(p_interior)
        for i in reversed(sorted(real_interiors)):
            _index_rings[_id]['interiors'].append(np.asarray(index_rings.pop(i)))
            areas.pop(i)
        if (len(index_rings) > 0):
            idx = areas.index(np.max(areas))
            exterior = index_rings.pop(idx)
            areas.pop(idx)
            _id += 1
            _index_rings[_id] = {'exterior': np.asarray(exterior), 'interiors': []}
            (e0, e1) = [list(t) for t in zip(*exterior)]
            path = Path(vertices[(e0 + [e0[0]]), :], closed=True)
    return _index_rings
Sorts a list of index-rings.

Takes a list of unsorted index rings and sorts them into
"exterior" and "interior" components. Any doubly-nested rings
are considered exterior rings.

Parameters
----------
index_rings : List[List[Tuple[int, int]]]
    Unosorted list of list of mesh edges as specified by end node
    indexs of each edge.
vertices : npt.NDArray[np.float32]
    2D ``n x 2`` array of node coordinate couples.

Returns
-------
SortedRingType
    Dictionary of information aboout polygon boundaries extracted
    based on the input

Notes
-----
The return value is a mapping of ring index to dictionary
containing exterior and interior linear ring information as
numpy array
This function is not currently used, instead a different faster
approach is used for boundary and polygon calculation from
elements.
def sort_rings(index_rings: List[List[Tuple[(int, int)]]], vertices: npt.NDArray[np.float32]) -> SortedRingType:
    'Sorts a list of index-rings.\n\n    Takes a list of unsorted index rings and sorts them into\n    "exterior" and "interior" components. Any doubly-nested rings\n    are considered exterior rings.\n\n    Parameters\n    ----------\n    index_rings : List[List[Tuple[int, int]]]\n        Unosorted list of list of mesh edges as specified by end node\n        indexs of each edge.\n    vertices : npt.NDArray[np.float32]\n        2D ``n x 2`` array of node coordinate couples.\n\n    Returns\n    -------\n    SortedRingType\n        Dictionary of information aboout polygon boundaries extracted\n        based on the input\n\n    Notes\n    -----\n    The return value is a mapping of ring index to dictionary\n    containing exterior and interior linear ring information as\n    numpy array\n    This function is not currently used, instead a different faster\n    approach is used for boundary and polygon calculation from\n    elements.\n    '
    areas = []
    for index_ring in index_rings:
        (e0, e1) = [list(t) for t in zip(*index_ring)]
        areas.append(float(Polygon(vertices[e0, :]).area))
    idx = areas.index(np.max(areas))
    exterior = index_rings.pop(idx)
    areas.pop(idx)
    _id = 0
    _index_rings = {}
    _index_rings[_id] = {'exterior': np.asarray(exterior), 'interiors': []}
    (e0, e1) = [list(t) for t in zip(*exterior)]
    path = Path(vertices[(e0 + [e0[0]]), :], closed=True)
    while (len(index_rings) > 0):
        potential_interiors = []
        for (i, index_ring) in enumerate(index_rings):
            (e0, e1) = [list(t) for t in zip(*index_ring)]
            if path.contains_point(vertices[e0[0], :]):
                potential_interiors.append(i)
        real_interiors = []
        for (i, p_interior) in reversed(list(enumerate(potential_interiors))):
            _p_interior = index_rings[p_interior]
            check = [index_rings[k] for (j, k) in reversed(list(enumerate(potential_interiors))) if (i != j)]
            has_parent = False
            for _path in check:
                (e0, e1) = [list(t) for t in zip(*_path)]
                _path = Path(vertices[(e0 + [e0[0]]), :], closed=True)
                if _path.contains_point(vertices[_p_interior[0][0], :]):
                    has_parent = True
            if (not has_parent):
                real_interiors.append(p_interior)
        for i in reversed(sorted(real_interiors)):
            _index_rings[_id]['interiors'].append(np.asarray(index_rings.pop(i)))
            areas.pop(i)
        if (len(index_rings) > 0):
            idx = areas.index(np.max(areas))
            exterior = index_rings.pop(idx)
            areas.pop(idx)
            _id += 1
            _index_rings[_id] = {'exterior': np.asarray(exterior), 'interiors': []}
            (e0, e1) = [list(t) for t in zip(*exterior)]
            path = Path(vertices[(e0 + [e0[0]]), :], closed=True)
    return _index_rings