4

I am having an issue with python namespaced packages and am wondering what is a good solution.

My project structure is similar to the following

project_name/ext/app_ext

That is the project I'm working on. It has dependencies that are also in the same namespace.

project_name/ext/base_ext
project_name/ext/other_dependency

I am working on the "app_ext" namespaced package in a django application. However, I am running into issues receiving a no module named app_ext.

I think it has to do with how the dependency namespaced packages are installed (I'm installing with PIP). The dependency namespaced packages aren't installed with the __init__.py files as is documented in the distribute / setuptools documentation, but all truly contain the following declarations in their installation packages.

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

Now to the real question. Is there a trick to working with a namespaced package when there is already some related namespaced packages installed?

shuttle87
  • 15,466
  • 11
  • 77
  • 106
Aaron
  • 4,206
  • 3
  • 24
  • 28
  • Couldn't you just include empty `__init__.py` files in the package directories? – JAB Jun 28 '12 at 17:27
  • @JAB are you suggesting he manually add `__init__.py` files in the project_name and ext virtual package directories in site-packages? – Matthew J Morrison Jun 28 '12 at 17:50
  • If the issue is the packages not being recognized as such, then that should work, right? As `__init__.py` doesn't actually have to contain anything to do its job as an indicator that the directory containing it is a package. Or perhaps there is something I'm missing here, considering the usage of the term "namespaced packages" when packages are essentially namespaces to begin with. Does PIP do some magic that would prevent addition of a file amongst the other files in the installed packages? – JAB Jun 28 '12 at 19:23
  • yes, that does work as a workaround if you include the "from pkgutil..." stuff. However, that's not a very elegant solution and not fun to have to do every time we create a new virtual environment. – Aaron Jun 28 '12 at 20:42
  • @JAB "namespaced packages" are special http://packages.python.org/distribute/setuptools.html#namespace-packages (note that: `__init__.py files will not be installed`) – Matthew J Morrison Jun 29 '12 at 03:29
  • @MatthewJMorrison Oh, interesting, so when working with them at first, the `__init__.py` files wouldn't actually be empty, they'd need `__import__('pkg_resources').declare_namespace(__name__)` in them (and can't have anything else in them because of the fact you mention). – JAB Jun 29 '12 at 12:36

1 Answers1

0

One solution is to modify the path of the namespaced package to add your local path. (if you are working in Django, you could add a snippet like the following to your settings.py).

from os import path
import sys

PACKAGE_NAMESPACE = ["project_name", "ext"]
VIRTUAL_PACKAGE = '.'.join(PACKAGE_NAMESPACE)
__import__(VIRTUAL_PACKAGE)
local_package = path.abspath(path.join(*PACKAGE_NAMESPACE))
sys.modules[VIRTUAL_PACKAGE].__dict__["__path__"].insert(0, local_package)

This approach is also used in the tiddlyweb project for the tiddlywebplugins namespace.

Matthew J Morrison
  • 4,343
  • 3
  • 28
  • 45
  • that feels quite odd, but seems to work and isn't a very intrusive change. Thanks for your help. – Aaron Jul 01 '12 at 11:04