setuptools troubles -- excluding packages, including data files

0x4B1D picture 0x4B1D · Dec 19, 2011 · Viewed 11.6k times · Source

I'm fairly new to setuptools. I've seen a few similar questions and it drives a little bit insane that I've seemed to follow advice I saw but setuptools still does something different than what I want.

Here is the structure of my project:

.
..
package1/
    __init__.py
    abc.py
    ...
tests/
    __init__.py
    test_package1.py
LICENSE
README.md
RELEASE
setup.py

And here is the contents of my setup.py:

#!/usr/bin/env python
import os
#from distutils.core import setup
from setuptools import setup, find_packages

setup(
    name='package1',
    version='1.1',
    test_suite="tests",
    packages=find_packages(exclude=['tests']),    
    include_package_data=True,
    package_data = {
        '': ['LICENSE', 'README.md5', 'RELEASE']
    },   
)

Also, in my manifest file I have:

include LICENSE
include RELEASE
include README.md

I build the tar with:

python setup.py sdist

I want to:

  1. Exclude tests directory from the source distribution;
  2. Have LICENSE, README.md, RELEASE files in the site-packages directory, either at the top level, or inside the package1 directory (at this point I will agree to either).

Instead, here's what happens:

  1. tests directory remains to be in the created tar archive and gets installed to the site-packages;
  2. Files are copied to the archive, but do not get installed to the site-packaged directory of the package.

I am out of ideas, can someone explain to me what I am doing wrong and how to fix it?

Answer

oby1 picture oby1 · Oct 9, 2014

find_packages uses fnmatchcase for its exclude filtering. You can test if your exclusion pattern matches a package name as follows:

>>> from fnmatch import fnmatchcase
>>> fnmatchcase('my.package.name.tests', 'tests')
False

Assuming all the tests in your project live in package names ending in tests or subpackages of those packages, the following should suffice to exclude all the test code:

setup(
    name='package1',
    version='1.1',
    packages=find_packages(exclude=['tests', '*.tests', '*.tests.*']),    
)

To also exclude the tests folder from source distributions, add the following to MANIFEST.in:

recursive-exclude tests *