Skip to content

Commit c5d5dfd

Browse files
bpo-22831: Use "with" to avoid possible fd leaks in distutils. (GH-10921)
1 parent 71f82a2 commit c5d5dfd

File tree

5 files changed

+65
-69
lines changed

5 files changed

+65
-69
lines changed

Lib/distutils/archive_util.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -166,21 +166,21 @@ def make_zipfile(base_name, base_dir, verbose=0, dry_run=0):
166166
zip = zipfile.ZipFile(zip_filename, "w",
167167
compression=zipfile.ZIP_STORED)
168168

169-
if base_dir != os.curdir:
170-
path = os.path.normpath(os.path.join(base_dir, ''))
171-
zip.write(path, path)
172-
log.info("adding '%s'", path)
173-
for dirpath, dirnames, filenames in os.walk(base_dir):
174-
for name in dirnames:
175-
path = os.path.normpath(os.path.join(dirpath, name, ''))
169+
with zip:
170+
if base_dir != os.curdir:
171+
path = os.path.normpath(os.path.join(base_dir, ''))
176172
zip.write(path, path)
177173
log.info("adding '%s'", path)
178-
for name in filenames:
179-
path = os.path.normpath(os.path.join(dirpath, name))
180-
if os.path.isfile(path):
174+
for dirpath, dirnames, filenames in os.walk(base_dir):
175+
for name in dirnames:
176+
path = os.path.normpath(os.path.join(dirpath, name, ''))
181177
zip.write(path, path)
182178
log.info("adding '%s'", path)
183-
zip.close()
179+
for name in filenames:
180+
path = os.path.normpath(os.path.join(dirpath, name))
181+
if os.path.isfile(path):
182+
zip.write(path, path)
183+
log.info("adding '%s'", path)
184184

185185
return zip_filename
186186

Lib/distutils/command/bdist_msi.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -390,18 +390,18 @@ def add_scripts(self):
390390
# entries for each version as the above code does
391391
if self.pre_install_script:
392392
scriptfn = os.path.join(self.bdist_dir, "preinstall.bat")
393-
f = open(scriptfn, "w")
394-
# The batch file will be executed with [PYTHON], so that %1
395-
# is the path to the Python interpreter; %0 will be the path
396-
# of the batch file.
397-
# rem ="""
398-
# %1 %0
399-
# exit
400-
# """
401-
# <actual script>
402-
f.write('rem ="""\n%1 %0\nexit\n"""\n')
403-
f.write(open(self.pre_install_script).read())
404-
f.close()
393+
with open(scriptfn, "w") as f:
394+
# The batch file will be executed with [PYTHON], so that %1
395+
# is the path to the Python interpreter; %0 will be the path
396+
# of the batch file.
397+
# rem ="""
398+
# %1 %0
399+
# exit
400+
# """
401+
# <actual script>
402+
f.write('rem ="""\n%1 %0\nexit\n"""\n')
403+
with open(self.pre_install_script) as fin:
404+
f.write(fin.read())
405405
add_data(self.db, "Binary",
406406
[("PreInstall", msilib.Binary(scriptfn))
407407
])

Lib/distutils/command/config.py

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,14 @@ def _check_compiler(self):
106106

107107
def _gen_temp_sourcefile(self, body, headers, lang):
108108
filename = "_configtest" + LANG_EXT[lang]
109-
file = open(filename, "w")
110-
if headers:
111-
for header in headers:
112-
file.write("#include <%s>\n" % header)
113-
file.write("\n")
114-
file.write(body)
115-
if body[-1] != "\n":
116-
file.write("\n")
117-
file.close()
109+
with open(filename, "w") as file:
110+
if headers:
111+
for header in headers:
112+
file.write("#include <%s>\n" % header)
113+
file.write("\n")
114+
file.write(body)
115+
if body[-1] != "\n":
116+
file.write("\n")
118117
return filename
119118

120119
def _preprocess(self, body, headers, include_dirs, lang):
@@ -203,17 +202,16 @@ def search_cpp(self, pattern, body=None, headers=None, include_dirs=None,
203202
if isinstance(pattern, str):
204203
pattern = re.compile(pattern)
205204

206-
file = open(out)
207-
match = False
208-
while True:
209-
line = file.readline()
210-
if line == '':
211-
break
212-
if pattern.search(line):
213-
match = True
214-
break
205+
with open(out) as file:
206+
match = False
207+
while True:
208+
line = file.readline()
209+
if line == '':
210+
break
211+
if pattern.search(line):
212+
match = True
213+
break
215214

216-
file.close()
217215
self._clean()
218216
return match
219217

Lib/distutils/command/sdist.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -407,14 +407,13 @@ def read_manifest(self):
407407
distribution.
408408
"""
409409
log.info("reading manifest file '%s'", self.manifest)
410-
manifest = open(self.manifest)
411-
for line in manifest:
412-
# ignore comments and blank lines
413-
line = line.strip()
414-
if line.startswith('#') or not line:
415-
continue
416-
self.filelist.append(line)
417-
manifest.close()
410+
with open(self.manifest) as manifest:
411+
for line in manifest:
412+
# ignore comments and blank lines
413+
line = line.strip()
414+
if line.startswith('#') or not line:
415+
continue
416+
self.filelist.append(line)
418417

419418
def make_release_tree(self, base_dir, files):
420419
"""Create the directory tree that will become the source

Lib/distutils/util.py

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -378,35 +378,34 @@ def byte_compile (py_files,
378378
else:
379379
script = open(script_name, "w")
380380

381-
script.write("""\
381+
with script:
382+
script.write("""\
382383
from distutils.util import byte_compile
383384
files = [
384385
""")
385386

386-
# XXX would be nice to write absolute filenames, just for
387-
# safety's sake (script should be more robust in the face of
388-
# chdir'ing before running it). But this requires abspath'ing
389-
# 'prefix' as well, and that breaks the hack in build_lib's
390-
# 'byte_compile()' method that carefully tacks on a trailing
391-
# slash (os.sep really) to make sure the prefix here is "just
392-
# right". This whole prefix business is rather delicate -- the
393-
# problem is that it's really a directory, but I'm treating it
394-
# as a dumb string, so trailing slashes and so forth matter.
395-
396-
#py_files = map(os.path.abspath, py_files)
397-
#if prefix:
398-
# prefix = os.path.abspath(prefix)
399-
400-
script.write(",\n".join(map(repr, py_files)) + "]\n")
401-
script.write("""
387+
# XXX would be nice to write absolute filenames, just for
388+
# safety's sake (script should be more robust in the face of
389+
# chdir'ing before running it). But this requires abspath'ing
390+
# 'prefix' as well, and that breaks the hack in build_lib's
391+
# 'byte_compile()' method that carefully tacks on a trailing
392+
# slash (os.sep really) to make sure the prefix here is "just
393+
# right". This whole prefix business is rather delicate -- the
394+
# problem is that it's really a directory, but I'm treating it
395+
# as a dumb string, so trailing slashes and so forth matter.
396+
397+
#py_files = map(os.path.abspath, py_files)
398+
#if prefix:
399+
# prefix = os.path.abspath(prefix)
400+
401+
script.write(",\n".join(map(repr, py_files)) + "]\n")
402+
script.write("""
402403
byte_compile(files, optimize=%r, force=%r,
403404
prefix=%r, base_dir=%r,
404405
verbose=%r, dry_run=0,
405406
direct=1)
406407
""" % (optimize, force, prefix, base_dir, verbose))
407408

408-
script.close()
409-
410409
cmd = [sys.executable]
411410
cmd.extend(subprocess._optim_args_from_interpreter_flags())
412411
cmd.append(script_name)

0 commit comments

Comments
 (0)