[Python-checkins] r69692 - in python/trunk: Doc/distutils/setupscript.rst Doc/distutils/sourcedist.rst Lib/distutils/command/sdist.py Lib/distutils/tests/support.py Lib/distutils/tests/test_sdist.py Misc/NEWS

tarek.ziade python-checkins at python.org
Mon Feb 16 22:38:01 CET 2009


Author: tarek.ziade
Date: Mon Feb 16 22:38:01 2009
New Revision: 69692

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

Modified:
   python/trunk/Doc/distutils/setupscript.rst
   python/trunk/Doc/distutils/sourcedist.rst
   python/trunk/Lib/distutils/command/sdist.py
   python/trunk/Lib/distutils/tests/support.py
   python/trunk/Lib/distutils/tests/test_sdist.py
   python/trunk/Misc/NEWS

Modified: python/trunk/Doc/distutils/setupscript.rst
==============================================================================
--- python/trunk/Doc/distutils/setupscript.rst	(original)
+++ python/trunk/Doc/distutils/setupscript.rst	Mon Feb 16 22:38:01 2009
@@ -427,6 +427,7 @@
 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 @@
          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 @@
 
 .. 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 @@
 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:
 

Modified: python/trunk/Doc/distutils/sourcedist.rst
==============================================================================
--- python/trunk/Doc/distutils/sourcedist.rst	(original)
+++ python/trunk/Doc/distutils/sourcedist.rst	Mon Feb 16 22:38:01 2009
@@ -74,6 +74,7 @@
   :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 @@
 * :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

Modified: python/trunk/Lib/distutils/command/sdist.py
==============================================================================
--- python/trunk/Lib/distutils/command/sdist.py	(original)
+++ python/trunk/Lib/distutils/command/sdist.py	Mon Feb 16 22:38:01 2009
@@ -259,6 +259,9 @@
           - 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 @@
             if files:
                 self.filelist.extend(files)
 
+        # 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():
-            build_py = self.get_finalized_command('build_py')
             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())

Modified: python/trunk/Lib/distutils/tests/support.py
==============================================================================
--- python/trunk/Lib/distutils/tests/support.py	(original)
+++ python/trunk/Lib/distutils/tests/support.py	Mon Feb 16 22:38:01 2009
@@ -42,6 +42,19 @@
         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()."""

Modified: python/trunk/Lib/distutils/tests/test_sdist.py
==============================================================================
--- python/trunk/Lib/distutils/tests/test_sdist.py	(original)
+++ python/trunk/Lib/distutils/tests/test_sdist.py	Mon Feb 16 22:38:01 2009
@@ -12,6 +12,7 @@
 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 @@
 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 @@
         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 @@
 
         # 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 @@
             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 @@
 
         # 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 @@
         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)
 

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Mon Feb 16 22:38:01 2009
@@ -159,6 +159,9 @@
 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.
 


More information about the Python-checkins mailing list