def _findPathsRecurse(self, source_stp, dest_stp, bandwidth, exclude_networks=None):

        source_network = self.getNetwork(source_stp.network)
        dest_network   = self.getNetwork(dest_stp.network)
        source_port    = source_network.getPort(source_stp.port)
        dest_port      = dest_network.getPort(dest_stp.port)

        if not (source_port.canMatchLabel(source_stp.label) or dest_port.canMatchLabel(dest_stp.label)):
            return []
#        if not (source_port.canProvideBandwidth(bandwidth) and dest_port.canProvideBandwidth(bandwidth)):
#            return []

        if source_port.isBidirectional() and dest_port.isBidirectional():
            # bidirectional path finding, easy case first
            if source_stp.network == dest_stp.network:
                # while it is possible to cross other network in order to connect to intra-network STPs
                # it is not something we really want to do in the real world, so we don't
                try:
                    if source_network.canSwapLabel(source_stp.label.type_):
                        source_label = source_port.label().intersect(source_stp.label)
                        dest_label   = dest_port.label().intersect(dest_stp.label)
                    else:
                        source_label = source_port.label().intersect(dest_port.label()).intersect(source_stp.label).intersect(dest_stp.label)
                        dest_label   = source_label
                    link = nsa.Link(source_stp.network, source_stp.port, dest_stp.port, source_label, dest_label)
                    return [ [ link ] ]
                except nsa.EmptyLabelSet:
                    return [] # no path
            else:
                # ok, time for real pathfinding
                link_ports = source_network.findPorts(True, source_stp.label, source_stp.port)
                link_ports = [ port for port in link_ports if port.hasRemote() ] # filter out termination ports
                links = []
                for lp in link_ports:
                    demarcation = self.findDemarcationPort(lp)
                    if demarcation is None:
                        continue

                    d_network_id, d_port_id = demarcation

                    if exclude_networks is not None and demarcation[0] in exclude_networks:
                        continue # don't do loops in path finding

                    demarcation_label = lp.label() if source_network.canSwapLabel(source_stp.label.type_) else source_stp.label.intersect(lp.label())
                    demarcation_stp = nsa.STP(demarcation[0], demarcation[1], demarcation_label)
                    sub_exclude_networks = [ source_network.id_ ] + (exclude_networks or [])
                    sub_links = self._findPathsRecurse(demarcation_stp, dest_stp, bandwidth, sub_exclude_networks)
                    # if we didn't find any sub paths, just continue
                    if not sub_links:
                        continue

                    for sl in sub_links:
                        # --
                        if source_network.canSwapLabel(source_stp.label.type_):
                            source_label = source_port.label().intersect(source_stp.label)
                            dest_label   = lp.label().intersect(sl[0].src_stp.label)
                        else:
                            source_label = source_port.label().intersect(source_stp.label).intersect(lp.label()).intersect(sl[0].src_stp.label)
                            dest_label   = source_label

                        first_link = nsa.Link(source_stp.network, source_stp.port, lp.id_, source_label, dest_label)
                        path = [ first_link ] + sl
                        links.append(path)

                return sorted(links, key=len) # sort by length, shortest first

        else:
            raise error.TopologyError('Unidirectional path-finding not implemented yet')
dataset/ETHPy150Open NORDUnet/opennsa/opennsa/topology/nml.py/Topology._findPathsRecurse/original