The packages option tells the Distutils to process (build,
distribute, install, etc.) all pure Python modules found in each package
mentioned in the packages list. In order to do this, of
course, there has to be a correspondence between package names and
directories in the filesystem. The default correspondence is the most
obvious one, i.e. package distutils is found in the directory
distutils relative to the distribution root. Thus, when you say
packages = ['foo']
in your setup script, you are promising that
the Distutils will find a file foo/__init__.py (which might
be spelled differently on your system, but you get the idea) relative to
the directory where your setup script lives. (If you break this
promise, the Distutils will issue a warning but process the broken
package anyways.)
If you use a different convention to lay out your source directory, that's no problem: you just have to supply the package_dir option to tell the Distutils about your convention. For example, say you keep all Python source under lib, so that modules in the ``root package'' (i.e., not in any package at all) are right in lib, modules in the foo package are in lib/foo, and so forth. Then you would put
package_dir = {'': 'lib'}
packages = ['foo']
, you are promising that the file
lib/foo/__init__.py exists.
Another possible convention is to put the foo package right in lib, the foo.bar package in lib/bar, etc. This would be written in the setup script as
package_dir = {'foo': 'lib'}
package: dir
entry in the package_dir
dictionary implicitly applies to all packages below package, so
the foo.bar case is automatically handled here. In this
example, having packages = ['foo', 'foo.bar']
tells the Distutils
to look for lib/__init__.py and
lib/bar/__init__.py. (Keep in mind that although
package_dir applies recursively, you must explicitly list all
packages in packages: the Distutils will not recursively
scan your source tree looking for any directory with an
__init__.py file.)