2009/7/20 Graham Dumpleton <[email protected]>: > 2009/7/20 Malcolm <[email protected]>: >> >> Hello, >> >> I am using mod_wsgi 2.3 with Apache 2.2.11 on Ubuntu 9.04. >> >> I seem to be having problems where the code I put in on of my WSGI >> application files, (django.wsgi) is affecting the (sub) interpreters >> of other WSGI applications. >> >> Here is the relevant part of the django.wsgi file: >> ---------- >> ... >> import warnings >> warnings.filterwarnings(action="ignore", >> message="^the sets module is deprecated$", >> category=DeprecationWarning, >> module="MySQLdb", lineno=34) >> >> # Determine the absolute path of the Django project directory that >> contains >> # this >> project. >> ... >> >> # If the Django project directory is not in the Python path, add >> it. >> ... >> >> os.environ['DJANGO_SETTINGS_MODULE'] = DJANGO_PROJ + '.settings' >> >> import django.core.handlers.wsgi >> application = django.core.handlers.wsgi.WSGIHandler() >> ---------- >> >> In the above WSGI application file, I suppress a warning emitted by a >> particular module. I expected this warning to be suppressed only for >> this one WSGI application, but this is not the case. Say I go to / >> site1 where the WSGI application file suppresses the warning, then >> sure enough, there will be no warning in the Apache error log. >> However, if after visiting that WSGI application, I now go to /site2 >> (another WSGI application that doesn't have that warning suppressed), >> the warning does not show up. >> >> Yet, if I restart Apache and visit /site2 first, the warning will >> appear in the log. >> >> I am running mod_wsgi in daemon mode with multiple WSGI applications. >> All the applications are running within the same process group; >> however, I can change this if I need to. I am using the Apache prefork >> MPM, and I have only one virtual host. >> >> I know this problem seems small and insignificant, since it is just >> affecting spam output to the Apache error log. However, it signals a >> larger problem for me: it means that my WSGI applications are somehow >> sharing state, which I don't want. > > The separation between sub interpreters isn't always perfect. If a C > extension module is used in implementing a Python module isn't > implemented correctly so as to separate data for different sub > interpreters properly, you can have issues. > > In this case though, we are talking about a core Python module and for > it I suspect it is operating on the Python core and so all > interpreters within the process and not just the one the module was > used from are affected. A quick look at the code shows: > > try: > from _warnings import (filters, default_action, once_registry, > warn, warn_explicit) > defaultaction = default_action > onceregistry = once_registry > _warnings_defaults = True > except ImportError: > filters = [] > defaultaction = "default" > onceregistry = {} > > So, what it does is try and import 'filters' from C extension module > _warnings. That value is a list and is actually a reference to a > global static C variable. As such, the same list will be imported into > all sub interpreters and changes made in one sub interpreter will > change what happens in other sub interpreters. > > This sharing of data between sub interpreters is actually usually not > a good thing to do and so am surprised to see this. I will have to do > a bit more research on this and post to the Python list asking about > why it is this way since it doesn't provide proper isolation for sub > interpreters. > > BTW, in mod_wsgi 3.0, you can use the WSGIPythonWarnings directive to > control warnings from configuration file. > > WSGIPythonWarnings ignore::DeprecationWarning:: > > This is done when Python first initialised and affects all sub > interpreters. But then, as you have demonstrated, there is no > separation where control of warnings is concerned. > > Anyway, for proper separation, looks like you will need to delegate > each WSGI application to a different daemon process group. > > Thanks for raising this issue as I didn't know about it.
The other thing you may be able to do is: import warnings warnings.filters = list(warnings.filters) warnings.onceregistry = list(warnings.onceregistry) One of my questions on Python list is why this is already being done with 'warnings' module. It is quite possible that C functions directly access the global static version of the list and doing this may short circuit something. Although, that is effectively what the fallback is if _warnings cannot be imported. Graham --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "modwsgi" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/modwsgi?hl=en -~----------~----~----~----~------~----~------~--~---
