diff --git a/Lib/distutils/command/sdist.py b/Lib/distutils/command/sdist.py index 535b8d2aea4..a366d1eaf65 100644 --- a/Lib/distutils/command/sdist.py +++ b/Lib/distutils/command/sdist.py @@ -57,8 +57,7 @@ class sdist (Command): "just regenerate the manifest and then stop " "(implies --force-manifest)"), ('force-manifest', 'f', - "forcibly regenerate the manifest and carry on as usual. " - "Deprecated: now the manifest is always regenerated."), + "forcibly regenerate the manifest and carry on as usual"), ('formats=', None, "formats for source distribution (comma-separated list)"), ('keep-temp', 'k', @@ -191,34 +190,67 @@ class sdist (Command): distribution, and put it in 'self.filelist'. This might involve reading the manifest template (and writing the manifest), or just reading the manifest, or just using the default file set -- it all - depends on the user's options. + depends on the user's options and the state of the filesystem. """ - # new behavior: - # the file list is recalculated everytime because - # even if MANIFEST.in or setup.py are not changed - # the user might have added some files in the tree that - # need to be included. - # - # This makes --force the default and only behavior. + + # If we have a manifest template, see if it's newer than the + # manifest; if so, we'll regenerate the manifest. template_exists = os.path.isfile(self.template) - if not template_exists: - self.warn(("manifest template '%s' does not exist " + - "(using default file list)") % - self.template) - self.filelist.findall() - - if self.use_defaults: - self.add_defaults() - if template_exists: - self.read_template() + template_newer = dep_util.newer(self.template, self.manifest) - if self.prune: - self.prune_file_list() + # The contents of the manifest file almost certainly depend on the + # setup script as well as the manifest template -- so if the setup + # script is newer than the manifest, we'll regenerate the manifest + # from the template. (Well, not quite: if we already have a + # manifest, but there's no template -- which will happen if the + # developer elects to generate a manifest some other way -- then we + # can't regenerate the manifest, so we don't.) + self.debug_print("checking if %s newer than %s" % + (self.distribution.script_name, self.manifest)) + setup_newer = dep_util.newer(self.distribution.script_name, + self.manifest) - self.filelist.sort() - self.filelist.remove_duplicates() - self.write_manifest() + # cases: + # 1) no manifest, template exists: generate manifest + # (covered by 2a: no manifest == template newer) + # 2) manifest & template exist: + # 2a) template or setup script newer than manifest: + # regenerate manifest + # 2b) manifest newer than both: + # do nothing (unless --force or --manifest-only) + # 3) manifest exists, no template: + # do nothing (unless --force or --manifest-only) + # 4) no manifest, no template: generate w/ warning ("defaults only") + + manifest_outofdate = (template_exists and + (template_newer or setup_newer)) + force_regen = self.force_manifest or self.manifest_only + manifest_exists = os.path.isfile(self.manifest) + neither_exists = (not template_exists and not manifest_exists) + + # Regenerate the manifest if necessary (or if explicitly told to) + if manifest_outofdate or neither_exists or force_regen: + if not template_exists: + self.warn(("manifest template '%s' does not exist " + + "(using default file list)") % + self.template) + self.filelist.findall() + + if self.use_defaults: + self.add_defaults() + if template_exists: + self.read_template() + if self.prune: + self.prune_file_list() + + self.filelist.sort() + self.filelist.remove_duplicates() + self.write_manifest() + + # Don't regenerate the manifest, just read it in. + else: + self.read_manifest() # get_file_list () diff --git a/Lib/distutils/tests/test_sdist.py b/Lib/distutils/tests/test_sdist.py index 6b8784ac3dc..e322c1385c6 100644 --- a/Lib/distutils/tests/test_sdist.py +++ b/Lib/distutils/tests/test_sdist.py @@ -29,7 +29,6 @@ class sdistTestCase(PyPIRCCommandTestCase): super(sdistTestCase, self).setUp() self.old_path = os.getcwd() self.temp_pkg = os.path.join(self.mkdtemp(), 'temppkg') - self.tmp_dir = self.mkdtemp() def tearDown(self): os.chdir(self.old_path) @@ -152,67 +151,6 @@ class sdistTestCase(PyPIRCCommandTestCase): self.assertEquals(result, ['fake-1.0.tar', 'fake-1.0.tar.gz']) - 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_get_file_list(self): - # make sure MANIFEST is recalculated - dist, cmd = self.get_cmd() - - os.chdir(self.tmp_dir) - - # filling data_files by pointing files in package_data - os.mkdir(os.path.join(self.tmp_dir, 'somecode')) - self.write_file((self.tmp_dir, 'somecode', '__init__.py'), '#') - self.write_file((self.tmp_dir, 'somecode', 'one.py'), '#') - cmd.ensure_finalized() - cmd.run() - - f = open(cmd.manifest) - try: - manifest = [line.strip() for line in f.read().split('\n') - if line.strip() != ''] - finally: - f.close() - - self.assertEquals(len(manifest), 2) - - # adding a file - self.write_file((self.tmp_dir, 'somecode', 'two.py'), '#') - - # make sure build_py is reinitinialized, like a fresh run - build_py = dist.get_command_obj('build_py') - build_py.finalized = False - build_py.ensure_finalized() - - cmd.run() - - f = open(cmd.manifest) - try: - manifest2 = [line.strip() for line in f.read().split('\n') - if line.strip() != ''] - finally: - f.close() - - # do we have the new file in MANIFEST ? - self.assertEquals(len(manifest2), 3) - self.assert_('two.py' in manifest2[-1]) - - def test_suite(): return unittest.makeSuite(sdistTestCase) diff --git a/Misc/NEWS b/Misc/NEWS index ec1256a426a..1ffcb49d670 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,9 @@ What's New in Python 2.6.6? Library ------- +- Issue #8688: Revert regression introduced in 2.6.6rc1 (making Distutils + recalculate MANIFEST every time). + - Issue #5798: Handle select.poll flag oddities properly on OS X. This fixes test_asynchat and test_smtplib failures on OS X.