You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mod_python-commits@quetz.apache.org by gr...@apache.org on 2006/03/17 05:14:25 UTC

svn commit: r386524 - in /httpd/mod_python/trunk: Doc/appendixc.tex Doc/modpython5.tex lib/python/mod_python/apache.py src/mod_python.c test/htdocs/dummymodule.py test/htdocs/tests.py test/test.py

Author: grahamd
Date: Thu Mar 16 20:14:22 2006
New Revision: 386524

URL: http://svn.apache.org/viewcvs?rev=386524&view=rev
Log:
PythonImport directive now uses apache.import_module() to import modules
to avoid issues with modules being loaded multiple times. (MODPYTHON-113)
PythonImport directive now allows function within module to be optionally
specified where function is called after module has been successfully
imported. (MODPYTHON-118)

Added:
    httpd/mod_python/trunk/test/htdocs/dummymodule.py
Modified:
    httpd/mod_python/trunk/Doc/appendixc.tex
    httpd/mod_python/trunk/Doc/modpython5.tex
    httpd/mod_python/trunk/lib/python/mod_python/apache.py
    httpd/mod_python/trunk/src/mod_python.c
    httpd/mod_python/trunk/test/htdocs/tests.py
    httpd/mod_python/trunk/test/test.py

Modified: httpd/mod_python/trunk/Doc/appendixc.tex
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/Doc/appendixc.tex?rev=386524&r1=386523&r2=386524&view=diff
==============================================================================
--- httpd/mod_python/trunk/Doc/appendixc.tex (original)
+++ httpd/mod_python/trunk/Doc/appendixc.tex Thu Mar 16 20:14:22 2006
@@ -59,6 +59,11 @@
       The \samp{apache.interpreter} and \samp{apache.main_server} attributes
       have been made publically available. These were previously private and
       not part of the public API.
+    \item
+      (\citetitle[http://issues.apache.org/jira/browse/MODPYTHON-118]{MODPYTHON-118})
+      Now possible using the \code{PythonImport} directive to specify the name
+      of a function contained in the module to be called once the designated
+      module has been imported.
   \end{itemize}
 
   Improvements
@@ -146,6 +151,11 @@
       shutdown. This was being done though from within the context of a
       signal handler, which is generally unsafe and would cause the process
       to lock up. This function is no longer called on child process shutdown.
+    \item
+      (\citetitle[http://issues.apache.org/jira/browse/MODPYTHON-113]{MODPYTHON-113})
+      The \code{PythonImport} directive now uses the
+      \code{apache.import_module()} function to import modules to avoid
+      reloading problems when same module is imported from a handler.
   \end{itemize}
 
 \chapter{Changes from Version (3.2.7)\label{app-changes-from-3.2.7}}

Modified: httpd/mod_python/trunk/Doc/modpython5.tex
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/Doc/modpython5.tex?rev=386524&r1=386523&r2=386524&view=diff
==============================================================================
--- httpd/mod_python/trunk/Doc/modpython5.tex (original)
+++ httpd/mod_python/trunk/Doc/modpython5.tex Thu Mar 16 20:14:22 2006
@@ -452,13 +452,20 @@
 mod_python.c
 
 Tells the server to import the Python module module at process startup
-under the specified interpreter name. This is useful for
-initialization tasks that could be time consuming and should not be
-done at the request processing time, e.g. initializing a database
-connection.
+under the specified interpreter name. The import takes place at child
+process initialization, so the module will actually be imported once for
+every child process spawned.
 
-The import takes place at child process initialization, so the module
-will actually be imported once for every child process spawned.
+This is useful for initialization tasks that could be time consuming and
+should not be done at the time of processing a request, e.g. initializing a
+database connection. Where such initialization code could fail and cause
+the importing of the module to fail, it should be placed in its own function
+and the alternate syntax used:
+
+\code{PythonImport \emph{module::function} \emph{interpreter_name}}
+
+The named function will be called only after the module has been imported
+successfully. The function will be called with no arguments.
 
 \begin{notice}
   At the time when the import takes place, the configuration is not

Modified: httpd/mod_python/trunk/lib/python/mod_python/apache.py
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/lib/python/mod_python/apache.py?rev=386524&r1=386523&r2=386524&view=diff
==============================================================================
--- httpd/mod_python/trunk/lib/python/mod_python/apache.py (original)
+++ httpd/mod_python/trunk/lib/python/mod_python/apache.py Thu Mar 16 20:14:22 2006
@@ -395,6 +395,22 @@
 
         return OK
 
+    def ImportDispatch(self, name):
+
+        debug = int(main_server.get_config().get("PythonDebug", "0"))
+
+        # split module::function
+        l = name.split('::', 1)
+        module_name = l[0]
+        func_name = None
+        if len(l) != 1:
+            func_name = l[1]
+
+        module = import_module(module_name, log=debug)
+
+        if func_name:
+            getattr(module, func_name)()
+
     def ReportError(self, etype, evalue, etb, req=None, filter=None, srv=None,
                     phase="N/A", hname="N/A", debug=0):
         """

Modified: httpd/mod_python/trunk/src/mod_python.c
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/src/mod_python.c?rev=386524&r1=386523&r2=386524&view=diff
==============================================================================
--- httpd/mod_python/trunk/src/mod_python.c (original)
+++ httpd/mod_python/trunk/src/mod_python.c Thu Mar 16 20:14:22 2006
@@ -2227,6 +2227,7 @@
     hl_entry *hle;
     py_config *conf = ap_get_module_config(s->module_config, &python_module);
     py_global_config *glb;
+    PyObject *resultobject = NULL;
 
     /* accordig Py C Docs we must do this after forking */
 
@@ -2342,15 +2343,26 @@
         }
 
     success:
-        /* now import the specified module */
-        if (! PyImport_ImportModule((char *)module_name)) {
+        /* 
+         * Call into Python to do import.
+         * This is the C equivalent of
+         * >>> resultobject = obCallBack.ImportDispatch(module_name)
+         */
+        resultobject = PyObject_CallMethod(idata->obcallback,
+                                           "ImportDispatch", "s", module_name);
+
+        if (!resultobject) {
             if (PyErr_Occurred()) {
                 PyErr_Print();
                 fflush(stderr); 
             }
             ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
-                         "directive_PythonImport: error importing %s", (!module_name) ? "<null>" : module_name);
+                         "directive_PythonImport: error importing %s",
+                         (!module_name) ? "<null>" : module_name);
         }
+
+        /* clean up */
+        Py_XDECREF(resultobject);
 
         /* release interpreter */
         release_interpreter();

Added: httpd/mod_python/trunk/test/htdocs/dummymodule.py
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/test/htdocs/dummymodule.py?rev=386524&view=auto
==============================================================================
--- httpd/mod_python/trunk/test/htdocs/dummymodule.py (added)
+++ httpd/mod_python/trunk/test/htdocs/dummymodule.py Thu Mar 16 20:14:22 2006
@@ -0,0 +1,7 @@
+from mod_python import apache
+
+apache.log_error("dummymodule / %s" % apache.interpreter)
+
+def function():
+    apache.log_error("dummymodule::function / %s" % apache.interpreter)
+    apache.main_server.get_options()["dummymodule::function"] = "1"

Modified: httpd/mod_python/trunk/test/htdocs/tests.py
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/test/htdocs/tests.py?rev=386524&r1=386523&r2=386524&view=diff
==============================================================================
--- httpd/mod_python/trunk/test/htdocs/tests.py (original)
+++ httpd/mod_python/trunk/test/htdocs/tests.py Thu Mar 16 20:14:22 2006
@@ -886,7 +886,11 @@
 
     import sys
     if sys.modules.has_key("dummymodule"):
-        req.write("test ok")
+        if not apache.main_server.get_options().has_key("dummymodule::function"):
+            req.log_error("dummymodule::function not executed")
+            req.write("test failed")
+        else:
+            req.write("test ok")
     else:
         req.log_error("dummymodule not found in sys.modules")
         req.write("test failed")

Modified: httpd/mod_python/trunk/test/test.py
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/test/test.py?rev=386524&r1=386523&r2=386524&view=diff
==============================================================================
--- httpd/mod_python/trunk/test/test.py (original)
+++ httpd/mod_python/trunk/test/test.py Thu Mar 16 20:14:22 2006
@@ -1519,14 +1519,10 @@
             
     def test_import_conf(self):
 
-        # create a dummy module
-        f = open(os.path.join(DOCUMENT_ROOT, "dummymodule.py"), "w")
-        f.write("# nothing here")
-        f.close()
-
         # configure apache to import it at startup
         c = Container(PythonPath("[r'%s']+sys.path" % DOCUMENT_ROOT),
                       PythonImport("dummymodule test_import"),
+                      PythonImport("dummymodule::function test_import"),
                       VirtualHost("*",
                                   ServerName("test_import"),
                                   DocumentRoot(DOCUMENT_ROOT),