views:

98

answers:

3

I wrote some code that I'd like to package as an egg. This is my directory structure:

src/
src/tests
src/tests/test.py # this has several tests for the movie name parser
src/torrent
src/torrent/__init__.py
src/torrent/movienameparser
src/torrent/movienameparser/__init__.py # this contains the code

I'd like to package this directory structure as an egg, and include the test file too. What should I include in the setup.py file so that I can have any number of namespaces, and any number of tests?

This is the first open source code I'd like to share. Even though, probably, I will be the only one who will find this module useful, I'd like to upload it on pypi. What license can I use that will allow users to do what they want with the code,no limitations upon redistribution,modifications?

Even though I plan on updating this egg, I'd like not to be responsible of anything ( such as providing support to users ). I know this may sound selfish, but this is my first open source code, so please bear with me. Will I need to provide a copy of the license? Where could I find a copy?

Thanks for reading all of this.

+2  A: 

It would be better to distribute it as a tarball (.tar.gz), not as an egg. Eggs are primarily for binary distribution, such as when using compiled C extensions. In source-only distributions, they are just unnecessary complexity.

If you just want to throw your code out into the world, the MIT or 3-clause BSD licenses are the most popular choice. Both include disclaimers of liability. All you have to do is include the main license in the tarball; typically as "License.txt", or similar. Optionally, you can add a small copyright notification to each source file; I encourage this, so the status of each file is obvious even without the entire archive, but some people think that's too verbose. It's a matter of personal preference.

The BSD license is available on Wikipdia, copied below:

Copyright (c) <year>, <copyright holder>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the <organization> nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY <copyright holder> ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
John Millikin
+4  A: 

I won't get into licensing discussion here, but it's typical to include LICENSE file at the root of your package source code, along with other customary things like README, etc.

I usually organize packages the same way they will be installed on the target system. The standard package layout convention is explained here.

For example if my package is 'torrent' and it has a couple sub-packages such as 'tests' and 'util', here's the source tree would look like:

workspace/torrent/setup.py
workspace/torrent/torrent/__init__.py
workspace/torrent/torrent/foo.py
workspace/torrent/torrent/bar.py
workspace/torrent/torrent/...
workspace/torrent/torrent/tests/__init__.py
workspace/torrent/torrent/tests/test.py
workspace/torrent/torrent/tests/...
workspace/torrent/torrent/util/__init__.py
workspace/torrent/torrent/util/helper1.py
workspace/torrent/torrent/util/...

This 'torrent/torrent' bit seems redundant, but this is the side-effect of this standard convention and of how Python imports work.

Here's the very minimalist setup.py (more info on how to write the setup script):

#!/usr/bin/env python

from distutils.core import setup

setup(name='torrent',
      version='0.1',
      description='would be nice',
      packages=['torrent', 'torrent.tests', 'torrent.util']
)
To obtain a source distro, I'd then do:
$ cd workspace/torrent
$ ./setup.py sdist

This distro (dist/torrent-0.1.tar.gz) will be usable on its own, simply by unpacking it and running setup.py install or by using easy_install from setuptools toolkit. And you won't have to make several "eggs" for each supported version of Python.

If you really need an egg, you will need to add a dependency on setuptools to your setup.py, which will introduce an additional subcommand bdist_egg that generates eggs.

But there's another advantage of setuptools besides its egg-producing-qualities, it removes the need to enumerate packages in your setup.py with a nice helper function find_packages:

#!/usr/bin/env python

from setuptools import setup, find_packages

setup(name='torrent',
      version='0.1',
      description='would be nice',
      packages=find_packages()
)
Then, to obtain an "egg", I will do:
$ cd workspace
$ ./setup.py bdist_egg

... and it will give me the egg file: dist/torrent-0.1-py2.6.egg

Notice the py2.6 suffix, this is because on my machine I have Python 2.6. If you want to please lots of people, you'd need to publish an egg for each major Python release. You don't want hordes of Python 2.5 folks with axes and spears at your doorstep, do you?

But you don't have to build an egg, you can still use sdist subcommand.

Updated: here's another useful page in Python documentation that introduces Distutils from user's perspective.

Pavel Repin
+1  A: 

Include ez_setup file from setuptools website and include, at the top of your setup.py:

from ez_setup import use_setuptools
use_setuptools()

This script is an helper for people who doesn't have setuptools. It download and install latest version of setuptools on system that do not have setuptools installed.

ohe