Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2ffea0e

Browse files
committed
Branch merge
2 parents 9525956 + 548c054 commit 2ffea0e

7 files changed

Lines changed: 111 additions & 47 deletions

File tree

Doc/distutils/sourcedist.rst

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,20 @@ per line, regular files (or symlinks to them) only. If you do supply your own
103103
:file:`MANIFEST`, you must specify everything: the default set of files
104104
described above does not apply in this case.
105105

106-
.. versionadded:: 3.1
106+
.. versionchanged:: 3.1
107+
An existing generated :file:`MANIFEST` will be regenerated without
108+
:command:`sdist` comparing its modification time to the one of
109+
:file:`MANIFEST.in` or :file:`setup.py`.
110+
111+
.. versionchanged:: 3.1.3
107112
:file:`MANIFEST` files start with a comment indicating they are generated.
108113
Files without this comment are not overwritten or removed.
109114

115+
.. versionchanged:: 3.2.2
116+
:command:`sdist` will read a :file:`MANIFEST` file if no :file:`MANIFEST.in`
117+
exists, like it used to do.
118+
119+
110120
The manifest template has one command per line, where each command specifies a
111121
set of files to include or exclude from the source distribution. For an
112122
example, again we turn to the Distutils' own manifest template::
@@ -185,8 +195,12 @@ Manifest-related options
185195

186196
The normal course of operations for the :command:`sdist` command is as follows:
187197

188-
* if the manifest file, :file:`MANIFEST` doesn't exist, read :file:`MANIFEST.in`
189-
and create the manifest
198+
* if the manifest file (:file:`MANIFEST` by default) exists and the first line
199+
does not have a comment indicating it is generated from :file:`MANIFEST.in`,
200+
then it is used as is, unaltered
201+
202+
* if the manifest file doesn't exist or has been previously automatically
203+
generated, read :file:`MANIFEST.in` and create the manifest
190204

191205
* if neither :file:`MANIFEST` nor :file:`MANIFEST.in` exist, create a manifest
192206
with just the default file set
@@ -204,8 +218,3 @@ distribution::
204218
python setup.py sdist --manifest-only
205219

206220
:option:`-o` is a shortcut for :option:`--manifest-only`.
207-
208-
.. versionchanged:: 3.1
209-
An existing generated :file:`MANIFEST` will be regenerated without
210-
:command:`sdist` comparing its modification time to the one of
211-
:file:`MANIFEST.in` or :file:`setup.py`.

Lib/distutils/command/sdist.py

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -174,14 +174,20 @@ def get_file_list(self):
174174
reading the manifest, or just using the default file set -- it all
175175
depends on the user's options.
176176
"""
177-
# new behavior:
177+
# new behavior when using a template:
178178
# the file list is recalculated everytime because
179179
# even if MANIFEST.in or setup.py are not changed
180180
# the user might have added some files in the tree that
181181
# need to be included.
182182
#
183-
# This makes --force the default and only behavior.
183+
# This makes --force the default and only behavior with templates.
184184
template_exists = os.path.isfile(self.template)
185+
if not template_exists and self._manifest_is_not_generated():
186+
self.read_manifest()
187+
self.filelist.sort()
188+
self.filelist.remove_duplicates()
189+
return
190+
185191
if not template_exists:
186192
self.warn(("manifest template '%s' does not exist " +
187193
"(using default file list)") %
@@ -336,36 +342,40 @@ def write_manifest(self):
336342
by 'add_defaults()' and 'read_template()') to the manifest file
337343
named by 'self.manifest'.
338344
"""
339-
if os.path.isfile(self.manifest):
340-
fp = open(self.manifest)
341-
try:
342-
first_line = fp.readline()
343-
finally:
344-
fp.close()
345-
346-
if first_line != '# file GENERATED by distutils, do NOT edit\n':
347-
log.info("not writing to manually maintained "
348-
"manifest file '%s'" % self.manifest)
349-
return
345+
if self._manifest_is_not_generated():
346+
log.info("not writing to manually maintained "
347+
"manifest file '%s'" % self.manifest)
348+
return
350349

351350
content = self.filelist.files[:]
352351
content.insert(0, '# file GENERATED by distutils, do NOT edit')
353352
self.execute(file_util.write_file, (self.manifest, content),
354353
"writing manifest file '%s'" % self.manifest)
355354

355+
def _manifest_is_not_generated(self):
356+
# check for special comment used in 3.1.3 and higher
357+
if not os.path.isfile(self.manifest):
358+
return False
359+
360+
fp = open(self.manifest)
361+
try:
362+
first_line = fp.readline()
363+
finally:
364+
fp.close()
365+
return first_line != '# file GENERATED by distutils, do NOT edit\n'
366+
356367
def read_manifest(self):
357368
"""Read the manifest file (named by 'self.manifest') and use it to
358369
fill in 'self.filelist', the list of files to include in the source
359370
distribution.
360371
"""
361372
log.info("reading manifest file '%s'", self.manifest)
362373
manifest = open(self.manifest)
363-
while True:
364-
line = manifest.readline()
365-
if line == '': # end of file
366-
break
367-
if line[-1] == '\n':
368-
line = line[0:-1]
374+
for line in manifest:
375+
# ignore comments and blank lines
376+
line = line.strip()
377+
if line.startswith('#') or not line:
378+
continue
369379
self.filelist.append(line)
370380
manifest.close()
371381

Lib/distutils/tests/test_sdist.py

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
"""Tests for distutils.command.sdist."""
22
import os
3+
import tarfile
34
import unittest
4-
import shutil
5+
import warnings
56
import zipfile
67
from os.path import join
7-
import sys
8-
import tempfile
9-
import warnings
8+
from textwrap import dedent
109

1110
from test.support import captured_stdout, check_warnings, run_unittest
1211

1312
from distutils.command.sdist import sdist, show_formats
1413
from distutils.core import Distribution
1514
from distutils.tests.test_config import PyPIRCCommandTestCase
16-
from distutils.errors import DistutilsExecError, DistutilsOptionError
15+
from distutils.errors import DistutilsOptionError
1716
from distutils.spawn import find_executable
18-
from distutils.tests import support
1917
from distutils.log import WARN
2018
from distutils.archive_util import ARCHIVE_FORMATS
2119

@@ -346,13 +344,33 @@ def test_manifest_marker(self):
346344
self.assertEqual(manifest[0],
347345
'# file GENERATED by distutils, do NOT edit')
348346

347+
@unittest.skipUnless(ZLIB_SUPPORT, "Need zlib support to run")
348+
def test_manifest_comments(self):
349+
# make sure comments don't cause exceptions or wrong includes
350+
contents = dedent("""\
351+
# bad.py
352+
#bad.py
353+
good.py
354+
""")
355+
dist, cmd = self.get_cmd()
356+
cmd.ensure_finalized()
357+
self.write_file((self.tmp_dir, cmd.manifest), contents)
358+
self.write_file((self.tmp_dir, 'good.py'), '# pick me!')
359+
self.write_file((self.tmp_dir, 'bad.py'), "# don't pick me!")
360+
self.write_file((self.tmp_dir, '#bad.py'), "# don't pick me!")
361+
cmd.run()
362+
self.assertEqual(cmd.filelist.files, ['good.py'])
363+
349364
@unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
350365
def test_manual_manifest(self):
351366
# check that a MANIFEST without a marker is left alone
352367
dist, cmd = self.get_cmd()
353368
cmd.ensure_finalized()
354369
self.write_file((self.tmp_dir, cmd.manifest), 'README.manual')
370+
self.write_file((self.tmp_dir, 'README.manual'),
371+
'This project maintains its MANIFEST file itself.')
355372
cmd.run()
373+
self.assertEqual(cmd.filelist.files, ['README.manual'])
356374

357375
f = open(cmd.manifest)
358376
try:
@@ -363,6 +381,15 @@ def test_manual_manifest(self):
363381

364382
self.assertEqual(manifest, ['README.manual'])
365383

384+
archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz')
385+
archive = tarfile.open(archive_name)
386+
try:
387+
filenames = [tarinfo.name for tarinfo in archive]
388+
finally:
389+
archive.close()
390+
self.assertEqual(sorted(filenames), ['fake-1.0', 'fake-1.0/PKG-INFO',
391+
'fake-1.0/README.manual'])
392+
366393
def test_suite():
367394
return unittest.makeSuite(SDistTestCase)
368395

Lib/lib2to3/tests/test_refactor.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,22 +177,26 @@ def print_output(self, old_text, new_text, filename, equal):
177177
self.assertEqual(results, expected)
178178

179179
def check_file_refactoring(self, test_file, fixers=_2TO3_FIXERS):
180+
tmpdir = tempfile.mkdtemp(prefix="2to3-test_refactor")
181+
self.addCleanup(shutil.rmtree, tmpdir)
182+
# make a copy of the tested file that we can write to
183+
shutil.copy(test_file, tmpdir)
184+
test_file = os.path.join(tmpdir, os.path.basename(test_file))
185+
os.chmod(test_file, 0o644)
186+
180187
def read_file():
181188
with open(test_file, "rb") as fp:
182189
return fp.read()
190+
183191
old_contents = read_file()
184192
rt = self.rt(fixers=fixers)
185193

186194
rt.refactor_file(test_file)
187195
self.assertEqual(old_contents, read_file())
188196

189-
try:
190-
rt.refactor_file(test_file, True)
191-
new_contents = read_file()
192-
self.assertNotEqual(old_contents, new_contents)
193-
finally:
194-
with open(test_file, "wb") as fp:
195-
fp.write(old_contents)
197+
rt.refactor_file(test_file, True)
198+
new_contents = read_file()
199+
self.assertNotEqual(old_contents, new_contents)
196200
return new_contents
197201

198202
def test_refactor_file(self):

Misc/ACKS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ Ned Deily
215215
Vincent Delft
216216
Arnaud Delobelle
217217
Erik Demaine
218+
John Dennis
218219
Roger Dev
219220
Raghuram Devarakonda
220221
Caleb Deveraux
@@ -875,6 +876,7 @@ Mikhail Terekhov
875876
Tobias Thelen
876877
James Thomas
877878
Robin Thomas
879+
Stephen Thorne
878880
Jeremy Thurgood
879881
Eric Tiedemann
880882
July Tikhonov

Misc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ Core and Builtins
4141
Library
4242
-------
4343

44+
- Issues #11104, #8688: Fix the behavior of distutils' sdist command with
45+
manually-maintained MANIFEST files.
46+
4447
- Issue #12464: tempfile.TemporaryDirectory.cleanup() should not follow
4548
symlinks: fix it. Patch by Petri Lehtinen.
4649

@@ -137,6 +140,9 @@ Tools/Demos
137140
Tests
138141
-----
139142

143+
- Issue #12331: The test suite for lib2to3 can now run from an installed
144+
Python.
145+
140146
- Issue #12626: In regrtest, allow to filter tests using a glob filter
141147
with the ``-m`` (or ``--match``) option. This works with all test cases
142148
using the unittest module. This is useful with long test suites

Tools/scripts/patchcheck.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44
import shutil
55
import os.path
66
import subprocess
7+
import sysconfig
78

89
import reindent
910
import untabify
1011

1112

13+
SRCDIR = sysconfig.get_config_var('srcdir')
14+
15+
1216
def n_files_str(count):
1317
"""Return 'N file(s)' with the proper plurality on 'file'."""
1418
return "{} file{}".format(count, "s" if count != 1 else "")
@@ -36,7 +40,7 @@ def call_fxn(*args, **kwargs):
3640
info=lambda x: n_files_str(len(x)))
3741
def changed_files():
3842
"""Get the list of changed or added files from the VCS."""
39-
if os.path.isdir('.hg'):
43+
if os.path.isdir(os.path.join(SRCDIR, '.hg')):
4044
vcs = 'hg'
4145
cmd = 'hg status --added --modified --no-status'
4246
elif os.path.isdir('.svn'):
@@ -75,7 +79,7 @@ def normalize_whitespace(file_paths):
7579
reindent.makebackup = False # No need to create backups.
7680
fixed = []
7781
for path in (x for x in file_paths if x.endswith('.py')):
78-
if reindent.check(path):
82+
if reindent.check(os.path.join(SRCDIR, path)):
7983
fixed.append(path)
8084
return fixed
8185

@@ -85,10 +89,11 @@ def normalize_c_whitespace(file_paths):
8589
"""Report if any C files """
8690
fixed = []
8791
for path in file_paths:
88-
with open(path, 'r') as f:
92+
abspath = os.path.join(SRCDIR, path)
93+
with open(abspath, 'r') as f:
8994
if '\t' not in f.read():
9095
continue
91-
untabify.process(path, 8, verbose=False)
96+
untabify.process(abspath, 8, verbose=False)
9297
fixed.append(path)
9398
return fixed
9499

@@ -99,13 +104,14 @@ def normalize_c_whitespace(file_paths):
99104
def normalize_docs_whitespace(file_paths):
100105
fixed = []
101106
for path in file_paths:
107+
abspath = os.path.join(SRCDIR, path)
102108
try:
103-
with open(path, 'rb') as f:
109+
with open(abspath, 'rb') as f:
104110
lines = f.readlines()
105111
new_lines = [ws_re.sub(br'\1', line) for line in lines]
106112
if new_lines != lines:
107-
shutil.copyfile(path, path + '.bak')
108-
with open(path, 'wb') as f:
113+
shutil.copyfile(abspath, abspath + '.bak')
114+
with open(abspath, 'wb') as f:
109115
f.writelines(new_lines)
110116
fixed.append(path)
111117
except Exception as err:

0 commit comments

Comments
 (0)