[mod_python] Subinterpreters and index.py

Jorey Bump list at joreybump.com
Thu Jul 1 13:23:35 EDT 2004


Nicolas Lehuen wrote:

> Hi,
>  
> I'm encoutering an unexpected behaviours while using the publisher handlers
> and two index.py, one in /app/index.py and one in /app/subdir/index.py.
>  
> When I first call http://localhost/app/, /app/index.py is called. Then if I
> call http://localhost/app/subdir/, /app/subdir/index.py is called allright,
> but then if I try again http://localhost/app/, I always get
> /app/subdir/index.py !

Modules are namespaces, regardless of their physical location. This is 
very important, even within subinterpreters.

> Maybe it would be possible to overcome this limitation if mod_python named
> and loaded the page modules according to their path relative to the place
> where a PythonInterpreter or PythonHandler (when PythonInterpPerDirective is
> On) was last defined. So, if I define "PythonInterpreter myapp" in /app,
> /app/index.py would be loaded as the 'index' module and /app/subdir/index.py
> would be loaded as the 'subdir.index' module.

[snip]

> Likewise, maybe such an improved behaviour could enable us to do something
> which is AFAIK quite difficult right now : importing modules relative to the
> current interpreter (maybe by automatically adding the directory where the
> interpreter was defined to sys.path). Say I've got a utility module
> /app/utils.py, I could use it in /app/index.py and /app/subdir/index.py by
> importing 'utils'.

mod_python already puts the directory at the front of the sys.path. You 
can determine this by creating a module:

app/test.py:

  import sys
  def syspath(req):
     return sys.path

Then access it at:

  http://localhost/app/test.py/syspath

You can test the import by creating two more files:

test1.py:

  import sys
  import test2

  def syspath1(req):
      return sys.path

  def syspath2(req):
      return test2.syspath2(req)

test2.py:

  import sys

  def syspath2(req):
      return sys.path

Access the results at these locations:

  http://localhost/app/test1.py/syspath1
  http://localhost/app/test1.py/syspath2

You can see that the import worked fine. To use subdirectories, you need 
to turn them into packages. This is extremely simple:

Create the subdirectory:

  app/dir1/

Create a package initialization file (it can be empty):

  app/dir1/__init__.py

Create a module in this directory:

app/dir1/test3.py:

  import sys

  def syspath3(req):
      return sys.path

Modify app/test1.py:

  import sys
  import test2
  import dir1.test3

  def syspath1(req):
      return sys.path

  def syspath2(req):
      return test2.syspath2(req)

  def syspath3(req):
      return dir1.test3.syspath3(req)

Try it out:

  http://localhost/app/test1.py/syspath3

This is exactly the behaviour you want, and requires no special 
directives. It's pure python, and it's beautiful.

mod_python embeds a python interpreter, pure and simple. It's best to 
use the basic features of python to overcome problems such as this. 
Forget that mod_python even exists (but be happy that it does!).



More information about the Mod_python mailing list