I'm restructuring the python libraries our company is developing into various groups. To avoid polluting the top level module namespace I'd like to group everything under a top level 'companyname' package, so we'll have 'coname.utils', 'coname.qa', 'coname.api', and so on. Several of these are expected to be distributed with our product, or publicly installable. 'qa' will be purely internal.
Google does something similar. E.g., the protobuf library is available as "google.protobuf" in the module path. However, it's not particularly clean: the .pth file installed by the protobuf package looks like this:
import sys, types, os;p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('google',));ie = os.path.exists(os.path.join(p,'__init__.py'));m = not ie and sys.modules.setdefault('google', types.ModuleType('google'));mp = (m or []) and m.__dict__.setdefault('__path__',[]);(p not in mp) and mp.append(p)
I think it does that to fool the import engine because there's no __init__.py in the "google" directory. But... not elegant.
Is there a well established way of achieving this? I don't mind making any of the "coname-*" packages require a "coname-top" package just to get the __init__.py in there. I'm as-yet unsure how to convince setuptools to treat the package as not at the top of the module tree, nor if it's possible to create sub-packages from one tree.
To clarify, I'm specifically asking how to set up the above so that coname-qa can be distributed and installed separately from coname-api, for example. It is reasonable that both would depend on coname-tools.
The directory a needs to be a package. Add an
__init__.pyfile to make it a package, which is a step up from being a simple directory.The directory b also needs to be a subpackage of a. Add an
__init__.pyfile.The directory test should probably also be a package. Hard to say if this is necessary or not. It's usually a good idea for every directory of Python modules to be a formal package.
In order to import, the package needs to be on sys.path; this is built from the PYTHONPATH environment variable. By default the installed site-packages and the current working directory are (effectively) the only two places where a package can be found.
That means that a must either be installed, or, your current working directory must also be a package one level above a.
OR, you need to set your PYTHONPATH environment variable to include a.