Modifying while looping

Hello, I’m not able to run a script I wrote a while ago (with Glyphs 1.x).

font = Glyphs.font
glyphs = font.glyphs

for glyph in glyphs:
	name = glyph.name
	newname = "new"+name
	glyph.name = newname

is returning:
Traceback (most recent call last):
File “”, line 4, in
File “GlyphsApp/init.py”, line 141, in iter
File “/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC/objc/_convenience.py”, line 589, in enumeratorGenerator
yield container_unwrap(anEnumerator.nextObject(), StopIteration)
objc.error: NSGenericException - *** Collection <__NSArrayM: 0x608003a5b2d0> was mutated while being enumerated.

It seams to be a very simple and useful thing to do, and I think it used to work on Glyphs 1.x

I found something about this error here in the forum but I can’t understand the logic of it…

Thanks a lot for your help!

Sylvain

This happens because the list of glyphs becomes different (“is mutated”) after the first glyph gets renamed. The list of [“A”, “B”, “C”] is lost after it’s changed to [“newA”, “B”, “C”]. You probably should make a list of glyph names elsewhere first and iterate through it.

use a copy of the glyphs list:

font = Glyphs.font
glyphs = list(font.glyphs)

for glyph in glyphs:
	name = glyph.name
	newname = "new"+name
	glyph.name = newname

Great!
This was exactly the simple answer I was hoping for :grinning:
Thank you very much!

Yes, you cannot change something you are looping through. But you can collect the items you want to change, count the items, and then loop through a list of indexes generated by range(itemcount):

font = Glyphs.font
glyphs = font.glyphs
glyphcount = len(glyphs)

for i in range(glyphcount):
	glyph = glyphs[i]
	name = glyph.name
	newname = "new"+name
	glyph.name = newname