Imagine that you want to develop a non-trivial end-user desktop (not web) application in Python. What is the best way to structure the project's folder hierarchy?
Desirable features are ease of maintenance, IDE-friendliness, suitability for source control branching/merging, and easy generation of install packages.
In particular:
- Where do you put the source?
- Where do you put application startup scripts?
- Where do you put the IDE project cruft?
- Where do you put the unit/acceptance tests?
- Where do you put non-Python data such as config files?
- Where do you put non-Python sources such as C++ for pyd/so binary extension modules?
Check out Open Sourcing a Python Project the Right Way.
Let me excerpt the project layout part of that excellent article:
Doesn't too much matter. Whatever makes you happy will work. There aren't a lot of silly rules because Python projects can be simple.
/scripts
or/bin
for that kind of command-line interface stuff/tests
for your tests/lib
for your C-language libraries/doc
for most documentation/apidoc
for the Epydoc-generated API docs.And the top-level directory can contain README's, Config's and whatnot.
The hard choice is whether or not to use a
/src
tree. Python doesn't have a distinction between/src
,/lib
, and/bin
like Java or C has.Since a top-level
/src
directory is seen by some as meaningless, your top-level directory can be the top-level architecture of your application./foo
/bar
/baz
I recommend putting all of this under the "name-of-my-product" directory. So, if you're writing an application named
quux
, the directory that contains all this stuff is named/quux
.Another project's
PYTHONPATH
, then, can include/path/to/quux/foo
to reuse theQUUX.foo
module.In my case, since I use Komodo Edit, my IDE cuft is a single .KPF file. I actually put that in the top-level
/quux
directory, and omit adding it to SVN.This blog post by Jean-Paul Calderone is commonly given as an answer in #python on Freenode.
According to Jean-Paul Calderone's Filesystem structure of a Python project:
Try starting the project using the python_boilerplate template. It largely follows the best practices (e.g. those here), but is better suited in case you find yourself willing to split your project into more than one egg at some point (and believe me, with anything but the simplest projects, you will. One common situation is where you have to use a locally-modified version of someone else's library).
Where do you put the source?
PROJECT_ROOT/src/<egg_name>
.Where do you put application startup scripts?
entry_point
in one of the eggs.Where do you put the IDE project cruft?
PROJECT_ROOT/.<something>
in the root of the project, and this is fine.Where do you put the unit/acceptance tests?
PROJECT_ROOT/src/<egg_name>/tests
directory. I personally prefer to usepy.test
to run them.Where do you put non-Python data such as config files?
pkg_resources
package.PROJECT_ROOT/config
. For deployment there can be various options. On Windows one can use%APP_DATA%/<app-name>/config
, on Linux,/etc/<app-name>
or/opt/<app-name>/config
.PROJECT_ROOT/var
during development, and under/var
during Linux deployment.PROJECT_ROOT/src/<egg_name>/native
Documentation would typically go into
PROJECT_ROOT/doc
orPROJECT_ROOT/src/<egg_name>/doc
(this depends on whether you regard some of the eggs to be a separate large projects). Some additional configuration will be in files likePROJECT_ROOT/buildout.cfg
andPROJECT_ROOT/setup.cfg
.Non-python data is best bundled inside your Python modules using the
package_data
support in setuptools. One thing I strongly recommend is using namespace packages to create shared namespaces which multiple projects can use -- much like the Java convention of putting packages incom.yourcompany.yourproject
(and being able to have a sharedcom.yourcompany.utils
namespace).Re branching and merging, if you use a good enough source control system it will handle merges even through renames; Bazaar is particularly good at this.
Contrary to some other answers here, I'm +1 on having a
src
directory top-level (withdoc
andtest
directories alongside). Specific conventions for documentation directory trees will vary depending on what you're using; Sphinx, for instance, has its own conventions which its quickstart tool supports.Please, please leverage setuptools and pkg_resources; this makes it much easier for other projects to rely on specific versions of your code (and for multiple versions to be simultaneously installed with different non-code files, if you're using
package_data
).