Q:

Error with networx.descendants() when nodes have tags

I am using networkx with Python 3.4, and I get a weird error when I try to find the reachable nodes. I think it has something to do with an optional property of the nodes, that I previously set. This minimal code replicates the error:
import networkx as nx

G = nx.Graph()
nodes = ["A", "B", "C", "D", "E"]                                      
G.add_nodes_from(nodes)                                                
G.add_edge("A", "B")
G.add_edge("A", "C")                                                   
G.add_edge("A", "D")                                                   
G.add_edge("B", "E")

for node in nodes :
        G[node]['occurrences'] = 1                                     

print("Now computing nodes reachable from \"A\"...")
reachableNodes = nx.descendants(G, "A")                                
print("List of reachable nodes:", reachableNodes)

The output is:
Now computing nodes reachable from "A"...
Traceback (most recent call last):
  File "exampleStackOverflow.py", line 17, in <module>
    reachableNodes = nx.descendants(G, "A")
  File "/usr/local/lib/python3.4/dist-packages/networkx/algorithms/dag.py", line 42, in descendants
    des = set(nx.shortest_path_length(G, source=source).keys()) - set([source])
  File "/usr/local/lib/python3.4/dist-packages/networkx/algorithms/shortest_paths/generic.py", line 239, in shortest_path_length
    paths=nx.single_source_shortest_path_length(G,source)
  File "/usr/local/lib/python3.4/dist-packages/networkx/algorithms/shortest_paths/unweighted.py", line 63, in single_source_shortest_path_length
    nextlevel.update(G[v]) # add neighbors of v
  File "/usr/local/lib/python3.4/dist-packages/networkx/classes/graph.py", line 407, in __getitem__
    return self.adj[n]
KeyError: 'occurrences'

Now, if I comment the lines when I set the tag 'occurrences', I get the expected result:
Now computing nodes reachable from "A"...
List of reachable nodes: {'B', 'D', 'C', 'E'}

Am I doing something wrong?

A:

@Gerrat's approach using a custom node class will work.  But the recommended way is to use G.node to store node data.  You got it almost correct.  This is the problem code
for node in nodes :
    G[node]['occurrences'] = 1 # INCORRECT, corrupts data structure

for node in nodes :
    G.node[node]['occurrences'] = 1 # CORRECT

Working example
import networkx as nx

G = nx.Graph()
nodes = ["A", "B", "C", "D", "E"]
G.add_nodes_from(nodes)
G.add_edge("A", "B")
G.add_edge("A", "C")
G.add_edge("A", "D")
G.add_edge("B", "E")

for n in nodes :
        G.node[n]['occurrences'] = 1

print("Now computing nodes reachable from \"A\"...")
reachableNodes = nx.descendants(G, "A")
print("List of reachable nodes:", reachableNodes)

for n in reachableNodes:
    print n,G.node[n]

#OUTPUT
Now computing nodes reachable from "A"...
('List of reachable nodes:', set(['C', 'B', 'E', 'D']))
C {'occurrences': 1}
B {'occurrences': 1}
E {'occurrences': 1}
D {'occurrences': 1}

There is more information at https://networkx.readthedocs.org/en/stable/tutorial/tutorial.html#adding-attributes-to-graphs-nodes-and-edges on how to set graph, node, and edge attributes.

