示例#1
0
    def merge(*lists):
        """
        Merge lists while trying to keep the relative order of the elements.
        Warn if the lists have the same elements in a different relative order.

        For static assets it can be important to have them included in the DOM
        in a certain order. In JavaScript you may not be able to reference a
        global or in CSS you might want to override a style.
        """
        dependency_graph = defaultdict(set)
        all_items = OrderedSet()
        for list_ in filter(None, lists):
            head = list_[0]
            # The first items depend on nothing but have to be part of the
            # dependency graph to be included in the result.
            dependency_graph.setdefault(head, set())
            for item in list_:
                all_items.add(item)
                # No self dependencies
                if head != item:
                    dependency_graph[item].add(head)
                head = item
        try:
            return stable_topological_sort(all_items, dependency_graph)
        except CyclicDependencyError:
            warnings.warn(
                "Detected duplicate Media files in an opposite order: {}".format(
                    ", ".join(repr(list_) for list_ in lists)
                ),
                MediaOrderConflictWarning,
            )
            return list(all_items)
示例#2
0
    def merge(*lists):
        """
        Merge lists while trying to keep the relative order of the elements.
        Warn if the lists have the same elements in a different relative order.

        For static assets it can be important to have them included in the DOM
        in a certain order. In JavaScript you may not be able to reference a
        global or in CSS you might want to override a style.
        """
        dependency_graph = defaultdict(set)
        all_items = OrderedSet()
        for list_ in filter(None, lists):
            head = list_[0]
            # The first items depend on nothing but have to be part of the
            # dependency graph to be included in the result.
            dependency_graph.setdefault(head, set())
            for item in list_:
                all_items.add(item)
                # No self dependencies
                if head != item:
                    dependency_graph[item].add(head)
                head = item
        try:
            return stable_topological_sort(all_items, dependency_graph)
        except CyclicDependencyError:
            warnings.warn(
                'Detected duplicate Media files in an opposite order: {}'.format(
                    ', '.join(repr(l) for l in lists)
                ), MediaOrderConflictWarning,
            )
            return list(all_items)
 def test_basic(self):
     dependency_graph = {
         1: {2, 3},
         2: set(),
         3: set(),
         4: {5, 6},
         5: set(),
         6: {5},
     }
     self.assertEqual(list(topological_sort_as_sets(dependency_graph)), [{2, 3, 5}, {1, 6}, {4}])
     self.assertEqual(stable_topological_sort([1, 2, 3, 4, 5, 6], dependency_graph), [2, 3, 5, 1, 6, 4])
示例#4
0
def get_sorted_dependencies(service_model):
    """
    Returns list of application models in topological order.
    It is used in order to correctly delete dependent resources.
    """
    app_models = list(service_model._meta.app_config.get_models())
    dependencies = {model: set() for model in app_models}
    relations = (relation for model in app_models
                 for relation in model._meta.related_objects
                 if relation.on_delete in (models.PROTECT, models.CASCADE))
    for rel in relations:
        dependencies[rel.model].add(rel.related_model)
    return stable_topological_sort(app_models, dependencies)
示例#5
0
 def test_basic(self):
     dependency_graph = {
         1: {2, 3},
         2: set(),
         3: set(),
         4: {5, 6},
         5: set(),
         6: {5},
     }
     self.assertEqual(list(topological_sort_as_sets(dependency_graph)),
                      [{2, 3, 5}, {1, 6}, {4}])
     self.assertEqual(
         stable_topological_sort([1, 2, 3, 4, 5, 6], dependency_graph),
         [2, 3, 5, 1, 6, 4])
示例#6
0
    def get_executors(cls):
        # Get cleanup executors from extensions
        executors = [
            extension.get_cleanup_executor()
            for extension in WaldurExtension.get_extensions()
        ]

        # Filter empty items from list because cleanup executor is optional
        executors = [executor for executor in executors if executor]

        # Apply topological sort with respect to dependencies between executors
        dependencies = {}
        for executor in executors:
            dependencies[executor] = set()
            if executor.related_executor:
                dependencies.setdefault(executor.related_executor, set())
                dependencies[executor.related_executor].add(executor)
        return stable_topological_sort(executors, dependencies)