RuntimeError: dictionary changed size during iteration

R

Robert Dailey

I'm executing the following code:

def CopyBoost( libraries ):
pass

def CopyEmotionFX( libraries ):
pass


def Copy( library, aliases ):
pass

stuff = vars()
for key in stuff:
print( key, '--', stuff[key] )



I get the following error message:
('CopyEmotionFX', '--', <function CopyEmotionFX at 0x0205BF70>)
Traceback (most recent call last):
File "C:\IT\work\jewett\depends.py", line 12, in <module>
for key in stuff:
RuntimeError: dictionary changed size during iteration

Why is this happening?
 
T

Terry Reedy

Robert said:
stuff = vars() True

for key in stuff:

You just changed globals, which is aliased as stuff.
Stuff changes.
print( key, '--', stuff[key] )



I get the following error message:
('CopyEmotionFX', '--', <function CopyEmotionFX at 0x0205BF70>)
Traceback (most recent call last):
File "C:\IT\work\jewett\depends.py", line 12, in <module>
for key in stuff:
RuntimeError: dictionary changed size during iteration

Why is this happening?
 
R

Robert Dailey

Robert said:
stuff = vars()

 >>> vars() is globals()
True
for key in stuff:

You just changed globals, which is aliased as stuff.
Stuff changes.
    print( key, '--', stuff[key] )
I get the following error message:
('CopyEmotionFX', '--', <function CopyEmotionFX at 0x0205BF70>)
Traceback (most recent call last):
  File "C:\IT\work\jewett\depends.py", line 12, in <module>
    for key in stuff:
RuntimeError: dictionary changed size during iteration
Why is this happening?

How am I changing globals()? I'm simply iterating the keys in the
dict. Can someone explain what is going on please?
 
S

Steven D'Aprano

Robert said:
stuff = vars()

 >>> vars() is globals()
True
for key in stuff:

You just changed globals, which is aliased as stuff. Stuff changes.
    print( key, '--', stuff[key] )
I get the following error message:
('CopyEmotionFX', '--', <function CopyEmotionFX at 0x0205BF70>)
Traceback (most recent call last):
  File "C:\IT\work\jewett\depends.py", line 12, in <module>
    for key in stuff:
RuntimeError: dictionary changed size during iteration
Why is this happening?
How am I changing globals()? I'm simply iterating the keys in the dict.
Can someone explain what is going on please?

You create an new name "key":

for key in stuff

I suppose you could do this:


key = None
stuff = vars()
for key in stuff:


but even better would be:

for key in vars().copy():

because that protects you from cases where globals() change inside the
for loop.
 
J

John Machin

Robert Dailey wrote:
stuff = vars()
 >>> vars() is globals()
True
for key in stuff:
You just changed globals, which is aliased as stuff. Stuff changes.
    print( key, '--', stuff[key] )
I get the following error message:
('CopyEmotionFX', '--', <function CopyEmotionFX at 0x0205BF70>)
Traceback (most recent call last):
  File "C:\IT\work\jewett\depends.py", line 12, in <module>
    for key in stuff:
RuntimeError: dictionary changed size during iteration
Why is this happening?
How am I changing globals()? I'm simply iterating the keys in the dict.
Can someone explain what is going on please?

You create an new name "key":

for key in stuff

I suppose you could do this:

key = None
stuff = vars()
for key in stuff:

but both 'key' and 'stuff' will appear in the dict, possibly causing
confusion; another reason why
 
R

Robert Dailey

Robert Dailey wrote:
stuff = vars()
 >>> vars() is globals()
True
for key in stuff:
You just changed globals, which is aliased as stuff. Stuff changes.
    print( key, '--', stuff[key] )
I get the following error message:
('CopyEmotionFX', '--', <function CopyEmotionFX at 0x0205BF70>)
Traceback (most recent call last):
  File "C:\IT\work\jewett\depends.py", line 12, in <module>
    for key in stuff:
RuntimeError: dictionary changed size during iteration
Why is this happening?
How am I changing globals()? I'm simply iterating the keys in the dict.
Can someone explain what is going on please?
You create an new name "key":
for key in stuff
I suppose you could do this:
key = None
stuff = vars()
for key in stuff:

but both 'key' and 'stuff' will appear in the dict, possibly causing
confusion; another reason why
even better would be:
for key in vars().copy():
because that protects you from cases where globals() change inside the
for loop.

When I do:

for key in stuff.keys():


It works! I wonder why .keys() makes a difference. It is using a
'view', which is a new concept in Python 3.0 that I'm not totally
familiar with yet.
 
T

Terry Reedy

Robert said:
When I do:

for key in stuff.keys():


It works! I wonder why .keys() makes a difference. It is using a
'view', which is a new concept in Python 3.0 that I'm not totally
familiar with yet.

Because stuff.keys() is evaluated *once* and the result is a separate
object from stuff == globals(), so creating the new entry 'key' in
globals == stuff does not change that new object.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,744
Latest member
CortneyMcK

Latest Threads

Top