Martin Panter added the comment:

You are basically right that it is garbage collection which causes your 
generator instance to be cleaned up, and in this instance it is happening after 
“time.sleep” has been set to None. It could also happen in the order, which 
would explain why changing names changes the behaviour you see.

Why the interpreter has to set module globals to None I’ve never quite 
understood. Maybe it is to guarantee that modules involved in garbage cycles 
with __del__() can still be partly cleaned up, otherwise such a cycle could 
easily keep lots of modules alive via globals.

This is not documented very obviously either. The best I can find at the moment 
is the warning under 
<https://docs.python.org/2/reference/datamodel.html#object.__del__>, which says 
“when __del__() is invoked in response to a module being deleted, [globals may 
be] in the process of being torn down”. The same applies to generator cleanup 
code. Looking through Python code you will often find workarounds such as 
prefixing globals with an underscore or caching references in non-global 
locations.

My recommended workaround though is to avoid relying on garbage collection as 
much as possible, and instead use a try / finally or “with” block. Then you 
know exactly when your generator will be cleaned up:

ct = create_generator()
try:
    ct.next()
finally:
    ct.close()

from contextlib import closing
with closing(create_generator()) as ct:
    ct.next()

----------
nosy: +martin.panter
type: crash -> behavior

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue25069>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to