Fixed #2279: distutils.sdist.add_defaults now add files listed in package_data and data_files

This commit is contained in:
Tarek Ziadé 2009-02-16 21:38:01 +00:00
parent a7b0c12152
commit 7dd533963f
6 changed files with 161 additions and 42 deletions

View File

@ -427,6 +427,7 @@ The versions identified by the qualifiers are those that are obsoleted by the
distribution being described. If no qualifiers are given, all versions of the
named module or package are understood to be obsoleted.
.. _distutils-installing-scripts:
Installing Scripts
==================
@ -449,6 +450,12 @@ way. From the PyXML setup script::
scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val']
)
All the scripts will also be added to the ``MANIFEST``
file if no template is provided. See :ref:`manifest`.
.. versionadded:: 2.7
.. _distutils-installing-package-data:
Installing Package Data
=======================
@ -492,6 +499,12 @@ The corresponding call to :func:`setup` might be::
.. versionadded:: 2.4
All the files that match ``package_data`` will be added to the ``MANIFEST``
file if no template is provided. See :ref:`manifest`.
.. versionadded:: 2.7
.. _distutils-additional-files:
Installing Additional Files
===========================
@ -527,6 +540,11 @@ without specifying a target directory, but this is not recommended, and the
files directly in the target directory, an empty string should be given as the
directory.
All the files that match ``data_files`` will be added to the ``MANIFEST``
file if no template is provided. See :ref:`manifest`.
.. versionadded:: 2.7
.. _meta-data:

View File

@ -74,6 +74,7 @@ source distribution:
:meth:`get_source_files` method in :file:`build_clib.py`! **\*\***)
* scripts identified by the :option:`scripts` option
See :ref:`distutils-installing-scripts`.
* anything that looks like a test script: :file:`test/test\*.py` (currently, the
Distutils don't do anything with test scripts except include them in source
@ -83,6 +84,17 @@ source distribution:
* :file:`README.txt` (or :file:`README`), :file:`setup.py` (or whatever you
called your setup script), and :file:`setup.cfg`
* all files that matches the ``package_data`` metadata.
See :ref:`distutils-installing-package-data`.
.. versionadded:: 2.7
* all files that matches the ``data_files`` metadata.
See :ref:`distutils-additional-files`.
.. versionadded:: 2.7
Sometimes this is enough, but usually you will want to specify additional files
to distribute. The typical way to do this is to write a *manifest template*,
called :file:`MANIFEST.in` by default. The manifest template is just a list of

View File

@ -259,6 +259,9 @@ class sdist (Command):
- setup.py
- test/test*.py
- all pure Python modules mentioned in setup script
- all files pointed by package_data (build_py)
- all files defined in data_files.
- all files defined as scripts.
- all C sources listed as part of extensions or C libraries
in the setup script (doesn't catch C headers!)
Warns if (README or README.txt) or setup.py are missing; everything
@ -291,10 +294,27 @@ class sdist (Command):
if files:
self.filelist.extend(files)
if self.distribution.has_pure_modules():
# build_py is used to get:
# - python modules
# - files defined in package_data
build_py = self.get_finalized_command('build_py')
# getting python files
if self.distribution.has_pure_modules():
self.filelist.extend(build_py.get_source_files())
# getting package_data files
# (computed in build_py.data_files by build_py.finalize_options)
for pkg, src_dir, build_dir, filenames in build_py.data_files:
for filename in filenames:
self.filelist.append(os.path.join(src_dir, filename))
# getting distribution.data_files
if self.distribution.has_data_files():
for dirname, filenames in self.distribution.data_files:
for filename in filenames:
self.filelist.append(os.path.join(dirname, filename))
if self.distribution.has_ext_modules():
build_ext = self.get_finalized_command('build_ext')
self.filelist.extend(build_ext.get_source_files())

View File

@ -42,6 +42,19 @@ class TempdirManager(object):
self.tempdirs.append(d)
return d
def write_file(self, path, content):
"""Writes a file in the given path.
path can be a string or a sequence.
"""
if isinstance(path, (list, tuple)):
path = os.path.join(*path)
f = open(path, 'w')
try:
f.write(content)
finally:
f.close()
class DummyCommand:
"""Class to store options for retrieval via set_undefined_options()."""

View File

@ -12,6 +12,7 @@ from distutils.core import Distribution
from distutils.tests.test_config import PyPIRCCommandTestCase
from distutils.errors import DistutilsExecError
from distutils.spawn import find_executable
from distutils.tests import support
SETUP_PY = """
from distutils.core import setup
@ -20,13 +21,20 @@ import somecode
setup(name='fake')
"""
MANIFEST_IN = """
recursive-include somecode *
MANIFEST = """\
README
setup.py
data/data.dt
scripts/script.py
somecode/__init__.py
somecode/doc.dat
somecode/doc.txt
"""
class sdistTestCase(PyPIRCCommandTestCase):
class sdistTestCase(support.LoggingSilencer, PyPIRCCommandTestCase):
def setUp(self):
support.LoggingSilencer.setUp(self)
# PyPIRCCommandTestCase creates a temp dir already
# and put it in self.tmp_dir
PyPIRCCommandTestCase.setUp(self)
@ -34,24 +42,34 @@ class sdistTestCase(PyPIRCCommandTestCase):
self.old_path = os.getcwd()
os.mkdir(join(self.tmp_dir, 'somecode'))
os.mkdir(join(self.tmp_dir, 'dist'))
# creating a MANIFEST, a package, and a README
self._write(join(self.tmp_dir, 'MANIFEST.in'), MANIFEST_IN)
self._write(join(self.tmp_dir, 'README'), 'xxx')
self._write(join(self.tmp_dir, 'somecode', '__init__.py'), '#')
self._write(join(self.tmp_dir, 'setup.py'), SETUP_PY)
# a package, and a README
self.write_file((self.tmp_dir, 'README'), 'xxx')
self.write_file((self.tmp_dir, 'somecode', '__init__.py'), '#')
self.write_file((self.tmp_dir, 'setup.py'), SETUP_PY)
os.chdir(self.tmp_dir)
def tearDown(self):
# back to normal
os.chdir(self.old_path)
PyPIRCCommandTestCase.tearDown(self)
support.LoggingSilencer.tearDown(self)
def _write(self, path, content):
f = open(path, 'w')
try:
f.write(content)
finally:
f.close()
def get_cmd(self, metadata=None):
"""Returns a cmd"""
if metadata is None:
metadata = {'name': 'fake', 'version': '1.0',
'url': 'xxx', 'author': 'xxx',
'author_email': 'xxx'}
dist = Distribution(metadata)
dist.script_name = 'setup.py'
dist.packages = ['somecode']
dist.include_package_data = True
cmd = sdist(dist)
cmd.dist_dir = 'dist'
def _warn(*args):
pass
cmd.warn = _warn
return dist, cmd
def test_prune_file_list(self):
# this test creates a package with some vcs dirs in it
@ -60,33 +78,24 @@ class sdistTestCase(PyPIRCCommandTestCase):
# creating VCS directories with some files in them
os.mkdir(join(self.tmp_dir, 'somecode', '.svn'))
self._write(join(self.tmp_dir, 'somecode', '.svn', 'ok.py'), 'xxx')
self.write_file((self.tmp_dir, 'somecode', '.svn', 'ok.py'), 'xxx')
os.mkdir(join(self.tmp_dir, 'somecode', '.hg'))
self._write(join(self.tmp_dir, 'somecode', '.hg',
self.write_file((self.tmp_dir, 'somecode', '.hg',
'ok'), 'xxx')
os.mkdir(join(self.tmp_dir, 'somecode', '.git'))
self._write(join(self.tmp_dir, 'somecode', '.git',
self.write_file((self.tmp_dir, 'somecode', '.git',
'ok'), 'xxx')
# now building a sdist
dist = Distribution()
dist.script_name = 'setup.py'
dist.metadata.name = 'fake'
dist.metadata.version = '1.0'
dist.metadata.url = 'http://xxx'
dist.metadata.author = dist.metadata.author_email = 'xxx'
dist.packages = ['somecode']
dist.include_package_data = True
cmd = sdist(dist)
cmd.manifest = 'MANIFEST'
cmd.template = 'MANIFEST.in'
cmd.dist_dir = 'dist'
dist, cmd = self.get_cmd()
# zip is available universally
# (tar might not be installed under win32)
cmd.formats = ['zip']
cmd.ensure_finalized()
cmd.run()
# now let's check what we have
@ -111,21 +120,11 @@ class sdistTestCase(PyPIRCCommandTestCase):
return
# now building a sdist
dist = Distribution()
dist.script_name = 'setup.py'
dist.metadata.name = 'fake'
dist.metadata.version = '1.0'
dist.metadata.url = 'http://xxx'
dist.metadata.author = dist.metadata.author_email = 'xxx'
dist.packages = ['somecode']
dist.include_package_data = True
cmd = sdist(dist)
cmd.manifest = 'MANIFEST'
cmd.template = 'MANIFEST.in'
cmd.dist_dir = 'dist'
dist, cmd = self.get_cmd()
# creating a gztar then a tar
cmd.formats = ['gztar', 'tar']
cmd.ensure_finalized()
cmd.run()
# making sure we have two files
@ -140,6 +139,8 @@ class sdistTestCase(PyPIRCCommandTestCase):
# now trying a tar then a gztar
cmd.formats = ['tar', 'gztar']
cmd.ensure_finalized()
cmd.run()
result = os.listdir(dist_folder)
@ -147,6 +148,58 @@ class sdistTestCase(PyPIRCCommandTestCase):
self.assertEquals(result,
['fake-1.0.tar', 'fake-1.0.tar.gz'])
def test_add_defaults(self):
# http://bugs.python.org/issue2279
# add_default should also include
# data_files and package_data
dist, cmd = self.get_cmd()
# filling data_files by pointing files
# in package_data
dist.package_data = {'': ['*.cfg', '*.dat'],
'somecode': ['*.txt']}
self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#')
self.write_file((self.tmp_dir, 'somecode', 'doc.dat'), '#')
# adding some data in data_files
data_dir = join(self.tmp_dir, 'data')
os.mkdir(data_dir)
self.write_file((data_dir, 'data.dt'), '#')
dist.data_files = [('data', ['data.dt'])]
# adding a script
script_dir = join(self.tmp_dir, 'scripts')
os.mkdir(script_dir)
self.write_file((script_dir, 'script.py'), '#')
dist.scripts = [join('scripts', 'script.py')]
cmd.formats = ['zip']
cmd.use_defaults = True
cmd.ensure_finalized()
cmd.run()
# now let's check what we have
dist_folder = join(self.tmp_dir, 'dist')
files = os.listdir(dist_folder)
self.assertEquals(files, ['fake-1.0.zip'])
zip_file = zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip'))
try:
content = zip_file.namelist()
finally:
zip_file.close()
# making sure everything was added
self.assertEquals(len(content), 8)
# checking the MANIFEST
manifest = open(join(self.tmp_dir, 'MANIFEST')).read()
self.assertEquals(manifest, MANIFEST)
def test_suite():
return unittest.makeSuite(sdistTestCase)

View File

@ -159,6 +159,9 @@ Core and Builtins
Library
-------
- Issue #2279: distutils.sdist.add_defaults now add files
from the package_data and the data_files metadata.
- Issue #5257: refactored all tests in distutils, so they use
support.TempdirManager, to avoid writing in the tests directory.