Skip to content

remove_edges_from causing RuntimeError on certain view generators #2717

@ahrenberg

Description

@ahrenberg

In certain cases when remove_edges_from is operating on an view generator it will fail with a RuntimeError due to the yielded objects being the same as those removed.

I have observed it in two cases:

  1. On on view returned by nx.selfloop_edges operating on MultiGraph and MultiDiGraph objects. G.remove_edges_from(nx.selfloop_edges(G)) is a standard construction for removing self-loops. It works with Graph and DiGraph, but fails for MultiGraph and MultiDiGraph.

  2. On the view returned by nx.edges for all graph types. The construction G.remove_edges_from(nx.edges(G)) might not be very useful, but the error also occurs when using functions from itertools to manipulate the view of nx.edges(G). Examples below.

Of course, in 2 the behaviour might perhaps be expected - the view seems to be an iterator to the same object as being manipulated, which is problematic. (A workaround is of course to create a list from it.)

However in 1, the selfloop view seems to be handled for Graph and DiGraph, so might it not be expected to work also for the ones provided for MultiGraph and MultiDiGraph?

Error-producing example

These three examples all fail:

Removing self-loops from MultiGraph

import networkx as nx
G = nx.MultiGraph([(0,0), (1,1), (0,1)])
G.remove_edges_from(nx.selfloop_edges(G)) # Fail here

Error Message

Traceback (most recent call last):                                                                                    
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/site-packages/networkx/classes/multigraph.py", line 603, in remove_edges_from              
    for e in ebunch:                                                                                                  
  File "/usr/lib/python3.6/site-packages/networkx/classes/function.py", line 1150, in <genexpr>
    if n in nbrs for d in nbrs[n].values())
  File "/usr/lib/python3.6/_collections_abc.py", line 761, in __iter__
    for key in self._mapping:
RuntimeError: dictionary changed size during iteration

Removing all edges from Graph

import networkx as nx
G = nx.Graph([(0,1), (1,2), (2,3)])
G.remove_edges_from(nx.edges(G)) # Fail here

Error Message

Traceback (most recent call last):                                                                                    
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/site-packages/networkx/classes/graph.py", line 1038, in remove_edges_from                  
    for e in ebunch:                                                                                                  
  File "/usr/lib/python3.6/site-packages/networkx/classes/reportviews.py", line 1024, in __iter__
    for nbr in nbrs:
RuntimeError: dictionary changed size during iteration

Manipulating edge view using itertools:

import networkx as nx
import itertools
G = nx.DiGraph([(0,1), (1,2), (2,3)])
# Remove edges not staring at 1.
e_iter = itertools.filterfalse(lambda e : e[0] == 1, nx.edges(G))
G.remove_edges_from(e_iter) # Fail here

Error Message

Traceback (most recent call last):                                                                                    
  File "<stdin>", line 1, in <module>                                                                                 
  File "/usr/lib/python3.6/site-packages/networkx/classes/digraph.py", line 753, in remove_edges_from                 
    for e in ebunch:                                                                                                  
  File "/usr/lib/python3.6/site-packages/networkx/classes/reportviews.py", line 914, in __iter__
    for nbr in nbrs:
RuntimeError: dictionary changed size during iteration

Version information

NetworkX: 2.0
sys.version_info(major=3, minor=6, micro=2, releaselevel='final', serial=0)

Finally, thanks for your work on NetworkX.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions