Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

""" 

Mutability Cython Implementation 

""" 

  

########################################################################## 

# 

# Sage: System for Algebra and Geometry Experimentation 

# 

# Copyright (C) 2006 William Stein <wstein@gmail.com> 

# 

# Distributed under the terms of the GNU General Public License (GPL) 

# http://www.gnu.org/licenses/ 

########################################################################## 

from __future__ import print_function, absolute_import 

  

  

cdef class Mutability: 

  

def __init__(self, is_immutable=False): 

self._is_immutable = is_immutable 

  

def _require_mutable(self): 

if self._is_immutable: 

raise ValueError("object is immutable; please change a copy instead.") 

  

cdef _require_mutable_cdef(self): 

if self._is_immutable: 

raise ValueError("object is immutable; please change a copy instead.") 

  

def set_immutable(self): 

""" 

Make this object immutable, so it can never again be changed. 

  

EXAMPLES:: 

  

sage: v = Sequence([1,2,3,4/5]) 

sage: v[0] = 5 

sage: v 

[5, 2, 3, 4/5] 

sage: v.set_immutable() 

sage: v[3] = 7 

Traceback (most recent call last): 

... 

ValueError: object is immutable; please change a copy instead. 

""" 

self._is_immutable = 1 

  

def is_immutable(self): 

""" 

Return True if this object is immutable (can not be changed) 

and False if it is not. 

  

To make this object immutable use self.set_immutable(). 

  

EXAMPLES:: 

  

sage: v = Sequence([1,2,3,4/5]) 

sage: v[0] = 5 

sage: v 

[5, 2, 3, 4/5] 

sage: v.is_immutable() 

False 

sage: v.set_immutable() 

sage: v.is_immutable() 

True 

""" 

self._is_immutable 

  

def is_mutable(self): 

return not self._is_immutable 

  

def __reduce__(self): 

return Mutability, (self._is_immutable, ) 

  

################################################################################# 

## Method decorators for mutating methods resp. methods that assume immutability 

from sage.misc.decorators import sage_wraps 

  

def require_mutable(f): 

""" 

A decorator that requires mutability for a method to be called. 

  

EXAMPLES:: 

  

sage: from sage.structure.mutability import require_mutable, require_immutable 

sage: class A(object): 

....: def __init__(self, val): 

....: self._m = val 

....: @require_mutable 

....: def change(self, new_val): 

....: 'change self' 

....: self._m = new_val 

....: @require_immutable 

....: def __hash__(self): 

....: 'implement hash' 

....: return hash(self._m) 

sage: a = A(5) 

sage: a.change(6) 

sage: hash(a) 

Traceback (most recent call last): 

... 

ValueError: <class '__main__.A'> instance is mutable, <function __hash__ at ...> must not be called 

sage: a._is_immutable = True 

sage: hash(a) 

6 

sage: a.change(7) # indirect doctest 

Traceback (most recent call last): 

... 

ValueError: <class '__main__.A'> instance is immutable, <function change at ...> must not be called 

sage: from sage.misc.sageinspect import sage_getdoc 

sage: print(sage_getdoc(a.change)) 

change self 

  

AUTHORS: 

  

- Simon King <simon.king@uni-jena.de> 

""" 

@sage_wraps(f) 

def new_f(self, *args,**kwds): 

if getattr(self, '_is_immutable', False): 

raise ValueError("%s instance is immutable, %s must not be called" % (type(self), repr(f))) 

return f(self, *args, **kwds) 

return new_f 

  

def require_immutable(f): 

""" 

A decorator that requires mutability for a method to be called. 

  

EXAMPLES:: 

  

sage: from sage.structure.mutability import require_mutable, require_immutable 

sage: class A(object): 

....: def __init__(self, val): 

....: self._m = val 

....: @require_mutable 

....: def change(self, new_val): 

....: 'change self' 

....: self._m = new_val 

....: @require_immutable 

....: def __hash__(self): 

....: 'implement hash' 

....: return hash(self._m) 

sage: a = A(5) 

sage: a.change(6) 

sage: hash(a) # indirect doctest 

Traceback (most recent call last): 

... 

ValueError: <class '__main__.A'> instance is mutable, <function __hash__ at ...> must not be called 

sage: a._is_immutable = True 

sage: hash(a) 

6 

sage: a.change(7) 

Traceback (most recent call last): 

... 

ValueError: <class '__main__.A'> instance is immutable, <function change at ...> must not be called 

sage: from sage.misc.sageinspect import sage_getdoc 

sage: print(sage_getdoc(a.__hash__)) 

implement hash 

  

AUTHORS: 

  

- Simon King <simon.king@uni-jena.de> 

""" 

@sage_wraps(f) 

def new_f(self, *args,**kwds): 

if not getattr(self,'_is_immutable',False): 

raise ValueError("%s instance is mutable, %s must not be called"%(type(self), repr(f))) 

return f(self, *args,**kwds) 

return new_f