Search code examples
pythondjangonamespacessetuptools

ImportError: Could not import settings 'company.foo.settings' (Is it on sys.path?): No module named foo.settings


I was asked to split a big project into some reusable libraries (packages). So the idea was to do this:

  • company-django-shared
  • company-django-shared-dev
  • company-python-shared
  • company-python-shared-dev

These are installable with setuptools and namespaces:

  • company
  • company.packagename
  • company.packagename.tests
  • company.util
  • etc...

All this works fine. I can start a shell and do any of the import i need. The problem arrives when I now want to use this in a django project. My settings are in:

  • company.foo.settings

At this point, since setuptools installed some packages, when I try to

$ ./manage.py shell

I get the error::

ImportError: Could not import settings 'company.foo.settings' (Is it on sys.path?): No module named foo.settings

I really can't figure out how to use namespace within django apps. If I fire up a shell and do:

import company
company.__path__

The installed paths are found, but not the current directory. What am I missing?

EDIT

I would like to point out that the problem is Python cannot find any package under company because setuptools-installed packages define company as a namespace.

EDIT 2

Django is just unhappy with namespaces. It seems there are no viable solutions.


Solution

  • The only way I found for now is the following:

    • Do not use the namespace_packages parameter in setuptools.setup()

    Instead, explicitly define "namespace" packages with this in the __init__.py file:

    __import__('pkg_resources').declare_namespace(__name__)

    I have not done a lot of testings as to if this will work if I don't install my libraries in the same order, but at least, I am able to import my django settings (and everything else).

    EDIT

    This ended up not being a viable solutions because if librairies are uninstalled and reinstalled, they will delete more than they should, so ending up loosing modules.

    I ended up using namespace_packages in setuptools.setup() and use a different first level "namespace" for the running django project.

    EDIT 2

    Scrap all this, this namespace thing seems to be a good idea, but ended up just being a nightmare with django. So i reverted everything back to non-namespace code. I'm not happy that I have to do this, but that's the price to work with django.