please override __setslice__

Bug #557286 reported by Ximin Luo
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
igraph
New
Undecided
Unassigned

Bug Description

at the moment, vs.__setslice__ has no effect (i guess es. is the same), yet doesn't throw an exception:

$ python
Python 2.5.5 (r255:77872, Feb 2 2010, 00:25:36)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from igraph import Graph
>>> g = Graph(4)
>>> g.vs["id"] = ["zero", "one", "two", "three"]
>>> g.vs["id"][1:3]
['one', 'two']
>>> g.vs["id"][1:3] = ["one-new", "two-new"]
>>> g.vs["id"][1:3]
['one', 'two']

Revision history for this message
Tamás Nepusz (ntamas) wrote :

g.vs["id"] returns a copy of the appropriate slice of the underlying data structure, not the data structure itself; on the above copy, you are merely modifying the copy. However, you can use the slicing operator on g.vs itself, which returns another VertexSeq object (restricted to the appropriate set of vertices), and you can call __setslice__ on that:

>>> g.vs[1:3]["id"]
['one', 'two']
>>> g.vs[1:3]["id"] = ["one-new", "two-new"]
>>> g.vs["id"]
['zero', 'one-new', 'two-new', 'three']

Revision history for this message
Tamás Nepusz (ntamas) wrote :

s/on the above copy/in the above example/g

Revision history for this message
Ximin Luo (infinity0) wrote :

hmm, this is a bit inconsistent, because you can use g.vs["id"] = [...] to set the entire list sequence. also, if g.vs was a standard python dictionary, and g.vs["id"] was a standard python list, you would expect it to work.

is there any part of igraph that absolutely depends on g.vs["id"] returning a copy, and g.vs["id"] = [...] modifying the graph?

Revision history for this message
Tamás Nepusz (ntamas) wrote :

AFAIK no part of igraph depends on the behaviour that g.vs["id"] returns an unmodifiable copy, but third-party code using the igraph library might assume that. For instance, one can use g.vs["id"] to obtain a list of IDs in his code and then do anything with that list without the risk of the modifications being transferred back to the original graph (which happens more often than the opposite case when one wants those changes to be propagated back).

Here are some more details about this behaviour. The vs property of the Graph object returns a VertexSeq object that is bound to the graph instance and represents the whole vertex sequence of the graph. When you slice or index the VertexSeq (using g.vs[2] or g.vs[1:3] or whatever), you get _another_ VertexSeq that is bound to the same graph object but restricted to the selected vertices. That's why g.vs[1:3]["id"] = foo works and g.vs["id"][1:3] = foo does not work; in the former case, you are invoking __setitem__ on a VertexSeq object, while the latter involves calling __setslice__ on an ordinary Python list which is thrown away as soon as the statement finished execution. I think that the only way to change this behaviour is to make VertexSeq.__getitem__ return some kind of a proxy object in place of the list that it returns now, and make that proxy object translate __getitem__, __setitem__, __getslice__, __setslice__ (and whatever else that makes sense here) back to the underlying list object that is used to store the attribute values. However, this could break existing code for users who rely on igraph's existing behaviour that the list can safely be modified without affecting the original graph.

> also, if g.vs was a standard python dictionary, and g.vs["id"] was a standard python list, you would expect it to work.
if g.vs was a standard Python dictionary, you wouldn't be able to slice it using g.vs[1:3] anyway ;)

Revision history for this message
Gábor Csárdi (gabor.csardi) wrote : Continue on github

The development of igraph has moved to github, so please do not comment on this bug here. You are of course welcome to comment on github, here:
https://github.com/igraph/igraph/issues/413

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.