22

I know you can exclude certain packages using:

packages = find_packages("src", exclude=["test"]),

Is it also possible to exclude single python files? I am building a binary wheel and want to exclude certain source files which I "cythonized" with a custom function:

python cythonize bdist_wheel

At the moment I remove all python files which also have a .so library file after building the wheel with a custom script and I would like to do that with setup.py.

sroecker
  • 500
  • 1
  • 5
  • 11
  • There seems to be a bug-report on this, still open (Sept-2015): https://bitbucket.org/pypa/wheel/issues/99/cannot-exclude-directory – ankostis Sep 09 '15 at 14:19

3 Answers3

27

There is a vague (IMO) article in py-docs "How to include/exclude files to the package". In two words: use combination of find_packages and MANIFEST.in

To check, what is in the package locally (before sending to PyPI), run python setup.py sdist, and then check the content of ./dist folder (there should be tarball with your package).

My use-cases

Ignore one file

Add MANIFEST.in to the root of your package, and add these lines:

exclude .travis.yml
exclude appveyor.yml
exclude data/private/file.env

This files won't be included into distribution package.

Tests near sources

If in your project test files are placed near the code (in other words, there is no separated directory tests), something like this:

package1
├── src
│   ├── __init__.py
│   ├── __init__test.py
│   ├── mymod.py
│   ├── mymod_test.py
│   ├── typeconv.py
│   └── typeconv_test.py
│
├── LICENSE
└── README.rst

You could add this lines to your MANIFEST.in, and setuptools will ignore test files:

global-exclude *_test.py

See also

maxkoryukov
  • 4,205
  • 5
  • 33
  • 54
  • 7
    `MANIFEST.in` works for source distributions, but it's ignored for wheels, which is what OP is asking about. See https://github.com/pypa/setuptools/issues/511. – paulmelnikow Jan 17 '20 at 21:57
4

You can use setuptools.find_packages() along with a revision-control plugin i.e. setuptools-git.

Here is some extracts from a setup.py projects setup to exclude the tests directory:

from setuptools import setup, find_packages

setup(
    name=...
    ...
    packages=find_packages(exclude=["tests"]),
    setup_requires=[
        'setuptools',
        'setuptools-git',
        'wheel',
    ]

Other plugins like the one used above are available for bzr, darcs, monotone, mercurial, etc.

Tip:

Don't forget to clean your build directory by running: python setup.py clean --all bdist_wheel

Charlie Clark
  • 18,477
  • 4
  • 49
  • 55
ankostis
  • 8,579
  • 3
  • 47
  • 61
  • 6
    But the original question was `Is it possible to exclude single python files?` and you are talking about excluding a directory. – Palasaty Feb 17 '17 at 17:45
  • @Palasaty, could you add similar criticism to my answer))) https://stackoverflow.com/a/45847842/1115187 – maxkoryukov Aug 23 '17 at 19:30
  • python setup.py clean --all – jmcgrath207 Jan 31 '18 at 07:45
  • 1
    It's **so** infuriating that bdist_wheel behaves differently to sdist! This has prevented me from releasing wheels for my pure Python library because bdist_wheel would **always** include stuff that I'd manage to exclude from the sdist. – Charlie Clark May 06 '20 at 14:24
  • @CharlieClark what do you mean here? – ankostis May 10 '20 at 17:04
  • If you use sdist, you can guarantee that the resulting package only contains what you've specified in setup and in the manifest. This is not necessarily the case with bdist_wheel. – Charlie Clark May 11 '20 at 09:03
4

You can also use exclude_package_data keyword from setup() function if you use include_package_data=True.

from setuptools import setup

setup(
    name=...,
    ...,
    include_package_data=True,
    exclude_package_data={
        '': 'file_to_exclude_from_any_pkg.c',
        'pkg_name': 'file_to_exclude_from_pkg_name.c',
        ...
    }
)
foreignmeloman
  • 109
  • 2
  • 4