diff --git a/Lib/distutils/command/sdist.py b/Lib/distutils/command/sdist.py --- a/Lib/distutils/command/sdist.py +++ b/Lib/distutils/command/sdist.py @@ -350,7 +350,8 @@ class sdist(Command): def write_manifest(self): """Write the file list in 'self.filelist' (presumably as filled in by 'add_defaults()' and 'read_template()') to the manifest file - named by 'self.manifest'. + named by 'self.manifest'. All paths will use '/' as separator, for + cross-platform portability. """ if os.path.isfile(self.manifest): fp = open(self.manifest) @@ -366,6 +367,11 @@ class sdist(Command): content = self.filelist.files[:] content.insert(0, '# file GENERATED by distutils, do NOT edit') + + # always use / as path separator in MANIFEST + #if os.sep != '/': + # content = [line.replace(os.sep, '/') for line in content] + self.execute(file_util.write_file, (self.manifest, content), "writing manifest file '%s'" % self.manifest) diff --git a/Lib/distutils/tests/test_sdist.py b/Lib/distutils/tests/test_sdist.py --- a/Lib/distutils/tests/test_sdist.py +++ b/Lib/distutils/tests/test_sdist.py @@ -1,9 +1,9 @@ """Tests for distutils.command.sdist.""" import os import unittest -import shutil import zipfile import tarfile +import warnings # zlib is not used here, but if it's not available # the tests that use zipfile may fail @@ -20,18 +20,15 @@ except ImportError: UID_GID_SUPPORT = False from os.path import join -import sys -import tempfile -import warnings +from textwrap import dedent from test.test_support import captured_stdout, check_warnings, run_unittest from distutils.command.sdist import sdist, show_formats from distutils.core import Distribution from distutils.tests.test_config import PyPIRCCommandTestCase -from distutils.errors import DistutilsExecError, DistutilsOptionError +from distutils.errors import DistutilsOptionError from distutils.spawn import find_executable -from distutils.tests import support from distutils.log import WARN from distutils.archive_util import ARCHIVE_FORMATS @@ -47,13 +44,13 @@ MANIFEST = """\ README inroot.txt setup.py -data%(sep)sdata.dt -scripts%(sep)sscript.py -some%(sep)sfile.txt -some%(sep)sother_file.txt -somecode%(sep)s__init__.py -somecode%(sep)sdoc.dat -somecode%(sep)sdoc.txt +data/data.dt +scripts/script.py +some/file.txt +some/other_file.txt +somecode/__init__.py +somecode/doc.dat +somecode/doc.txt """ class SDistTestCase(PyPIRCCommandTestCase): @@ -233,7 +230,7 @@ class SDistTestCase(PyPIRCCommandTestCas f = open(join(self.tmp_dir, 'MANIFEST')) try: manifest = f.read() - self.assertEqual(manifest, MANIFEST % {'sep': os.sep}) + self.assertEqual(manifest, MANIFEST) finally: f.close() @@ -422,6 +419,56 @@ class SDistTestCase(PyPIRCCommandTestCas self.assertEqual(manifest, ['README.manual']) + def test_manifest_sep(self): + # paths in MANIFEST use '/' as path separator, so that Unix systems can + # read MANIFEST generated on Windows and vice versa (#828450) + self.addCleanup(setattr, os, 'sep', os.sep) + os.sep = '\\' + + dist, cmd = self.get_cmd() + cmd.ensure_finalized() + cmd.run() + + expected = [ + '# file GENERATED by distutils, do NOT edit\n', + 'README\n', + 'setup.py\n', + 'somecode/__init__.py\n', + ] + + f = open(cmd.manifest) + try: + manifest = f.readlines() + finally: + f.close() + + self.assertEqual(manifest, expected) + + def test_read_manifest(self): + # check if it's ok to read the MANIFEST file when all the file paths + # in it has taken '/' as separator, especially when Python use '\' as + # the separator on a specific system + self.addCleanup(setattr, os, 'sep', os.sep) + os.sep = '\\' + + manifest = dedent("""\ + README + setup.py + somecode/__init__.py + """) + + f = open(join(self.tmp_dir, 'MANIFEST'), 'w') + try: + f.write(manifest) + finally: + f.close() + + dist, cmd = self.get_cmd() + cmd.ensure_finalized() + cmd.run() + self.assertEqual(cmd.filelist.files, manifest.splitlines()) + + def test_suite(): return unittest.makeSuite(SDistTestCase)