diff options
| author | Guido van Rossum <guido@python.org> | 1998-02-19 20:51:52 (GMT) | 
|---|---|---|
| committer | Guido van Rossum <guido@python.org> | 1998-02-19 20:51:52 (GMT) | 
| commit | f1dc0615e913fd0028a2fa6fda9607b3edfa76d5 (patch) | |
| tree | f2d858ecea20146e601215cf16d4072c32765720 /Objects/moduleobject.c | |
| parent | c83db33781d9333581f90c1f427b2c64c4e7c0d8 (diff) | |
| download | cpython-f1dc0615e913fd0028a2fa6fda9607b3edfa76d5.zip cpython-f1dc0615e913fd0028a2fa6fda9607b3edfa76d5.tar.gz cpython-f1dc0615e913fd0028a2fa6fda9607b3edfa76d5.tar.bz2  | |
Add internal routine _PyModule_Clear(), which does approximately what
clear_carefully() used to do in import.c.  Differences: leave only
__builtins__ alone in the 2nd pass; and don't clear the dictionary (on
the theory that as long as there are references left to the
dictionary, those might be destructors that might expect __builtins__
to be alive when they run; and __builtins__ can't normally be part of
a cycle).
Diffstat (limited to 'Objects/moduleobject.c')
| -rw-r--r-- | Objects/moduleobject.c | 51 | 
1 files changed, 50 insertions, 1 deletions
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 1ba1a1b..7a41439 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -93,6 +93,55 @@ PyModule_GetName(m)  	return PyString_AsString(nameobj);  } +void +_PyModule_Clear(m) +	PyObject *m; +{ +	/* To make the execution order of destructors for global +	   objects a bit more predictable, we first zap all objects +	   whose name starts with a single underscore, before we clear +	   the entire dictionary.  We zap them by replacing them with +	   None, rather than deleting them from the dictionary, to +	   avoid rehashing the dictionary (to some extent). */ + +	int pos; +	PyObject *key, *value; +	PyObject *d; + +	d = ((PyModuleObject *)m)->md_dict; + +	/* First, clear only names starting with a single underscore */ +	pos = 0; +	while (PyDict_Next(d, &pos, &key, &value)) { +		if (value != Py_None && PyString_Check(key)) { +			char *s = PyString_AsString(key); +			if (s[0] == '_' && s[1] != '_') { +				if (Py_VerboseFlag > 1) +				    fprintf(stderr, "#   clear[1] %s\n", s); +				PyDict_SetItem(d, key, Py_None); +			} +		} +	} + +	/* Next, clear all names except for __builtins__ */ +	pos = 0; +	while (PyDict_Next(d, &pos, &key, &value)) { +		if (value != Py_None && PyString_Check(key)) { +			char *s = PyString_AsString(key); +			if (s[0] != '_' || strcmp(s, "__builtins__") != 0) { +				if (Py_VerboseFlag > 1) +				    fprintf(stderr, "#   clear[2] %s\n", s); +				PyDict_SetItem(d, key, Py_None); +			} +		} +	} + +	/* Note: we leave __builtins__ in place, so that destructors +	   of non-global objects defined in this module can still use +	   builtins, in particularly 'None'. */ + +} +  /* Methods */  static void @@ -100,7 +149,7 @@ module_dealloc(m)  	PyModuleObject *m;  {  	if (m->md_dict != NULL) { -		PyDict_Clear(m->md_dict); +		_PyModule_Clear((PyObject *)m);  		Py_DECREF(m->md_dict);  	}  	free((char *)m);  | 
