Commit d9892301 authored by PJ Eby's avatar PJ Eby

Added the ``exclude_package_data`` keyword to ``setup()``, allowing you

to trim back files included via the ``package_data`` and
``include_package_data`` options.

--HG--
branch : setuptools
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4041693
parent 1b77dd8e
......@@ -55,6 +55,8 @@ setup(
"entry_points = setuptools.dist:check_entry_points",
"test_suite = setuptools.dist:check_test_suite",
"zip_safe = setuptools.dist:assert_bool",
"package_data = setuptools.dist:check_package_data",
"exclude_package_data = setuptools.dist:check_package_data",
"include_package_data = setuptools.dist:assert_bool",
],
"egg_info.writers": [
......@@ -78,8 +80,6 @@ setup(
classifiers = [f.strip() for f in """
Development Status :: 3 - Alpha
Intended Audience :: Developers
......
[distutils.setup_keywords]
entry_points = setuptools.dist:check_entry_points
extras_require = setuptools.dist:check_extras
package_data = setuptools.dist:check_package_data
install_requires = setuptools.dist:check_requirements
include_package_data = setuptools.dist:assert_bool
exclude_package_data = setuptools.dist:check_package_data
namespace_packages = setuptools.dist:check_nsp
test_suite = setuptools.dist:check_test_suite
eager_resources = setuptools.dist:assert_string_list
......
......@@ -289,10 +289,20 @@ unless you need the associated ``setuptools`` feature.
file. For more information, see the section below on `Including Data
Files`_.
``exclude_package_data``
A dictionary mapping package names to lists of glob patterns that should
be *excluded* from your package directories. You can use this to trim back
any excess files included by ``include_package_data``. For a complete
description and examples, see the section below on `Including Data Files`_.
``package_data``
A dictionary mapping package names to lists of glob patterns. For a
complete description and examples, see the section below on `Including
Data Files`_.
Data Files`_. You do not need to use this option if you are using
``include_package_data``, unless you need to add e.g. files that are
generated by your setup script and build process. (And are therefore not
in source control or are files that you don't want to include in your
source distribution.)
``zip_safe``
A boolean (True or False) flag specifying whether the project can be
......@@ -627,7 +637,7 @@ are placed in a platform-specific location. However, the most common use case
for data files distributed with a package is for use *by* the package, usually
by including the data files in the package directory.
Setuptools offers two ways to specify data files to be included in your
Setuptools offers three ways to specify data files to be included in your
packages. First, you can simply use the ``include_package_data`` keyword,
e.g.::
......@@ -643,7 +653,7 @@ specified via the distutils' ``MANIFEST.in`` file.
If you want finer-grained control over what files are included (for example, if
you have documentation files in your package directories and want to exclude
them from installation), then you can use the ``package_data`` keyword instead,
them from installation), then you can also use the ``package_data`` keyword,
e.g.::
from setuptools import setup, find_packages
......@@ -704,6 +714,55 @@ python.org website.)
__ http://docs.python.org/dist/node11.html
Sometimes, the ``include_package_data`` or ``package_data`` options alone
aren't sufficient to precisely define what files you want included. For
example, you may want to include package README files in your revision control
system and source distributions, but exclude them from being installed. So,
setuptools offers an ``exclude_package_data`` option as well, that allows you
to do things like this::
from setuptools import setup, find_packages
setup(
...
packages = find_packages('src'), # include all packages under src
package_dir = {'':'src'}, # tell distutils packages are under src
include_package_data = True, # include everything in source control
# ...but exclude README.txt from all packages
exclude_package_data = { '': ['README.txt'] },
)
The ``exclude_package_data`` option is a dictionary mapping package names to
lists of wildcard patterns, just like the ``package_data`` option. And, just
as with that option, a key of ``''`` will apply the given pattern(s) to all
packages. However, any files that match these patterns will be *excluded*
from installation, even if they were listed in ``package_data`` or were
included as a result of using ``include_package_data``.
In summary, the three options allow you to:
``include_package_data``
Accept all data files and directories matched by ``MANIFEST.in`` or found
in source control.
``package_data``
Specify additional patterns to match files and directories that may or may
not be matched by ``MANIFEST.in`` or found in source control.
``exclude_package_data``
Specify patterns for data files and directories that should *not* be
included when a package is installed, even if they would otherwise have
been included due to the use of the preceding options.
NOTE: Due to the way the distutils build process works, a data file that you
include in your project and then stop including may be "orphaned" in your
project's build directories, requiring you to run ``setup.py clean --all`` to
fully remove them. This may also be important for your users and contributors
if they track intermediate revisions of your project using Subversion; be sure
to let them know when you make changes that remove files from inclusion so they
can run ``setup.py clean --all``.
Accessing Data Files at Runtime
-------------------------------
......@@ -2223,7 +2282,11 @@ Release Notes/Change History
* Added the ``include_package_data`` keyword to ``setup()``, allowing you to
automatically include any package data listed in revision control or
``MANIFEST.in``.
``MANIFEST.in``
* Added the ``exclude_package_data`` keyword to ``setup()``, allowing you to
trim back files included via the ``package_data`` and
``include_package_data`` options.
* Fixed ``--tag-svn-revision`` not working when run from a source
distribution.
......
import os.path, sys
import os.path, sys, fnmatch
from distutils.command.build_py import build_py as _build_py
from distutils.util import convert_path
from glob import glob
......@@ -12,10 +12,10 @@ class build_py(_build_py):
Also, this version of the 'build_py' command allows you to specify both
'py_modules' and 'packages' in the same setup operation.
"""
def finalize_options(self):
_build_py.finalize_options(self)
self.package_data = self.distribution.package_data
self.exclude_package_data = self.distribution.exclude_package_data or {}
if 'data_files' in self.__dict__: del self.__dict__['data_files']
def run(self):
......@@ -68,7 +68,7 @@ class build_py(_build_py):
for pattern in globs:
# Each pattern has to be converted to a platform-specific path
files.extend(glob(os.path.join(src_dir, convert_path(pattern))))
return files
return self.exclude_data_files(package, src_dir, files)
def build_package_data(self):
"""Copy data files into build directory"""
......@@ -155,6 +155,47 @@ class build_py(_build_py):
def initialize_options(self):
self.packages_checked={}
_build_py.initialize_options(self)
def exclude_data_files(self, package, src_dir, files):
"""Filter filenames for package's data files in 'src_dir'"""
globs = (self.exclude_package_data.get('', [])
+ self.exclude_package_data.get(package, []))
bad = []
for pattern in globs:
bad.extend(
fnmatch.filter(
files, os.path.join(src_dir, convert_path(pattern))
)
)
bad = dict.fromkeys(bad)
return [f for f in files if f not in bad]
......
......@@ -103,20 +103,20 @@ def check_test_suite(dist, attr, value):
raise DistutilsSetupError("test_suite must be a string")
def check_package_data(dist, attr, value):
"""Verify that value is a dictionary of package names to glob lists"""
if isinstance(value,dict):
for k,v in value.items():
if not isinstance(k,str): break
try: iter(v)
except TypeError:
break
else:
return
raise DistutilsSetupError(
attr+" must be a dictionary mapping package names to lists of "
"wildcard patterns"
)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment