Python – Exception warnings for djcelery, billiard, and django_settings_module

Exception warnings for djcelery, billiard, and django_settings_module… here is a solution to the problem.

Exception warnings for djcelery, billiard, and django_settings_module

When running manage.py celeryd for an async process, everything works as expected, but I get a weird warning every time I start. It doesn’t cause any errors, but I can’t make it go away or understand what it means.

Here it is:

/home/user/lib/python2.7/billiard-2.7.3.15-py2.7-linux 
-x86_64.egg/billiard/forking.py:455:           
UserWarning: Will add directory '/home/user/webapps/django/proj' to path! 
This is  necessary to accommodate pre-Django 1.4 layouts using setup_environ.
You can skip this warning by adding a DJANGO_SETTINGS_MODULE=settings 
environment variable.

W_OLD_DJANGO_LAYOUT % os.path.realpath(project_dir)

This is unusual because the django settings module has been added to my wsgi and it works for everything else. Does it ask me to add settings to httpd.conf or what?

Thanks

Solution

Strangely, I just had the same problem! Looking for the file in question (billiard/forking.py), I found this function:

def _Django_old_layout_hack__save():
    if 'DJANGO_PROJECT_DIR' not in os.environ:
        try:
            settings_name = os.environ['DJANGO_SETTINGS_MODULE']
        except KeyError:
            return  # not using Django.

try:
            project_name, _ = settings_name.split('.', 1)
        except ValueError:
            return  # not modified by setup_environ

project = __import__(project_name)
        try:
            project_dir = os.path.normpath(_module_parent_dir(project))
        except AttributeError:
            return  # dynamically generated module (no __file__)
        warnings.warn(UserWarning(
            W_OLD_DJANGO_LAYOUT % os.path.realpath(project_dir)
        ))
        os.environ['DJANGO_PROJECT_DIR'] = project_dir

This function obviously does some integrity checking on os.environ. Note that after retrieving the DJANGO_SETTINGS_MODULE, it attempts to split the module name with a period. This code seems to assume that if your DJANGO_SETTINGS_MODULE is a top-level module (which it is by default), then your environment has not been modified.

Unfortunately, if it’s not a top-level module, it seems to assume you’re using setup_environ, and it now has to add the project directory to the path.

In my case, I just moved the simple settings.py module into its own settings package, splitting it into generic files and dev/production files. Of course, I had to modify manage.py and wsgi.py to point to the correct settings module. Of course, this starts triggering this warning.

My solution to this problem is to add DJANGO_PROJECT_DIR variables directly in my manage.py. I’m not sure if I need to add it somewhere else (e.g. in production), but that’s all I’m having so far.

This is the relevant line in manage.py:

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.current")

# Add the project directory to the path, to appease billiard
    os.environ.setdefault("DJANGO_PROJECT_DIR",
        os.path.dirname(os.path.realpath(__file__)))

Related Problems and Solutions