Skip to content

Commit 1898aa2

Browse files
committed
Implement key changing
1 parent 68b4995 commit 1898aa2

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

cycler.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,46 @@ def keys(self):
138138
"""
139139
return set(self._keys)
140140

141+
def key_change(self, old, new):
142+
"""
143+
Change a key in this cycler to a new name.
144+
Modification is performed in-place.
145+
146+
Does nothing if the old key is the same as the new key.
147+
Raises a ValueError if the new key is already a key.
148+
Raises a KeyError if the old key isn't a key.
149+
150+
"""
151+
if old == new:
152+
return
153+
if new in self._keys:
154+
raise ValueError("Can't replace %s with %s, %s is already a key" %
155+
(old, new, new))
156+
if old not in self._keys:
157+
raise KeyError("Can't replace %s with %s, %s is not a key" %
158+
(old, new, old))
159+
160+
self._keys.remove(old)
161+
self._keys.add(new)
162+
163+
if self._right is not None and old in self._right.keys:
164+
self._right.key_change(old, new)
165+
elif self._left is not None:
166+
if isinstance(self._left, Cycler):
167+
self._left.key_change(old, new)
168+
else:
169+
Cycler._key_change(iter(self._left), old, new)
170+
171+
@staticmethod
172+
def _key_change(itr, old, new):
173+
entry = six.next(itr)
174+
if old in entry:
175+
entry[new] = entry[old]
176+
del entry[old]
177+
for entry in itr:
178+
entry[new] = entry[old]
179+
del entry[old]
180+
141181
def _compose(self):
142182
"""
143183
Compose the 'left' and 'right' components of this cycle

test_cycler.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,32 @@ def test_copying():
216216
assert_equal(c3, cycler('foo', [['y', 'g', 'blue'], ['b', 'k']]))
217217

218218

219+
def test_keychange():
220+
c1 = cycler('c', 'rgb')
221+
c2 = cycler('lw', [1, 2, 3])
222+
c3 = cycler('ec', 'yk')
223+
224+
c3.key_change('ec', 'edgecolor')
225+
assert_equal(c3, cycler('edgecolor', c3))
226+
227+
c = c1 + c2
228+
c.key_change('lw', 'linewidth')
229+
assert_equal(c, c1 + cycler('linewidth', c2))
230+
231+
c = (c1 + c2) * c3
232+
c.key_change('c', 'color')
233+
assert_equal(c, (cycler('color', c1) + c2) * c3)
234+
235+
# Perfectly fine, it is a no-op
236+
c.key_change('color', 'color')
237+
assert_equal(c, (cycler('color', c1) + c2) * c3)
238+
239+
# Can't change a key to one that is already in there
240+
assert_raises(ValueError, Cycler.key_change, c, 'color', 'linewidth')
241+
# Can't change a key you don't have
242+
assert_raises(KeyError, Cycler.key_change, c, 'c', 'foobar')
243+
244+
219245
def _eq_test_helper(a, b, res):
220246
if res:
221247
assert_equal(a, b)

0 commit comments

Comments
 (0)