2009/7/20 Graham Dumpleton <[email protected]>: > 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)
Whoops. warnings.onceregistry = dict(warnings.onceregistry) Graham > 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 -~----------~----~----~----~------~----~------~--~---
