| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535 |
- # -*- coding: utf-8 -*-
- """sdist tests"""
- import locale
- import os
- import shutil
- import sys
- import tempfile
- import unittest
- import unicodedata
- import re
- from setuptools.tests import environment, test_svn
- from setuptools.tests.py26compat import skipIf
- from setuptools.compat import StringIO, unicode
- from setuptools.tests.py26compat import skipIf
- from setuptools.command.sdist import sdist, walk_revctrl
- from setuptools.command.egg_info import manifest_maker
- from setuptools.dist import Distribution
- from setuptools import svn_utils
- SETUP_ATTRS = {
- 'name': 'sdist_test',
- 'version': '0.0',
- 'packages': ['sdist_test'],
- 'package_data': {'sdist_test': ['*.txt']}
- }
- SETUP_PY = """\
- from setuptools import setup
- setup(**%r)
- """ % SETUP_ATTRS
- if sys.version_info >= (3,):
- LATIN1_FILENAME = 'smörbröd.py'.encode('latin-1')
- else:
- LATIN1_FILENAME = 'sm\xf6rbr\xf6d.py'
- # Cannot use context manager because of Python 2.4
- def quiet():
- global old_stdout, old_stderr
- old_stdout, old_stderr = sys.stdout, sys.stderr
- sys.stdout, sys.stderr = StringIO(), StringIO()
- def unquiet():
- sys.stdout, sys.stderr = old_stdout, old_stderr
- # Fake byte literals for Python <= 2.5
- def b(s, encoding='utf-8'):
- if sys.version_info >= (3,):
- return s.encode(encoding)
- return s
- # Convert to POSIX path
- def posix(path):
- if sys.version_info >= (3,) and not isinstance(path, str):
- return path.replace(os.sep.encode('ascii'), b('/'))
- else:
- return path.replace(os.sep, '/')
- # HFS Plus uses decomposed UTF-8
- def decompose(path):
- if isinstance(path, unicode):
- return unicodedata.normalize('NFD', path)
- try:
- path = path.decode('utf-8')
- path = unicodedata.normalize('NFD', path)
- path = path.encode('utf-8')
- except UnicodeError:
- pass # Not UTF-8
- return path
- class TestSdistTest(unittest.TestCase):
- def setUp(self):
- self.temp_dir = tempfile.mkdtemp()
- f = open(os.path.join(self.temp_dir, 'setup.py'), 'w')
- f.write(SETUP_PY)
- f.close()
- # Set up the rest of the test package
- test_pkg = os.path.join(self.temp_dir, 'sdist_test')
- os.mkdir(test_pkg)
- # *.rst was not included in package_data, so c.rst should not be
- # automatically added to the manifest when not under version control
- for fname in ['__init__.py', 'a.txt', 'b.txt', 'c.rst']:
- # Just touch the files; their contents are irrelevant
- open(os.path.join(test_pkg, fname), 'w').close()
- self.old_cwd = os.getcwd()
- os.chdir(self.temp_dir)
- def tearDown(self):
- os.chdir(self.old_cwd)
- shutil.rmtree(self.temp_dir)
- def test_package_data_in_sdist(self):
- """Regression test for pull request #4: ensures that files listed in
- package_data are included in the manifest even if they're not added to
- version control.
- """
- dist = Distribution(SETUP_ATTRS)
- dist.script_name = 'setup.py'
- cmd = sdist(dist)
- cmd.ensure_finalized()
- # squelch output
- quiet()
- try:
- cmd.run()
- finally:
- unquiet()
- manifest = cmd.filelist.files
- self.assertTrue(os.path.join('sdist_test', 'a.txt') in manifest)
- self.assertTrue(os.path.join('sdist_test', 'b.txt') in manifest)
- self.assertTrue(os.path.join('sdist_test', 'c.rst') not in manifest)
- def test_manifest_is_written_with_utf8_encoding(self):
- # Test for #303.
- dist = Distribution(SETUP_ATTRS)
- dist.script_name = 'setup.py'
- mm = manifest_maker(dist)
- mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
- os.mkdir('sdist_test.egg-info')
- # UTF-8 filename
- filename = os.path.join('sdist_test', 'smörbröd.py')
- # Add UTF-8 filename and write manifest
- quiet()
- try:
- mm.run()
- mm.filelist.files.append(filename)
- mm.write_manifest()
- finally:
- unquiet()
- manifest = open(mm.manifest, 'rbU')
- contents = manifest.read()
- manifest.close()
- # The manifest should be UTF-8 encoded
- try:
- u_contents = contents.decode('UTF-8')
- except UnicodeDecodeError:
- e = sys.exc_info()[1]
- self.fail(e)
- # The manifest should contain the UTF-8 filename
- if sys.version_info >= (3,):
- self.assertTrue(posix(filename) in u_contents)
- else:
- self.assertTrue(posix(filename) in contents)
- # Python 3 only
- if sys.version_info >= (3,):
- def test_write_manifest_allows_utf8_filenames(self):
- # Test for #303.
- dist = Distribution(SETUP_ATTRS)
- dist.script_name = 'setup.py'
- mm = manifest_maker(dist)
- mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
- os.mkdir('sdist_test.egg-info')
- # UTF-8 filename
- filename = os.path.join(b('sdist_test'), b('smörbröd.py'))
- # Add filename and write manifest
- quiet()
- try:
- mm.run()
- u_filename = filename.decode('utf-8')
- mm.filelist.files.append(u_filename)
- # Re-write manifest
- mm.write_manifest()
- finally:
- unquiet()
- manifest = open(mm.manifest, 'rbU')
- contents = manifest.read()
- manifest.close()
- # The manifest should be UTF-8 encoded
- try:
- contents.decode('UTF-8')
- except UnicodeDecodeError:
- e = sys.exc_info()[1]
- self.fail(e)
- # The manifest should contain the UTF-8 filename
- self.assertTrue(posix(filename) in contents)
- # The filelist should have been updated as well
- self.assertTrue(u_filename in mm.filelist.files)
- def test_write_manifest_skips_non_utf8_filenames(self):
- # Test for #303.
- dist = Distribution(SETUP_ATTRS)
- dist.script_name = 'setup.py'
- mm = manifest_maker(dist)
- mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
- os.mkdir('sdist_test.egg-info')
- # Latin-1 filename
- filename = os.path.join(b('sdist_test'), LATIN1_FILENAME)
- # Add filename with surrogates and write manifest
- quiet()
- try:
- mm.run()
- u_filename = filename.decode('utf-8', 'surrogateescape')
- mm.filelist.files.append(u_filename)
- # Re-write manifest
- mm.write_manifest()
- finally:
- unquiet()
- manifest = open(mm.manifest, 'rbU')
- contents = manifest.read()
- manifest.close()
- # The manifest should be UTF-8 encoded
- try:
- contents.decode('UTF-8')
- except UnicodeDecodeError:
- e = sys.exc_info()[1]
- self.fail(e)
- # The Latin-1 filename should have been skipped
- self.assertFalse(posix(filename) in contents)
- # The filelist should have been updated as well
- self.assertFalse(u_filename in mm.filelist.files)
- def test_manifest_is_read_with_utf8_encoding(self):
- # Test for #303.
- dist = Distribution(SETUP_ATTRS)
- dist.script_name = 'setup.py'
- cmd = sdist(dist)
- cmd.ensure_finalized()
- # Create manifest
- quiet()
- try:
- cmd.run()
- finally:
- unquiet()
- # Add UTF-8 filename to manifest
- filename = os.path.join(b('sdist_test'), b('smörbröd.py'))
- cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
- manifest = open(cmd.manifest, 'ab')
- manifest.write(b('\n')+filename)
- manifest.close()
- # The file must exist to be included in the filelist
- open(filename, 'w').close()
- # Re-read manifest
- cmd.filelist.files = []
- quiet()
- try:
- cmd.read_manifest()
- finally:
- unquiet()
- # The filelist should contain the UTF-8 filename
- if sys.version_info >= (3,):
- filename = filename.decode('utf-8')
- self.assertTrue(filename in cmd.filelist.files)
- # Python 3 only
- if sys.version_info >= (3,):
- def test_read_manifest_skips_non_utf8_filenames(self):
- # Test for #303.
- dist = Distribution(SETUP_ATTRS)
- dist.script_name = 'setup.py'
- cmd = sdist(dist)
- cmd.ensure_finalized()
- # Create manifest
- quiet()
- try:
- cmd.run()
- finally:
- unquiet()
- # Add Latin-1 filename to manifest
- filename = os.path.join(b('sdist_test'), LATIN1_FILENAME)
- cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
- manifest = open(cmd.manifest, 'ab')
- manifest.write(b('\n')+filename)
- manifest.close()
- # The file must exist to be included in the filelist
- open(filename, 'w').close()
- # Re-read manifest
- cmd.filelist.files = []
- quiet()
- try:
- try:
- cmd.read_manifest()
- except UnicodeDecodeError:
- e = sys.exc_info()[1]
- self.fail(e)
- finally:
- unquiet()
- # The Latin-1 filename should have been skipped
- filename = filename.decode('latin-1')
- self.assertFalse(filename in cmd.filelist.files)
- @skipIf(sys.version_info >= (3,) and locale.getpreferredencoding() != 'UTF-8',
- 'Unittest fails if locale is not utf-8 but the manifests is recorded correctly')
- def test_sdist_with_utf8_encoded_filename(self):
- # Test for #303.
- dist = Distribution(SETUP_ATTRS)
- dist.script_name = 'setup.py'
- cmd = sdist(dist)
- cmd.ensure_finalized()
- # UTF-8 filename
- filename = os.path.join(b('sdist_test'), b('smörbröd.py'))
- open(filename, 'w').close()
- quiet()
- try:
- cmd.run()
- finally:
- unquiet()
- if sys.platform == 'darwin':
- filename = decompose(filename)
- if sys.version_info >= (3,):
- fs_enc = sys.getfilesystemencoding()
- if sys.platform == 'win32':
- if fs_enc == 'cp1252':
- # Python 3 mangles the UTF-8 filename
- filename = filename.decode('cp1252')
- self.assertTrue(filename in cmd.filelist.files)
- else:
- filename = filename.decode('mbcs')
- self.assertTrue(filename in cmd.filelist.files)
- else:
- filename = filename.decode('utf-8')
- self.assertTrue(filename in cmd.filelist.files)
- else:
- self.assertTrue(filename in cmd.filelist.files)
- def test_sdist_with_latin1_encoded_filename(self):
- # Test for #303.
- dist = Distribution(SETUP_ATTRS)
- dist.script_name = 'setup.py'
- cmd = sdist(dist)
- cmd.ensure_finalized()
- # Latin-1 filename
- filename = os.path.join(b('sdist_test'), LATIN1_FILENAME)
- open(filename, 'w').close()
- self.assertTrue(os.path.isfile(filename))
- quiet()
- try:
- cmd.run()
- finally:
- unquiet()
- if sys.version_info >= (3,):
- #not all windows systems have a default FS encoding of cp1252
- if sys.platform == 'win32':
- # Latin-1 is similar to Windows-1252 however
- # on mbcs filesys it is not in latin-1 encoding
- fs_enc = sys.getfilesystemencoding()
- if fs_enc == 'mbcs':
- filename = filename.decode('mbcs')
- else:
- filename = filename.decode('latin-1')
- self.assertTrue(filename in cmd.filelist.files)
- else:
- # The Latin-1 filename should have been skipped
- filename = filename.decode('latin-1')
- self.assertFalse(filename in cmd.filelist.files)
- else:
- # No conversion takes place under Python 2 and the file
- # is included. We shall keep it that way for BBB.
- self.assertTrue(filename in cmd.filelist.files)
- class TestDummyOutput(environment.ZippedEnvironment):
- def setUp(self):
- self.datafile = os.path.join('setuptools', 'tests',
- 'svn_data', "dummy.zip")
- self.dataname = "dummy"
- super(TestDummyOutput, self).setUp()
- def _run(self):
- code, data = environment.run_setup_py(["sdist"],
- pypath=self.old_cwd,
- data_stream=0)
- if code:
- info = "DIR: " + os.path.abspath('.')
- info += "\n SDIST RETURNED: %i\n\n" % code
- info += data
- raise AssertionError(info)
- datalines = data.splitlines()
- possible = (
- "running sdist",
- "running egg_info",
- "creating dummy\.egg-info",
- "writing dummy\.egg-info",
- "writing top-level names to dummy\.egg-info",
- "writing dependency_links to dummy\.egg-info",
- "writing manifest file 'dummy\.egg-info",
- "reading manifest file 'dummy\.egg-info",
- "reading manifest template 'MANIFEST\.in'",
- "writing manifest file 'dummy\.egg-info",
- "creating dummy-0.1.1",
- "making hard links in dummy-0\.1\.1",
- "copying files to dummy-0\.1\.1",
- "copying \S+ -> dummy-0\.1\.1",
- "copying dummy",
- "copying dummy\.egg-info",
- "hard linking \S+ -> dummy-0\.1\.1",
- "hard linking dummy",
- "hard linking dummy\.egg-info",
- "Writing dummy-0\.1\.1",
- "creating dist",
- "creating 'dist",
- "Creating tar archive",
- "running check",
- "adding 'dummy-0\.1\.1",
- "tar .+ dist/dummy-0\.1\.1\.tar dummy-0\.1\.1",
- "gzip .+ dist/dummy-0\.1\.1\.tar",
- "removing 'dummy-0\.1\.1' \\(and everything under it\\)",
- )
- print(" DIR: " + os.path.abspath('.'))
- for line in datalines:
- found = False
- for pattern in possible:
- if re.match(pattern, line):
- print(" READ: " + line)
- found = True
- break
- if not found:
- raise AssertionError("Unexpexected: %s\n-in-\n%s"
- % (line, data))
- return data
- def test_sources(self):
- self._run()
- class TestSvn(environment.ZippedEnvironment):
- def setUp(self):
- version = svn_utils.SvnInfo.get_svn_version()
- if not version: # None or Empty
- return
- self.base_version = tuple([int(x) for x in version.split('.')][:2])
- if not self.base_version:
- raise ValueError('No SVN tools installed')
- elif self.base_version < (1, 3):
- raise ValueError('Insufficient SVN Version %s' % version)
- elif self.base_version >= (1, 9):
- #trying the latest version
- self.base_version = (1, 8)
- self.dataname = "svn%i%i_example" % self.base_version
- self.datafile = os.path.join('setuptools', 'tests',
- 'svn_data', self.dataname + ".zip")
- super(TestSvn, self).setUp()
- @skipIf(not test_svn._svn_check, "No SVN to text, in the first place")
- def test_walksvn(self):
- if self.base_version >= (1, 6):
- folder2 = 'third party2'
- folder3 = 'third party3'
- else:
- folder2 = 'third_party2'
- folder3 = 'third_party3'
- #TODO is this right
- expected = set([
- os.path.join('a file'),
- os.path.join(folder2, 'Changes.txt'),
- os.path.join(folder2, 'MD5SUMS'),
- os.path.join(folder2, 'README.txt'),
- os.path.join(folder3, 'Changes.txt'),
- os.path.join(folder3, 'MD5SUMS'),
- os.path.join(folder3, 'README.txt'),
- os.path.join(folder3, 'TODO.txt'),
- os.path.join(folder3, 'fin'),
- os.path.join('third_party', 'README.txt'),
- os.path.join('folder', folder2, 'Changes.txt'),
- os.path.join('folder', folder2, 'MD5SUMS'),
- os.path.join('folder', folder2, 'WatashiNiYomimasu.txt'),
- os.path.join('folder', folder3, 'Changes.txt'),
- os.path.join('folder', folder3, 'fin'),
- os.path.join('folder', folder3, 'MD5SUMS'),
- os.path.join('folder', folder3, 'oops'),
- os.path.join('folder', folder3, 'WatashiNiYomimasu.txt'),
- os.path.join('folder', folder3, 'ZuMachen.txt'),
- os.path.join('folder', 'third_party', 'WatashiNiYomimasu.txt'),
- os.path.join('folder', 'lalala.txt'),
- os.path.join('folder', 'quest.txt'),
- # The example will have a deleted file
- # (or should) but shouldn't return it
- ])
- self.assertEqual(set(x for x in walk_revctrl()), expected)
- def test_suite():
- return unittest.defaultTestLoader.loadTestsFromName(__name__)
|