Skip to content

delete_vertices does not work on subclassed graph #496

@chaosflaws

Description

@chaosflaws

Describe the bug

I have subclassed Graph and added a custom __init__ method by:

  1. Creating an instance of the subclassed Graph
  2. Calling igraph.Graph.__init__
  3. Merging the existing graph into the new one

but this apparently fails when trying to delete vertices. The edge set is not updated properly. In the test, the graph is:

0 -> 0
1 -> 1

and the first edge has prop set to a while the second edge has prop set to b. Now, if I delete the first vertex, it would be expected that graph.es['prop'] returns b, but it returns a in the subclass case.

Fwiw, delete_vertices deals with vertex properties correctly and delete_edges seems to work fine as well.

To reproduce

Test case:

import unittest
from igraph import Graph


class TestSubclass(Graph):
    @staticmethod
    def __new__(cls, graph=None, *args, **kwargs):
        instance = super().__new__(cls, directed=True, *args, **kwargs)
        super().__init__(instance, directed=True, *args, **kwargs)

        if graph is not None:
            instance = instance.union(graph)

        return instance

    def __init__(self, graph=None, *args, **kwargs) -> None:
        pass


class SubclassTest(unittest.TestCase):
    def test_deleteVertices_igraph(self) -> None:
        graph = Graph(2, [(0, 0), (1, 1)], directed=True)
        graph.es['prop'] = ["a", "b"]

        graph.delete_vertices({1})

        self.assertEqual(["a"], graph.es['prop'])

    def test_deleteVertices_subclass(self) -> None:
        graph = Graph(2, [(0, 0), (1, 1)], directed=True)
        automaton = TestSubclass(graph)
        automaton.es['prop'] = ["a", "b"]

        automaton.delete_vertices({1})

        self.assertEqual(["a"], automaton.es['prop'])

    def test_incident_igraph(self) -> None:
        graph = Graph(4, [(0, 0), (1, 1), (2, 2), (3, 3)], directed=True)
        graph.es['prop'] = ["a", "b", "c", "d"]

        self.assertEqual(["a"], graph.es(_incident=[0])['prop'])

    def test_incident_subclass(self) -> None:
        graph = Graph(4, [(0, 0), (1, 1), (2, 2), (3, 3)], directed=True)
        automaton = TestSubclass(graph)
        automaton.es['prop'] = ["a", "b", "c", "d"]

        self.assertEqual(["a"], automaton.es(_incident=[0])['prop'])

    def test_deleteVertices_subclass_deleteEdge(self) -> None:
        graph = Graph(2, [(0, 0), (1, 1)], directed=True)
        automaton = TestSubclass(graph)
        automaton.es['prop'] = ["a", "b"]

        automaton.delete_edges({1})

        self.assertEqual(["a"], automaton.es['prop'])

    def test_deleteVertices_subclass_vertexSet(self) -> None:
        graph = Graph(2, [(0, 0), (1, 1)], directed=True)
        automaton = TestSubclass(graph)
        automaton.vs['prop'] = ["c", "d"]

        automaton.delete_vertices({1})

        self.assertEqual(["c"], automaton.vs['prop'])

Version information

igraph 0.9.8 on Python 3.9, also tested on igraph 0.9.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    highHigh-priority issue; typically for cases when igraph returns incorrect result for non-corner casestodoTriaged for implementation in some unspecified future version

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions