comparison venv/lib/python2.7/site-packages/setuptools/tests/test_sdist.py @ 0:d67268158946 draft

planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
author bcclaywell
date Mon, 12 Oct 2015 17:43:33 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:d67268158946
1 # -*- coding: utf-8 -*-
2 """sdist tests"""
3
4 import locale
5 import os
6 import shutil
7 import sys
8 import tempfile
9 import unicodedata
10 import contextlib
11
12 import pytest
13
14 import pkg_resources
15 from setuptools.compat import StringIO, unicode, PY3, PY2
16 from setuptools.command.sdist import sdist
17 from setuptools.command.egg_info import manifest_maker
18 from setuptools.dist import Distribution
19
20 SETUP_ATTRS = {
21 'name': 'sdist_test',
22 'version': '0.0',
23 'packages': ['sdist_test'],
24 'package_data': {'sdist_test': ['*.txt']}
25 }
26
27
28 SETUP_PY = """\
29 from setuptools import setup
30
31 setup(**%r)
32 """ % SETUP_ATTRS
33
34
35 if PY3:
36 LATIN1_FILENAME = 'smörbröd.py'.encode('latin-1')
37 else:
38 LATIN1_FILENAME = 'sm\xf6rbr\xf6d.py'
39
40
41 # Cannot use context manager because of Python 2.4
42 @contextlib.contextmanager
43 def quiet():
44 old_stdout, old_stderr = sys.stdout, sys.stderr
45 sys.stdout, sys.stderr = StringIO(), StringIO()
46 try:
47 yield
48 finally:
49 sys.stdout, sys.stderr = old_stdout, old_stderr
50
51
52 # Fake byte literals for Python <= 2.5
53 def b(s, encoding='utf-8'):
54 if PY3:
55 return s.encode(encoding)
56 return s
57
58
59 # Convert to POSIX path
60 def posix(path):
61 if PY3 and not isinstance(path, str):
62 return path.replace(os.sep.encode('ascii'), b('/'))
63 else:
64 return path.replace(os.sep, '/')
65
66
67 # HFS Plus uses decomposed UTF-8
68 def decompose(path):
69 if isinstance(path, unicode):
70 return unicodedata.normalize('NFD', path)
71 try:
72 path = path.decode('utf-8')
73 path = unicodedata.normalize('NFD', path)
74 path = path.encode('utf-8')
75 except UnicodeError:
76 pass # Not UTF-8
77 return path
78
79
80 class TestSdistTest:
81
82 def setup_method(self, method):
83 self.temp_dir = tempfile.mkdtemp()
84 f = open(os.path.join(self.temp_dir, 'setup.py'), 'w')
85 f.write(SETUP_PY)
86 f.close()
87
88 # Set up the rest of the test package
89 test_pkg = os.path.join(self.temp_dir, 'sdist_test')
90 os.mkdir(test_pkg)
91 # *.rst was not included in package_data, so c.rst should not be
92 # automatically added to the manifest when not under version control
93 for fname in ['__init__.py', 'a.txt', 'b.txt', 'c.rst']:
94 # Just touch the files; their contents are irrelevant
95 open(os.path.join(test_pkg, fname), 'w').close()
96
97 self.old_cwd = os.getcwd()
98 os.chdir(self.temp_dir)
99
100 def teardown_method(self, method):
101 os.chdir(self.old_cwd)
102 shutil.rmtree(self.temp_dir)
103
104 def test_package_data_in_sdist(self):
105 """Regression test for pull request #4: ensures that files listed in
106 package_data are included in the manifest even if they're not added to
107 version control.
108 """
109
110 dist = Distribution(SETUP_ATTRS)
111 dist.script_name = 'setup.py'
112 cmd = sdist(dist)
113 cmd.ensure_finalized()
114
115 with quiet():
116 cmd.run()
117
118 manifest = cmd.filelist.files
119 assert os.path.join('sdist_test', 'a.txt') in manifest
120 assert os.path.join('sdist_test', 'b.txt') in manifest
121 assert os.path.join('sdist_test', 'c.rst') not in manifest
122
123
124 def test_defaults_case_sensitivity(self):
125 """
126 Make sure default files (README.*, etc.) are added in a case-sensitive
127 way to avoid problems with packages built on Windows.
128 """
129
130 open(os.path.join(self.temp_dir, 'readme.rst'), 'w').close()
131 open(os.path.join(self.temp_dir, 'SETUP.cfg'), 'w').close()
132
133 dist = Distribution(SETUP_ATTRS)
134 # the extension deliberately capitalized for this test
135 # to make sure the actual filename (not capitalized) gets added
136 # to the manifest
137 dist.script_name = 'setup.PY'
138 cmd = sdist(dist)
139 cmd.ensure_finalized()
140
141 with quiet():
142 cmd.run()
143
144 # lowercase all names so we can test in a case-insensitive way to make sure the files are not included
145 manifest = map(lambda x: x.lower(), cmd.filelist.files)
146 assert 'readme.rst' not in manifest, manifest
147 assert 'setup.py' not in manifest, manifest
148 assert 'setup.cfg' not in manifest, manifest
149
150 def test_manifest_is_written_with_utf8_encoding(self):
151 # Test for #303.
152 dist = Distribution(SETUP_ATTRS)
153 dist.script_name = 'setup.py'
154 mm = manifest_maker(dist)
155 mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
156 os.mkdir('sdist_test.egg-info')
157
158 # UTF-8 filename
159 filename = os.path.join('sdist_test', 'smörbröd.py')
160
161 # Must create the file or it will get stripped.
162 open(filename, 'w').close()
163
164 # Add UTF-8 filename and write manifest
165 with quiet():
166 mm.run()
167 mm.filelist.append(filename)
168 mm.write_manifest()
169
170 manifest = open(mm.manifest, 'rbU')
171 contents = manifest.read()
172 manifest.close()
173
174 # The manifest should be UTF-8 encoded
175 u_contents = contents.decode('UTF-8')
176
177 # The manifest should contain the UTF-8 filename
178 if PY2:
179 fs_enc = sys.getfilesystemencoding()
180 filename = filename.decode(fs_enc)
181
182 assert posix(filename) in u_contents
183
184 # Python 3 only
185 if PY3:
186
187 def test_write_manifest_allows_utf8_filenames(self):
188 # Test for #303.
189 dist = Distribution(SETUP_ATTRS)
190 dist.script_name = 'setup.py'
191 mm = manifest_maker(dist)
192 mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
193 os.mkdir('sdist_test.egg-info')
194
195 # UTF-8 filename
196 filename = os.path.join(b('sdist_test'), b('smörbröd.py'))
197
198 # Must touch the file or risk removal
199 open(filename, "w").close()
200
201 # Add filename and write manifest
202 with quiet():
203 mm.run()
204 u_filename = filename.decode('utf-8')
205 mm.filelist.files.append(u_filename)
206 # Re-write manifest
207 mm.write_manifest()
208
209 manifest = open(mm.manifest, 'rbU')
210 contents = manifest.read()
211 manifest.close()
212
213 # The manifest should be UTF-8 encoded
214 contents.decode('UTF-8')
215
216 # The manifest should contain the UTF-8 filename
217 assert posix(filename) in contents
218
219 # The filelist should have been updated as well
220 assert u_filename in mm.filelist.files
221
222 def test_write_manifest_skips_non_utf8_filenames(self):
223 """
224 Files that cannot be encoded to UTF-8 (specifically, those that
225 weren't originally successfully decoded and have surrogate
226 escapes) should be omitted from the manifest.
227 See https://bitbucket.org/tarek/distribute/issue/303 for history.
228 """
229 dist = Distribution(SETUP_ATTRS)
230 dist.script_name = 'setup.py'
231 mm = manifest_maker(dist)
232 mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
233 os.mkdir('sdist_test.egg-info')
234
235 # Latin-1 filename
236 filename = os.path.join(b('sdist_test'), LATIN1_FILENAME)
237
238 # Add filename with surrogates and write manifest
239 with quiet():
240 mm.run()
241 u_filename = filename.decode('utf-8', 'surrogateescape')
242 mm.filelist.append(u_filename)
243 # Re-write manifest
244 mm.write_manifest()
245
246 manifest = open(mm.manifest, 'rbU')
247 contents = manifest.read()
248 manifest.close()
249
250 # The manifest should be UTF-8 encoded
251 contents.decode('UTF-8')
252
253 # The Latin-1 filename should have been skipped
254 assert posix(filename) not in contents
255
256 # The filelist should have been updated as well
257 assert u_filename not in mm.filelist.files
258
259 def test_manifest_is_read_with_utf8_encoding(self):
260 # Test for #303.
261 dist = Distribution(SETUP_ATTRS)
262 dist.script_name = 'setup.py'
263 cmd = sdist(dist)
264 cmd.ensure_finalized()
265
266 # Create manifest
267 with quiet():
268 cmd.run()
269
270 # Add UTF-8 filename to manifest
271 filename = os.path.join(b('sdist_test'), b('smörbröd.py'))
272 cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
273 manifest = open(cmd.manifest, 'ab')
274 manifest.write(b('\n') + filename)
275 manifest.close()
276
277 # The file must exist to be included in the filelist
278 open(filename, 'w').close()
279
280 # Re-read manifest
281 cmd.filelist.files = []
282 with quiet():
283 cmd.read_manifest()
284
285 # The filelist should contain the UTF-8 filename
286 if PY3:
287 filename = filename.decode('utf-8')
288 assert filename in cmd.filelist.files
289
290 # Python 3 only
291 if PY3:
292
293 def test_read_manifest_skips_non_utf8_filenames(self):
294 # Test for #303.
295 dist = Distribution(SETUP_ATTRS)
296 dist.script_name = 'setup.py'
297 cmd = sdist(dist)
298 cmd.ensure_finalized()
299
300 # Create manifest
301 with quiet():
302 cmd.run()
303
304 # Add Latin-1 filename to manifest
305 filename = os.path.join(b('sdist_test'), LATIN1_FILENAME)
306 cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt')
307 manifest = open(cmd.manifest, 'ab')
308 manifest.write(b('\n') + filename)
309 manifest.close()
310
311 # The file must exist to be included in the filelist
312 open(filename, 'w').close()
313
314 # Re-read manifest
315 cmd.filelist.files = []
316 with quiet():
317 cmd.read_manifest()
318
319 # The Latin-1 filename should have been skipped
320 filename = filename.decode('latin-1')
321 assert filename not in cmd.filelist.files
322
323 @pytest.mark.skipif(PY3 and locale.getpreferredencoding() != 'UTF-8',
324 reason='Unittest fails if locale is not utf-8 but the manifests is '
325 'recorded correctly')
326 def test_sdist_with_utf8_encoded_filename(self):
327 # Test for #303.
328 dist = Distribution(SETUP_ATTRS)
329 dist.script_name = 'setup.py'
330 cmd = sdist(dist)
331 cmd.ensure_finalized()
332
333 # UTF-8 filename
334 filename = os.path.join(b('sdist_test'), b('smörbröd.py'))
335 open(filename, 'w').close()
336
337 with quiet():
338 cmd.run()
339
340 if sys.platform == 'darwin':
341 filename = decompose(filename)
342
343 if PY3:
344 fs_enc = sys.getfilesystemencoding()
345
346 if sys.platform == 'win32':
347 if fs_enc == 'cp1252':
348 # Python 3 mangles the UTF-8 filename
349 filename = filename.decode('cp1252')
350 assert filename in cmd.filelist.files
351 else:
352 filename = filename.decode('mbcs')
353 assert filename in cmd.filelist.files
354 else:
355 filename = filename.decode('utf-8')
356 assert filename in cmd.filelist.files
357 else:
358 assert filename in cmd.filelist.files
359
360 def test_sdist_with_latin1_encoded_filename(self):
361 # Test for #303.
362 dist = Distribution(SETUP_ATTRS)
363 dist.script_name = 'setup.py'
364 cmd = sdist(dist)
365 cmd.ensure_finalized()
366
367 # Latin-1 filename
368 filename = os.path.join(b('sdist_test'), LATIN1_FILENAME)
369 open(filename, 'w').close()
370 assert os.path.isfile(filename)
371
372 with quiet():
373 cmd.run()
374
375 if PY3:
376 # not all windows systems have a default FS encoding of cp1252
377 if sys.platform == 'win32':
378 # Latin-1 is similar to Windows-1252 however
379 # on mbcs filesys it is not in latin-1 encoding
380 fs_enc = sys.getfilesystemencoding()
381 if fs_enc == 'mbcs':
382 filename = filename.decode('mbcs')
383 else:
384 filename = filename.decode('latin-1')
385
386 assert filename in cmd.filelist.files
387 else:
388 # The Latin-1 filename should have been skipped
389 filename = filename.decode('latin-1')
390 filename not in cmd.filelist.files
391 else:
392 # Under Python 2 there seems to be no decoded string in the
393 # filelist. However, due to decode and encoding of the
394 # file name to get utf-8 Manifest the latin1 maybe excluded
395 try:
396 # fs_enc should match how one is expect the decoding to
397 # be proformed for the manifest output.
398 fs_enc = sys.getfilesystemencoding()
399 filename.decode(fs_enc)
400 assert filename in cmd.filelist.files
401 except UnicodeDecodeError:
402 filename not in cmd.filelist.files
403
404
405 def test_default_revctrl():
406 """
407 When _default_revctrl was removed from the `setuptools.command.sdist`
408 module in 10.0, it broke some systems which keep an old install of
409 setuptools (Distribute) around. Those old versions require that the
410 setuptools package continue to implement that interface, so this
411 function provides that interface, stubbed. See #320 for details.
412
413 This interface must be maintained until Ubuntu 12.04 is no longer
414 supported (by Setuptools).
415 """
416 ep_def = 'svn_cvs = setuptools.command.sdist:_default_revctrl'
417 ep = pkg_resources.EntryPoint.parse(ep_def)
418 res = ep.resolve()
419 assert hasattr(res, '__iter__')