[mod_python] python path and 3.3

Graham Dumpleton grahamd at dscpl.com.au
Sat Dec 2 18:16:38 EST 2006


On 02/12/2006, at 8:46 PM, Clodoaldo wrote:

> 2006/12/2, Graham Dumpleton <grahamd at dscpl.com.au>:
>>
>> On 02/12/2006, at 10:57 AM, Clodoaldo wrote:
>>
>> >> Ok, I did it and now this works:
>> >>
>> >> import constants as C
>> >>
>> >> But this does not work:
>> >>
>> >> from mod_python import apache
>> >> C = apache.import_module('constants.py')
>> >>
>> >
>> > Changed it to:
>> >
>> > from mod_python import apache
>> > C = apache.import_module('~/mod/constants.py')
>> >
>> > And it works.
>>
>> The apache.import_module() function is doing double duty in allowing
>> either a module name or a path for a file (including extension).  
>> For a
>> path it has to be able to be distinguishable from a module or module
>> within
>
> I should have tried it. This works:
>
> from mod_python import apache
> C = apache.import_module('constants')

Yes, but if you want to be able to also run your code outside of  
Apache in
a test harness or something, using normal Python 'import' construct  
it still
possibly better. In the context of mod_python, provided the parent was
imported using the mod_python module importer and not handed off to
the standard Python importer, and the child is on the mod_python module
search path and not in sys.path, auto reloading still works okay.  
Thus, if
you change 'constants', the parent and the child will be automatically
reloaded next time the parent is required, even though the parent hadn't
been changed. That is, in the new module importer detects changes to
children and reloads the parent automatically as well. This didn't  
happen
in the old importer.

>> package name. Thus, for a path, can only use:
>>
>>    /some/path/module.py
>>    ~/some/path/module.py
>>    ./some/path/module.py
>>    ../some/path/module.py
>>
>> For anything else it assumes it is a normal module import. For
>> 'constants.py'
>> that thus means it thinks you are wanting to import a submodule
>> called 'py'
>> from a package called 'constants'.
>>
>> There are a few other quirks with the new importer. The first is that
>> when a
>> path is specified, you don't actually need to use a .py extension.
>> This means
>> for example that the mpservlets package which uses a .mps extension
>> could
>> quite easily be rewritten to use the new module importer rather than
>> its own
>> and get all the benefit of the full depth checks on module reloading.
>> In other
>> words:
>>
>>    module = apache.import_module("/some/path/servlet.mps")
>>
>> will work.
>>
>> This may be useful if you don't want to use a .py extension and want
>> to use
>> something else to hide the fact that Python is being used.
>>
>> Another strange characteristic of the new module importer,  
>> although this
>> also actually works in more recent Python versions if using  
>> __import__
>> (),
>> although not perhaps on all platforms, is that one can use a '/' to
>> refer to a
>> module name in a subdirectory somewhere on the module search path.
>>
>> What this means is that if you had used:
>>
>>    PythonOption mod_python.importer.path "['~/']"
>>
>> rather than:
>>
>>    PythonOption mod_python.importer.path "['~/mod']"
>>
>> you could then have said:
>>
>>    apache.import_module('mod/constants')
>>
>> Note that I haven't used a '.py' extension. In some way this is like
>> having a
>> package, but the big difference is that the 'mod' directory doesn't
>> have to be
>> an actual package, ie., no __init__.py file is required.
>>
>> This method can thus be used to create a namespace for modules still,
>> ie.,
>> by using a subdirectory, but since a package isn't being used,  
>> automatic
>> module reloading still works.
>>
>> Since the same works with __import__() for some versions of Python,
>> falling back to using __import__() may be useful if you are trying  
>> to do
>> testing outside of mod_python.
>>
>> Graham
>>
>
> This topic is now a very complete tutorial on the new 3.3 importer. It
> can make a valuable article in the wiki, if properly cleaned.

Far from complete unfortunately. There is a lot of other stuff one  
needs to
know about the module importer as far as how reloading of modules  
occurs.
Unlike the old importer, the new importer doesn't just load modules  
on top
of the old ones. Thus, if you need to preserve some state or cache  
information
across reloads, for example a database connection pool, you need to
provide some hook functions to allow it.

Anyway, will describe that when someone comes across the need unless
I can get some separate documentation completed about it first.

Graham


More information about the Mod_python mailing list