Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

__eq__ (equality) can in some cases return false for two identical graphs #41

Closed
Sappique opened this issue Apr 29, 2024 · 1 comment
Closed

Comments

@Sappique
Copy link

In some cases the private _edges of a graph can gain an empty dict as a entry. This leads to incorrect behavior when comparing graphs.
This bug is very similar to #40.

To reproduce

Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32
>>> from graph import Graph
>>> g1 = Graph(from_list=[(1,2),(2,3)])
>>> g2 = Graph(from_list=[(1,2),(2,3)])
>>> g1.edge(3,1)
>>> g1 == g2
False
>>> g1._edges
defaultdict(<class 'dict'>, {1: {2: 1}, 2: {3: 1}, 3: {}})
>>> g2._edges
defaultdict(<class 'dict'>, {1: {2: 1}, 2: {3: 1}})

Cause

The equality function of graphs compares the private variable _edges of both graphs and if they are not equal, the function returns false.
The variable _edges can in some cases be accessed with keys that don't exist, since it is a defaultdict(dict) in those cases a empty dict is created for that key. If that happens with only one of two identical graphs, they are no longer equal.
The accessing of _edges with not existing keys and thus the creation of a new entry can occur when edge(node1, node2) is called with a node1 without outgoing edges or sometimes when is_connected(n1, n2) is called depending on the graph. Those are the two examples I found, there could be more.

Other problems

Just like with #40 this also causes strange behavior when copying graphs, because copy() uses the public edge getter edges() instead of the private variable _edges.

Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32
>>> from graph import Graph
>>> g1 = Graph(from_list=[(1,2),(2,3)])
>>> g1.edge(3,1)
>>> g2 = g1.copy()
>>> g1 == g2
False
>>> g1._edges
defaultdict(<class 'dict'>, {1: {2: 1}, 2: {3: 1}, 3: {}})
>>> g2._edges  
defaultdict(<class 'dict'>, {1: {2: 1}, 2: {3: 1}})

Additional information

I'm using version 2023.7.6 of graph-theory with Python 3.10 on windows.

root-11 added a commit that referenced this issue Apr 29, 2024
root-11 added a commit that referenced this issue Apr 29, 2024
root-11 added a commit that referenced this issue Apr 29, 2024
root-11 added a commit that referenced this issue Apr 29, 2024
@root-11
Copy link
Owner

root-11 commented Apr 29, 2024

Thank you so much for the write-up @Sappique. This is a role-model bug report. Excellent work!

I have added your tests in a9be334 and added the bugfix in 58d78ac .

The release 2023.7.7 is now on pypi.org thanks to you.

@root-11 root-11 closed this as completed Apr 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants