[mod_python] Catalog of mod_python.publisher problems.

Graham Dumpleton grahamd at dscpl.com.au
Tue Jan 25 00:14:42 EST 2005


Jorey Bump wrote ..
> Create 2 modules, in the same directory, named master.py and slave.py:
> 
> master.py:
> 
>   import slave
> 
>   def hello(req):
>       return slave.hello
> 
> slave.py:
> 
>   hello = "Hello, world!"
> 
> Access http://host/master/hello and "Hello, world!" appears in the 
> browser. Now move the files into a subdirectory and access 
> http://host/subdir/master/hello. It throws up an error:
> 
>   ImportError: No module named slave
> 
> What happened? It originally appeared as though a module could import 
> adjacent modules, but this failed in a subdirectory. The reason is that
> the original directory was where the interpreter was defined (with no 
> PythonPath), and so was prepended to the module search path. It doesn't
> matter where master.py is (as long as it accessible by the defined 
> interpreter), but slave.py  must be in sys.path if it is to be imported
> by a published module.
> 
> This falls under the "perceived problem" category, in that it's not a 
> bug, but sure looks like one at first. My own practice for coping with
> this is to set a PythonPath directive, appending a directory outside the
> DocumentRoot from which I can reliably import modules and packages 
> specific to that interpreter or VirtualHost.

As I gave as response to a recent question, this is possibly better solved
by writing:

  import os
  from mod_python import apache
  directory = os.path.dirname(__file__)

  slave = apache.import_module("slave",[directory])
 
  def hello(req):
      return slave.hello

Everyone has their own personal opinions on how best to use mod_python.
As to my own two cents worth, although mod_python uses Python, the
environment which it is running under isn't like running Python from the
command line. One is using it in the context of a web server and what
people tend to expect in doing stuff with web servers is that they can use
the same resource name in different locations of the URL namespace.

Because people are using mod_python/Python specifically to build web
applications, I believe that this expectation about using the same
resource names in multiple places is an overriding factor and any design
should accomodate this practice.

Thus, I would suggest that best practice would be:

1. Only use the "import" statement to import modules which have been
provided with Python, are installed into the "site-packages" directory
or are clearly seperated out into a directory distinct from the document
hierarchy. In this later case PythonPath should be used to denote where
that directory is.

2. That sys.path should not ever include any directory which is a part of
the document hierarchy. Unfortunately the way handlers are setup this
is done by default. This can be avoided though by setting PythonPath
explicity at the same point PythonHandler is defined. If PythonPath isn't
being defined anyway to add in extra external directories containing
application specific modules, then PythonPath should be set to "sys.path"
to ensure the document directory isn't added.

3. Always use apache.import_module() to import relative code files which
are contained within the document hierarchy. Because of (2) above, one
wouldn't be able to rely on sys.path though, so one should calculate the
exact directory that a code files resides in. This can be done by using
__file__ as described above. The directory would then be supplied to the
import module method to ensure that only that directory is searched.

In other words, a clear distinction is drawn. If it is outside the document
hierarchy, then "import" must be used with sys.path defining the search
path. Because "import" is used, modules outside of document hierarchy
must be uniquely named.

Inside the document heirarchy always use import_module() and always
define the exact directory you want something loaded from. Within the
document hierarchy, rather than calling them modules, they should be
seen as code files and duplicates should be allowed in different
directories.

All that now would need to be done is to fix import_module() so that it
copes properly with loading from the document hierarchy code files
with the same name in different directories. This isn't actually that hard
to do, but at the moment we seemed to be bogged down in arguing
about whether it is right or not.

Graham


More information about the Mod_python mailing list