def test_with_cyclic_edges(self): graph = { 1: {2}, 2: {1}, } with self.assertRaises(CyclicGraphError): tsort(graph)
def _init_plugins(self): def _extend_plugin_type_graph(graph: Graph, plugin_type: Type): dependencies = plugin_type.depends_on() # Ensure each plugin type appears in the graph, even if they're isolated. graph.setdefault(plugin_type, set()) for dependency in dependencies: seen_dependency = dependency in graph graph[dependency].add(plugin_type) if not seen_dependency: _extend_plugin_type_graph(graph, dependency) plugin_types_graph = defaultdict(set) # Add dependencies to the plugin graph. for plugin_type in self._configuration.plugins.keys(): _extend_plugin_type_graph(plugin_types_graph, plugin_type) # Now all dependencies have been collected, extend the graph with optional plugin orders. for plugin_type in self._configuration.plugins.keys(): for before in plugin_type.comes_before(): if before in plugin_types_graph: plugin_types_graph[plugin_type].add(before) for after in plugin_type.comes_after(): if after in plugin_types_graph: plugin_types_graph[after].add(plugin_type) for plugin_type in tsort(plugin_types_graph): plugin_configuration = self.configuration.plugins[ plugin_type] if plugin_type in self.configuration.plugins else {} plugin = plugin_type.from_configuration_dict( self, plugin_configuration) self._plugins[plugin_type] = plugin for event_name, listener in plugin.subscribes_to(): self._event_dispatcher.add_listener(event_name, listener) if plugin.resource_directory_path is not None: self._resources.paths.appendleft( plugin.resource_directory_path)
def _init_plugins(self) -> None: from betty.plugin import NO_CONFIGURATION def _extend_plugin_type_graph(graph: Graph, plugin_type: Type['Plugin']): dependencies = plugin_type.depends_on() # Ensure each plugin type appears in the graph, even if they're isolated. graph.setdefault(plugin_type, set()) for dependency in dependencies: seen_dependency = dependency in graph graph[dependency].add(plugin_type) if not seen_dependency: _extend_plugin_type_graph(graph, dependency) plugin_types_graph = defaultdict(set) # Add dependencies to the plugin graph. for plugin_type, _ in self._configuration.plugins: _extend_plugin_type_graph(plugin_types_graph, plugin_type) # Now all dependencies have been collected, extend the graph with optional plugin orders. for plugin_type, _ in self._configuration.plugins: for before in plugin_type.comes_before(): if before in plugin_types_graph: plugin_types_graph[plugin_type].add(before) for after in plugin_type.comes_after(): if after in plugin_types_graph: plugin_types_graph[after].add(plugin_type) for plugin_type in tsort(plugin_types_graph): plugin_configuration = self.configuration.plugins[ plugin_type] if plugin_type in self.configuration.plugins else NO_CONFIGURATION plugin = plugin_type.for_site(self, plugin_configuration) self._plugins[plugin_type] = plugin
def test_with_isolated_vertices(self): graph = { 1: set(), 2: set(), } # Without edges we cannot assert the order. self.assertCountEqual([1, 2], tsort(graph))
def test_with_multiple_outdegrees(self): graph = { 1: {2, 3}, } vertices = tsort(graph) self.assertEquals(3, len(vertices)) self.assertEquals(1, vertices[0]) self.assertIn(2, vertices) self.assertIn(3, vertices)
def test_with_multiple_indegrees(self): graph = { 1: {3}, 2: {3}, } vertices = tsort(graph) self.assertEquals(3, len(vertices)) self.assertIn(1, vertices) self.assertIn(2, vertices) self.assertEquals(3, vertices[2])
def _clean_places(ancestry: Ancestry) -> None: places = list(ancestry.places.values()) def _extend_place_graph(graph: Graph, enclosing_place: Place) -> None: enclosed_places = enclosing_place.encloses # Ensure each place appears in the graph, even if they're anonymous. graph.setdefault(enclosing_place, set()) for enclosed_place in enclosed_places: seen_enclosed_place = enclosed_place in graph graph[enclosed_place].add(enclosing_place) if not seen_enclosed_place: _extend_place_graph(graph, enclosed_place) places_graph = defaultdict(set) for place in places: _extend_place_graph(places_graph, place) for place in tsort(places_graph): _clean_place(ancestry, place)
def test_with_empty_graph(self): graph = {} self.assertCountEqual([], tsort(graph))
def test_with_multiple_chained_edges(self): graph = { 2: {3}, 1: {2}, } self.assertEquals([1, 2, 3], tsort(graph))
def test_with_edges(self): graph = { 1: {2}, } self.assertEquals([1, 2], tsort(graph))