@@ -117,14 +117,18 @@ def __init__(self, left, right=None, op=None):
117
117
if isinstance (left , Cycler ):
118
118
self ._left = Cycler (left ._left , left ._right , left ._op )
119
119
elif left is not None :
120
- self ._left = list (left )
120
+ # Need to copy the dictionary or else that will be a residual
121
+ # mutable that could lead to strange errors
122
+ self ._left = [copy .copy (v ) for v in left ]
121
123
else :
122
124
self ._left = None
123
125
124
126
if isinstance (right , Cycler ):
125
127
self ._right = Cycler (right ._left , right ._right , right ._op )
126
128
elif right is not None :
127
- self ._right = list (right )
129
+ # Need to copy the dictionary or else that will be a residual
130
+ # mutable that could lead to strange errors
131
+ self ._right = [copy .copy (v ) for v in right ]
128
132
else :
129
133
self ._right = None
130
134
@@ -138,6 +142,41 @@ def keys(self):
138
142
"""
139
143
return set (self ._keys )
140
144
145
+ def change_key (self , old , new ):
146
+ """
147
+ Change a key in this cycler to a new name.
148
+ Modification is performed in-place.
149
+
150
+ Does nothing if the old key is the same as the new key.
151
+ Raises a ValueError if the new key is already a key.
152
+ Raises a KeyError if the old key isn't a key.
153
+
154
+ """
155
+ if old == new :
156
+ return
157
+ if new in self ._keys :
158
+ raise ValueError ("Can't replace %s with %s, %s is already a key" %
159
+ (old , new , new ))
160
+ if old not in self ._keys :
161
+ raise KeyError ("Can't replace %s with %s, %s is not a key" %
162
+ (old , new , old ))
163
+
164
+ self ._keys .remove (old )
165
+ self ._keys .add (new )
166
+
167
+ if self ._right is not None and old in self ._right .keys :
168
+ self ._right .change_key (old , new )
169
+
170
+ # self._left should always be non-None
171
+ # if self._keys is non-empty.
172
+ elif isinstance (self ._left , Cycler ):
173
+ self ._left .change_key (old , new )
174
+ else :
175
+ # It should be completely safe at this point to
176
+ # assume that the old key can be found in each
177
+ # iteration.
178
+ self ._left = [{new : entry [old ]} for entry in self ._left ]
179
+
141
180
def _compose (self ):
142
181
"""
143
182
Compose the 'left' and 'right' components of this cycle
0 commit comments