From c774057bf07b2da8539f2395555b2062428874f4 Mon Sep 17 00:00:00 2001 From: Simon King Date: Tue, 15 Oct 2013 16:16:22 +0200 Subject: [PATCH] Prepare hash and copy for immutable graphs. Let .weighted() respect mutability. --- src/sage/graphs/generic_graph.py | 40 +++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 49e0631d261..e60804039b6 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -304,6 +304,7 @@ """ from sage.misc.decorators import options +from sage.misc.cachefunc import cached_method from sage.misc.prandom import random from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer @@ -463,21 +464,18 @@ def __eq__(self, other): return False return True + @cached_method def __hash__(self): """ - Since graphs are mutable, they should not be hashable, so we return - a type error. + Only immutable graphs are hashable. - EXAMPLES:: - - sage: hash(Graph()) - Traceback (most recent call last): - ... - TypeError: graphs are mutable, and thus not hashable + The hash value of an immutable graph relies on the tuple + of vertices and the tuple of edges. The resulting value + is cached. """ if getattr(self, "_immutable", False): return hash((tuple(self.vertices()), tuple(self.edges()))) - raise TypeError("graphs are mutable, and thus not hashable") + raise TypeError("This graph is mutable, and thus not hashable") def __mul__(self, n): """ @@ -699,6 +697,11 @@ def __copy__(self, implementation='c_graph', data_structure=None, """ Creates a copy of the graph. + NOTE: + + If the graph is immutable then the graph itself is returned, rather + than a copy, unless one of the optional arguments is used. + INPUT: - ``implementation`` - string (default: 'networkx') the @@ -773,6 +776,9 @@ def __copy__(self, implementation='c_graph', data_structure=None, sage: h._boundary is g._boundary False """ + if getattr(self, '_immutable', False): + if implementation=='c_graph' and data_structure is None and sparse is not None: + return self if sparse != None: if data_structure != None: raise ValueError("The 'sparse' argument is an alias for " @@ -2180,8 +2186,18 @@ def weighted(self, new=None): """ Whether the (di)graph is to be considered as a weighted (di)graph. - Note that edge weightings can still exist for (di)graphs ``G`` where - ``G.weighted()`` is ``False``. + INPUT: + + - ``new`` (optional bool): If it is provided, then the weightedness + flag is set accordingly. + + .. NOTE:: + + Changing the weightedness flag changes the ``==``-class of + a graph and is thus not allowed for immutable graphs. + + Edge weightings can still exist for (di)graphs ``G`` where + ``G.weighted()`` is ``False``. EXAMPLES: @@ -2234,6 +2250,8 @@ def weighted(self, new=None): True """ if new is not None: + if getattr(self, '_immutable', False): + raise TypeError("This graph is immutable and can thus not be changed") if new in [True, False]: self._weighted = new else: