views:

455

answers:

4

I'm trying to build a Python distribution with distutils. Unfortunately, my directory structure looks like this:

/code
    /mypackage
        __init__.py
        file1.py
        file2.py
        /subpackage
            __init__.py
    /build
        setup.py

Here's my setup.py file:

from distutils.core import setup

setup(
    name = 'MyPackage',
    description = 'This is my package',
    packages = ['mypackage', 'mypackage.subpackage'], 
    package_dir = { 'mypackage' : '../mypackage' }, 
    version = '1',
    url = 'http://www.mypackage.org/',
    author = 'Me',
    author_email = '[email protected]',
)

When I run python setup.py sdist it correctly generates the manifest file, but doesn't include my source files in the distribution. Apparently, it creates a directory to contain the source files (i.e. mypackage1) then copies each of the source files to mypackage1/../mypackage which puts them outside of the distribution.

How can I correct this, without forcing my directory structure to conform to what distutils expects?

A: 

A sorta lame workaround but I'd probably just use a Makefile that rsynced ./mypackage to ./build/mypackage and then use the usual distutils syntax from inside ./build. Fact is, distutils expects to unpack setup.py into the root of the sdist and have code under there, so you're going to have a devil of time convincing it to do otherwise.

You can always nuke the copy when you make clean so you don't have to mess up your vcs.

easel
+2  A: 

What directory structure do you want inside of the distribution archive file? The same as your existing structure?

You could package everything one directory higher (code in your example) with this modified setup.py:

from distutils.core import setup

setup(
    name = 'MyPackage',
    description = 'This is my package',
    packages = ['mypackage', 'mypackage.subpackage'], 
    version = '1',
    url = 'http://www.mypackage.org/',
    author = 'Me',
    author_email = '[email protected]',
    script_name = './build/setup.py',
    data_files = ['./build/setup.py']
)

You'd run this (in the code directory):

python build/setup.py sdist

Or, if you want to keep dist inside of build:

python build/setup.py sdist --dist-dir build/dist

I like the directory structure you're trying for. I've never thought setup.py was special enough to warrant being in the root code folder. But like it or not, I think that's where users of your distribution will expect it to be. So it's no surprise that you have to trick distutils to do something else. The data_files parameter is a hack to get your setup.py into the distribution in the same place you've located it.

Jon-Eric
I don't much care what the structure in the distribution file looks like, as long as it does the right thing when users try and install it using easy_install. But the Python documentation is absolutely horrible when it comes to these details--I have no idea what the structure is even supposed to look like. And I'm still wrapping my head around the idea that you run a script in the distribution before it's installed in order to install the distribution.
Chris B.
A: 

Have it change to the parent directory first, perhaps?

import os
os.chdir(os.pardir)

from distutils.core import setup

etc.

Or if you might be running it from anywhere (this is overkill, but...):

import os.path
my_path = os.path.abspath(__file__)
os.chdir(os.normpath(os.path.join(my_path, os.pardir)))

etc. Not sure this works, but should be easy to try.

Ken Arnold
A: 

Run setup.py from the root folder of the project

In your case, place setup.py in code/

code/ should also include:

  • LICENSE.txt
  • README.txt
  • INSTALL.txt
  • TODO.txt
  • CHANGELOG.txt

The when you run "setup.py sdist' it should auto-gen a MANIFEST including: - any files specified in py_modules and/or packages - setup.py - README.txt

To add more files just hand-edit the MANIFEST file to include whatever other files your project needs.

For a somewhat decent explanation of this read this.

To see a working example checkout my project.

Note: I don't put the MANIFEST under version control so you won't find it there.

Evan Plaice