From 51d63284da70ffa4772a0d0fda6020750aef2e6d Mon Sep 17 00:00:00 2001 From: Simon King Date: Fri, 27 Dec 2013 22:10:39 +0100 Subject: [PATCH] Trac 15278: Error messages explain how to create (im)mutable graph copy --- src/sage/graphs/digraph.py | 3 ++- src/sage/graphs/generic_graph.py | 43 ++++++++++++++++++++++++++------ src/sage/graphs/graph.py | 6 +++-- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index bf43960cbc6..af944405c19 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -429,7 +429,8 @@ class DiGraph(GenericGraph): sage: {G_imm:1}[G] Traceback (most recent call last): ... - TypeError: This graph is mutable, and thus not hashable + TypeError: This graph is mutable, and thus not hashable. Create an + immutable copy by `g.copy(data_structure='static_sparse')` """ _directed = True diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 81112359b8b..245344011fa 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -479,7 +479,8 @@ def __hash__(self): sage: {G:1}[G] Traceback (most recent call last): ... - TypeError: This graph is mutable, and thus not hashable + TypeError: This graph is mutable, and thus not hashable. Create + an immutable copy by `g.copy(data_structure='static_sparse')` sage: G_imm = Graph(G, data_structure="static_sparse") sage: G_imm == G True @@ -491,7 +492,8 @@ def __hash__(self): """ if getattr(self, "_immutable", False): return hash((tuple(self.vertices()), tuple(self.edges()))) - raise TypeError("This graph is mutable, and thus not hashable") + raise TypeError("This graph is mutable, and thus not hashable. " + "Create an immutable copy by `g.copy(data_structure='static_sparse')`") def __mul__(self, n): """ @@ -781,8 +783,9 @@ def __copy__(self, implementation='c_graph', data_structure=None, sage: G2 is G False - TESTS: We make copies of the _pos and _boundary attributes. + TESTS: + We make copies of the _pos and _boundary attributes. :: sage: g = graphs.PathGraph(3) @@ -791,16 +794,38 @@ def __copy__(self, implementation='c_graph', data_structure=None, False sage: h._boundary is g._boundary False + + We make sure that one can make immutable copies by providing the + ``data_structure`` optional argument, and that copying an immutable graph + returns the graph:: + + sage: G = graphs.PetersenGraph() + sage: hash(G) + Traceback (most recent call last): + ... + TypeError: This graph is mutable, and thus not hashable. Create an + immutable copy by `g.copy(data_structure='static_sparse')` + sage: g = G.copy(data_structure='static_sparse') + sage: hash(g) # random + 1833517720 + sage: g==G + True + sage: g is copy(g) is g.copy() + True + sage: g is g.copy(data_structure='static_sparse') + True + """ - 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 " "'data_structure'. Please do not define both.") data_structure = "sparse" if sparse else "dense" + if getattr(self, '_immutable', False): + if implementation=='c_graph' and (data_structure=='static_sparse' or data_structure is None): + return self + if data_structure is None: from sage.graphs.base.dense_graph import DenseGraphBackend from sage.graphs.base.sparse_graph import SparseGraphBackend @@ -2285,12 +2310,14 @@ def weighted(self, new=None): sage: G_imm.weighted(True) Traceback (most recent call last): ... - TypeError: This graph is immutable and can thus not be changed + TypeError: This graph is immutable and can thus not be changed. + Create a mutable copy, e.g., by `g.copy(sparse=False)` """ if new is not None: if getattr(self, '_immutable', False): - raise TypeError("This graph is immutable and can thus not be changed") + raise TypeError("This graph is immutable and can thus not be changed. " + "Create a mutable copy, e.g., by `g.copy(sparse=False)`") if new in [True, False]: self._weighted = new else: diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 4b6480dd5b0..46bbaf8f55f 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -503,7 +503,8 @@ sage: {G:1}[G] Traceback (most recent call last): ... - TypeError: This graph is mutable, and thus not hashable + TypeError: This graph is mutable, and thus not hashable. Create an + immutable copy by `g.copy(data_structure='static_sparse')` sage: G_immutable = Graph(G, data_structure="static_sparse") sage: G_immutable == G True @@ -960,7 +961,8 @@ class Graph(GenericGraph): sage: {G:1}[H] Traceback (most recent call last): ... - TypeError: This graph is mutable, and thus not hashable + TypeError: This graph is mutable, and thus not hashable. Create + an immutable copy by `g.copy(data_structure='static_sparse')` If the ``data_structure`` is equal to ``"static_sparse"``, then an immutable graph results. Note that this does not use the NetworkX data