Author: christian.heimes
Date: Fri Jan 11 01:41:34 2008
New Revision: 59902
Modified:
python/branches/py3k-importhook/Lib/test/test_imp.py
python/branches/py3k-importhook/Python/import.c
Log:
Changed an implementation detail that causes the hooks to be called in a more
predictable order. If a hook for module is registered during the processing of
the versy same module than the hook is called after the already registered
hooks.
Hooks for loaded modules are still executed ASAP.
Modified: python/branches/py3k-importhook/Lib/test/test_imp.py
==============================================================================
--- python/branches/py3k-importhook/Lib/test/test_imp.py (original)
+++ python/branches/py3k-importhook/Lib/test/test_imp.py Fri Jan 11
01:41:34 2008
@@ -101,6 +101,26 @@
("pih_test a b __init__", "package = 2"),
]
+mod_callback = """
+import imp
+
+def callback(mod):
+ imp.test_callbacks.append(("pih_test%s", mod.__name__))
+
+imp.register_post_import_hook(callback, "pih_test")
+imp.register_post_import_hook(callback, "pih_test.a")
+imp.register_post_import_hook(callback, "pih_test.a.b")
+"""
+
+hier_withregister = [
+ ("pih_test", None),
+ ("pih_test __init__", mod_callback % ''),
+ ("pih_test a", None),
+ ("pih_test a __init__", mod_callback % '.a'),
+ ("pih_test a b", None),
+ ("pih_test a b __init__", mod_callback % '.a.b'),
+]
+
class CallBack:
def __init__(self):
self.mods = {}
@@ -116,11 +136,13 @@
self.sys_pih = sys.post_import_hooks.copy()
self.module_names = set(sys.modules)
self.sys_path = list(sys.path)
+ imp.test_callbacks = []
self.tmpdir = None
def tearDown(self):
sys.post_import_hooks = self.sys_pih
sys.path = self.sys_path
+ del imp.test_callbacks
for name in list(sys.modules):
if name not in self.module_names:
del sys.modules[name]
@@ -218,6 +240,40 @@
self.assertEqual(callback.names,
["pih_test", "pih_test.a", "pih_test.a.b"])
+ def test_hook_hirarchie(self):
+ self.tmpdir = mkhier(hier_withregister)
+
+ def callback(mod):
+ imp.test_callbacks.append(('', mod.__name__))
+
+ imp.register_post_import_hook(callback, "pih_test")
+ imp.register_post_import_hook(callback, "pih_test.a")
+ imp.register_post_import_hook(callback, "pih_test.a.b")
+
+ expected = []
+ self.assertEqual(imp.test_callbacks, expected)
+
+ import pih_test
+ expected.append(("", "pih_test"))
+ expected.append(("pih_test", "pih_test"))
+ self.assertEqual(imp.test_callbacks, expected)
+
+ import pih_test.a
+ expected.append(("pih_test.a", "pih_test"))
+ expected.append(("", "pih_test.a"))
+ expected.append(("pih_test", "pih_test.a"))
+ expected.append(("pih_test.a", "pih_test.a"))
+ self.assertEqual(imp.test_callbacks, expected)
+
+ import pih_test.a.b
+ expected.append(("pih_test.a.b", "pih_test"))
+ expected.append(("pih_test.a.b", "pih_test.a"))
+ expected.append(("", "pih_test.a.b"))
+ expected.append(("pih_test", "pih_test.a.b"))
+ expected.append(("pih_test.a", "pih_test.a.b"))
+ expected.append(("pih_test.a.b", "pih_test.a.b"))
+ self.assertEqual(imp.test_callbacks, expected)
+
def test_notifyloaded_byname(self):
callback = CallBack()
Modified: python/branches/py3k-importhook/Python/import.c
==============================================================================
--- python/branches/py3k-importhook/Python/import.c (original)
+++ python/branches/py3k-importhook/Python/import.c Fri Jan 11 01:41:34 2008
@@ -718,12 +718,9 @@
/* Either no hooks are defined or they are already fired */
if (hooks == NULL)
PyErr_Clear();
- goto end;
+ goto success;
}
Py_INCREF(hooks);
- if (PyDict_SetItem(registry, mod_name, Py_None) < 0) {
- goto end;
- }
if (!PyList_Check(hooks)) {
PyErr_Format(PyExc_TypeError,
"expected None or list of hooks, got '%.200s'",
@@ -739,13 +736,20 @@
o = PyObject_CallFunctionObjArgs(hook, module, NULL);
Py_DECREF(hook);
if (o == NULL) {
- goto error;
+ goto removehooks;
}
Py_DECREF(o);
}
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
- end:
+ success:
status = 0;
+ removehooks:
+ if (PyDict_SetItem(registry, mod_name, Py_None) < 0) {
+ status = -1;
+ }
error:
Py_XDECREF(mod_name);
Py_XDECREF(it);
@@ -838,6 +842,7 @@
locked = 1;
hooks = PyDict_GetItem(registry, mod_name);
+ Py_XINCREF(hooks);
/* module may be already loaded, get the module object from sys */
if (hooks == NULL || hooks == Py_None) {
PyObject *module = NULL;
@@ -856,7 +861,7 @@
if (o == NULL) {
goto error;
}
- goto end;
+ goto success;
}
else {
/* no hook has been registered so far */
@@ -882,7 +887,7 @@
goto error;
}
- end:
+ success:
status = 0;
error:
Py_XDECREF(callable);
_______________________________________________
Python-3000-checkins mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-3000-checkins