Graham Dumpleton
grahamd at dscpl.com.au
Wed May 10 19:31:00 EDT 2006
Dan Eloff wrote .. > > from mod_python import apache > > __info__.path.extend(eval(apache.main_server.get_options().get > > ('my_import_path','[]'))) > > > > I like that, but I agree __info__.path is not ideal. > > ... > > > By a module explicitly adding items to the embedded search path, it > > would be > > more predictable perhaps than blindly always using what the option > > may be set > > to, as by adding the code in you are making a conscious decision that > > you want > > it to work that way. You need not even use an option to obtain what > > the path > > should be set to, you could also use hard coded paths, or a path > > determined by > > taking a relative path and adding it to the dirname of the __file__ > > attribute of the > > module. > > Not ideal for me, since I would simply add this to the top of every > single python file. But I can live with that because it does solve all > the issues related to a global setting. All in all a pretty good > solution. Depending on how your modules are structured, it may not be quite as bad as having to add it to every file. At least not the look up of what path to use. This is because what you may be able to do is use the fact that if you supply an absolute or relative path to apache.import_module(), that the "path" argument, rather than being a search path, becomes the path which is encoded into the module as '__info__.path'. Thus, if a top level entry point module were used, much like a package root, and although there were various sub modules that any methods were exposed through the top level module, you could do something like: # toplevel.py from mod_python import apache __info__.path.extend(eval(apache.main_server.get_options().get('my_import_path','[]'))) submodule_1 = apache.import_module('./submodule_1.py', path=__info__.path) submodule_2 = apache.import_module('./subdir_2/toplevel.py', path=__info__.path) Thus, those submodules now don't need to set '__info__.path', as they will inherit that from the top level module. This may turn out to be messy or not useful as is as well. Overall, I guess what we need to come up with is some example use cases where search paths are required and perhaps work from that as to what is a good interface for supporting it. At the moment, my impression is that the common use case is in order to access some configuration module in a central location. Can you describe again your use case? One other issue that may come into play in this is that besides being able to access 'apache.main_server.get_options()', that is, the main server options, there is no way at global scope within a module to access the options related to the request, or virtual host that the module is being imported into. There was a similar issue in respect of the mod_python config settings for PythonDebug and PythonAutoReload when it came to the importer itself. To get around this the importer uses new top level dispatch functions to cache the appropriate configuration available so it is available no matter where apache.import_module() is used. At the moment this cached config isn't accessible through the 'apache' module but is available as 'mod_python.importer.get_config()'. If a module import is occurring do to PythonImport and you call that function, you will get the 'apache.main_server.get_config()' object. If the module import is occurring within the context of a request, the function will return 'req.get_config()'. Thus the 'apache.import_module()' function uses this to get the PythonDebug and PythonAutoReload settings so that they don't have to be explicitly passed to the function itself, thus avoiding some of the problems described in my issues list. I guess the question in respect of user options, is whether there should be some means getting the appropriate options object from global scope in a module. Thus, something like: from mod_python import apache __info__.path.extend(eval(apache.get_options().get('my_import_path','[]'))) Where like with the config, if it is PythonImport, it returns the main server options and if in context of a request, the request options. The only problem with this is that you get back to unpredictable behaviour if a module might be imported from different places where the option set is different. That option set which is used first takes precedence. The issue is whether we want to protect people from doing stupid things by not allowing it, or give them a loaded gun and let them kill themselves if they want to. :-) Note, in Vampire, it actually for the time that a module is being imported exposes a variable '__req__' as global data within the module so that either the config, options or anything else for that matter about the request can be accessed. When I modified the Vampire importer for use in mod_python though, I didn't carry across that feature as was unsure about how wise it was providing it. Sorry, I know this should be on the developer list. Maybe we should look at bumping it over there. Dan are you on the developer list? Graham
|