diff options
author | Guido van Rossum <guido@python.org> | 2007-02-25 21:22:21 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2007-02-25 21:22:21 (GMT) |
commit | 5c0a6de79acfa39cc5e5b522d638c65dc1347030 (patch) | |
tree | f17367d4a3665787e8014aa2ce695cc0fc9eb579 /Lib | |
parent | 55b4a4a1a97ed880bbc1e12cbc8975fe9f84e32e (diff) | |
download | cpython-5c0a6de79acfa39cc5e5b522d638c65dc1347030.zip cpython-5c0a6de79acfa39cc5e5b522d638c65dc1347030.tar.gz cpython-5c0a6de79acfa39cc5e5b522d638c65dc1347030.tar.bz2 |
Use Glyph's trick to ensure that __globals__ is set properly.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/xreload.py | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/Lib/xreload.py b/Lib/xreload.py index 0730be5..921d87e 100644 --- a/Lib/xreload.py +++ b/Lib/xreload.py @@ -55,22 +55,22 @@ def xreload(mod): finally: if stream: stream.close() - # Execute the code in a temporary namespace; if this fails, no changes - tmpns = {} - exec(code, tmpns) + # Execute the code. We copy the module dict to a temporary; then + # clear the module dict; then execute the new code in the module + # dict; then swap things back and around. This trick (due to + # Glyph Lefkowitz) ensures that the (readonly) __globals__ + # attribute of methods and functions is set to the correct dict + # object. + tmpns = modns.copy() + modns.clear() + modns["__name__"] = tmpns["__name__"] + exec(code, modns) # Now we get to the hard part - oldnames = set(modns) - newnames = set(tmpns) - # Add newly introduced names - for name in newnames - oldnames: - modns[name] = tmpns[name] - # Delete names that are no longer current - # XXX What to do about renamed objects? - for name in oldnames - newnames - {"__name__"}: - del modns[name] - # Now update the rest in place + oldnames = set(tmpns) + newnames = set(modns) + # Update attributes in place for name in oldnames & newnames: - modns[name] = _update(modns[name], tmpns[name]) + modns[name] = _update(tmpns[name], modns[name]) # Done! return mod |