Title: Document that runpy.run_path and run_module copy the module globals
Type: enhancement Stage: needs patch
Components: Documentation Versions: Python 3.3, Python 3.4, Python 2.7
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: Drekin, docs@python, ncoghlan, sbt
Priority: normal Keywords:

Created on 2013-06-30 14:33 by Drekin, last changed 2013-07-01 00:25 by ncoghlan.

Messages (3)
msg192072 - (view) Author: Adam BartoŇ° (Drekin) * Date: 2013-06-30 14:33
Let's have a simple script
def f():
	return x
x = 2

Now if we try to run it via runpy.run_path, we get the following:
>>> import runpy
>>> g = runpy.run_path("")
>>> g["f"]() is None
>>> g["x"] is 2
>>> g["f"].__globals__["x"] is None

Is the behaviour of f.__globals__ after return from run_path intended and why?
msg192078 - (view) Author: Richard Oudkerk (sbt) * (Python committer) Date: 2013-06-30 16:58
When modules are garbage collected the associated globals dict is purged -- see #18214.  This means that all values (except __builtins__) are replaced by None.

To work around this run_path() apparently returns a *copy* of the globals dict which was created before purging.
msg192097 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2013-07-01 00:25
As Richard said, the __globals__ attributes of the functions are pointing at the real module dictionary, which may have been cleared when the temporary module was destroyed.

However, I just checked the docs and they don't actually mention the fact that run_path and run_module currently return a copy of the globals - they say they "return the resulting module globals dictionary."

Since I would prefer it if the functions actually worked as advertised, I suggest we document the namespace copying as a CPython implementation detail, rather than as a guaranteed feature. That way we can eliminate these copy operations once the module namespace purging has been eliminated.

Some related references:
   Don't purge module dicts before shutdown: issue 18214
   Don't purge module dicts at all: issue 812369
   More robust finalisation semantics: PEP 442
We should also tidy up the headings in the data model reference ( so we can link directly to the section that mentions the CPython module clearing implementation detail this behaviour is designed to work around.
Date User Action Args
2013-07-01 00:25:49ncoghlansetassignee: docs@python
type: behavior -> enhancement

components: + Documentation, - Library (Lib)
title: runpy.run_path gives functions with corrupted .__globals__ -> Document that runpy.run_path and run_module copy the module globals
nosy: + docs@python
versions: + Python 2.7, Python 3.4
messages: + msg192097
stage: needs patch
2013-06-30 16:58:58sbtsetnosy: + sbt
messages: + msg192078
2013-06-30 15:27:14r.david.murraysetnosy: + ncoghlan
2013-06-30 14:33:02Drekincreate