Commit 36e4c21d authored by Tiago Peixoto's avatar Tiago Peixoto

Ensure that PropertyMaps always belong to the desired graph

parent a4ad0019
......@@ -181,6 +181,12 @@ def _prop(t, g, prop):
names = {'e': 'edge', 'v': 'vertex', 'g': 'graph'}
raise ValueError("Expected '%s' property map, got '%s'" %
(names[t], names[prop.key_type()]))
u = pmap.get_graph()
if u is None:
raise ValueError("Received orphaned property map")
if g.base is not u.base:
raise ValueError("Received property map for graph %s (base: %s), expected: %s (base: %s)" %
(str(g), str(g.base), str(u), str(u.base)))
return pmap._get_any()
......@@ -377,14 +383,9 @@ class PropertyMap(object):
def __init__(self, pmap, g, key_type):
self.__map = pmap
self.__g = weakref.ref(g)
self.__base_g = lambda: None
try:
if isinstance(g, GraphView):
self.__base_g = weakref.ref(g.base) # keep reference to the
# base graph, in case the
# graph view is deleted.
except NameError:
pass # ignore if GraphView is yet undefined
self.__base_g = weakref.ref(g.base) # keep reference to the
# base graph, in case the
# graph view is deleted.
self.__key_type = key_type
self.__convert = _converter(self.value_type())
self.__register_map()
......@@ -1318,6 +1319,13 @@ class InternalPropertyDict(dict):
@_require("val", PropertyMap)
def __setitem__(self, key, val):
t, k = key
u = val.get_graph()
if u is None:
raise ValueError("Received orphaned property map")
g = self.g()
if u.base is not g.base:
raise ValueError("Received property map for graph %s (base: %s), expected: %s (base: %s)" %
(str(u), str(u.base), str(g), str(g.base)))
self.__set_property(t, k, val)
@_limit_args({"t": ["v", "e", "g"]})
......@@ -2897,6 +2905,9 @@ class Graph(object):
stream = gzip.GzipFile(fileobj=sio, mode="rb")
self.load(stream, "xml")
def __get_base(self):
return self
base = property(__get_base, doc="Base graph (self).")
def load_graph(file_name, fmt="auto", ignore_vp=None, ignore_ep=None,
ignore_gp=None):
......@@ -3068,7 +3079,7 @@ class GraphView(Graph):
def __init__(self, g, vfilt=None, efilt=None, directed=None,
reversed=False, skip_properties=False, skip_vfilt=False,
skip_efilt=False):
self.__base = g if not isinstance(g, GraphView) else g.base
self.__base = g.base
Graph.__init__(self)
# copy graph reference
self._Graph__graph = libcore.GraphInterface(g._Graph__graph, True,
......
......@@ -840,8 +840,8 @@ def radial_tree_layout(g, root, rel_order=None, rel_order_leaf=False,
elif node_weight.value_type() != "double":
node_weight = node_weight.copy("double")
libgraph_tool_layout.get_radial(t._Graph__graph,
_prop("v", g, pos),
_prop("v", g, levels),
_prop("v", t, pos),
_prop("v", t, levels),
_prop("v", g, rel_order),
_prop("v", g, node_weight),
int(root), weighted, r,
......
......@@ -699,8 +699,10 @@ def cairo_draw(g, pos, cr, vprops=None, eprops=None, vorder=None, eorder=None,
parallel_distance = _defaults
eprops["control_points"] = position_parallel_edges(g, pos, loop_angle,
parallel_distance)
generator = libgraph_tool_draw.cairo_draw(g._Graph__graph, _prop("v", g, pos),
_prop("v", g, vorder), _prop("e", g, eorder),
generator = libgraph_tool_draw.cairo_draw(g._Graph__graph,
_prop("v", g, pos),
_prop("v", g, vorder),
_prop("e", g, eorder),
nodesfirst, vattrs, eattrs, vdefs, edefs, res,
max_render_time, cr)
if max_render_time >= 0:
......@@ -2048,18 +2050,23 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, node_weight=None,
vorder = kwargs.pop("vorder", None)
if vorder is None:
vorder = g.degree_property_map("total")
tvorder = u.own_property(tvorder)
tvorder.fa[:g.num_vertices()] = vorder.fa
for k, v in kwargs.items():
if isinstance(v, PropertyMap) and v.get_graph().base is not u.base:
kwargs[k] = u.own_property(v.copy())
pos = graph_draw(u, pos, vprops=t_vprops, eprops=t_eprops, vorder=tvorder,
**kwargs)
if isinstance(pos, PropertyMap):
pos = g.own_property(pos)
t_orig.copy_property(pos, tpos, g=u)
pos = g.own_property(pos)
else:
t_orig.copy_property(pos[0], tpos, g=u)
pos = (g.own_property(pos[0]),
g.own_property(pos[1]))
t_orig.copy_property(pos[0], tpos, g=u)
return pos, t_orig, tpos
......
......@@ -922,7 +922,7 @@ def generate_sbm(b, probs, out_degs=None, in_degs=None, directed=False):
... g.degree_property_map("in").a, directed=True)
>>> gt.graph_draw(g, g.vp.pos, output="polblogs-sbm.png")
<...>
>>> gt.graph_draw(u, g.vp.pos, output="polblogs-sbm-generated.png")
>>> gt.graph_draw(u, u.own_property(g.vp.pos), output="polblogs-sbm-generated.png")
<...>
.. image:: polblogs-sbm.*
......@@ -1195,7 +1195,7 @@ def graph_union(g1, g2, intersection=None, props=None, include=False,
vmap, emap = libgraph_tool_generation.graph_union(u1._Graph__graph,
u2._Graph__graph,
_prop("v", g1,
_prop("v", g2,
intersection))
if include:
......@@ -1915,7 +1915,7 @@ def condensation_graph(g, prop, vweight=None, eweight=None, avprops=None,
raise ValueError("Cannot compute sum of string properties!")
temp = g.new_vertex_property(p.value_type())
cp = gp.new_vertex_property(p.value_type())
avp.append((_prop("v", g, p), _prop("v", g, temp), _prop("v", g, cp)))
avp.append((_prop("v", g, p), _prop("v", g, temp), _prop("v", gp, cp)))
r_avp.append(cp)
if aeprops is None:
......@@ -1929,7 +1929,7 @@ def condensation_graph(g, prop, vweight=None, eweight=None, avprops=None,
raise ValueError("Cannot compute sum of string properties!")
temp = g.new_edge_property(p.value_type())
cp = gp.new_edge_property(p.value_type())
aep.append((_prop("e", g, p), _prop("e", g, temp), _prop("e", g, cp)))
aep.append((_prop("e", g, p), _prop("e", g, temp), _prop("e", gp, cp)))
r_aep.append(cp)
libgraph_tool_generation.community_network(g._Graph__graph,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment