[Python-checkins] cpython: Issue #22831: Use "with" to avoid possible fd leaks.

serhiy.storchaka python-checkins at python.org
Sat Apr 4 10:03:46 CEST 2015


https://hg.python.org/cpython/rev/ea94f6c87f5d
changeset:   95436:ea94f6c87f5d
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Sat Apr 04 11:01:02 2015 +0300
summary:
  Issue #22831: Use "with" to avoid possible fd leaks.

files:
  Lib/binhex.py         |  28 ++++++-------
  Lib/cgitb.py          |   5 +-
  Lib/dbm/__init__.py   |   6 +-
  Lib/http/cookiejar.py |   1 -
  Lib/platform.py       |  65 +++++++++++++++---------------
  Lib/pydoc.py          |   5 +-
  Lib/sre_constants.py  |  37 ++++++++---------
  Lib/token.py          |  12 ++--
  Lib/trace.py          |  40 +++++++++---------
  Lib/xmlrpc/client.py  |  28 +++++--------
  10 files changed, 107 insertions(+), 120 deletions(-)


diff --git a/Lib/binhex.py b/Lib/binhex.py
--- a/Lib/binhex.py
+++ b/Lib/binhex.py
@@ -229,14 +229,13 @@
     finfo = getfileinfo(inp)
     ofp = BinHex(finfo, out)
 
-    ifp = io.open(inp, 'rb')
-    # XXXX Do textfile translation on non-mac systems
-    while True:
-        d = ifp.read(128000)
-        if not d: break
-        ofp.write(d)
-    ofp.close_data()
-    ifp.close()
+    with io.open(inp, 'rb') as ifp:
+        # XXXX Do textfile translation on non-mac systems
+        while True:
+            d = ifp.read(128000)
+            if not d: break
+            ofp.write(d)
+        ofp.close_data()
 
     ifp = openrsrc(inp, 'rb')
     while True:
@@ -449,13 +448,12 @@
     if not out:
         out = ifp.FName
 
-    ofp = io.open(out, 'wb')
-    # XXXX Do translation on non-mac systems
-    while True:
-        d = ifp.read(128000)
-        if not d: break
-        ofp.write(d)
-    ofp.close()
+    with io.open(out, 'wb') as ofp:
+        # XXXX Do translation on non-mac systems
+        while True:
+            d = ifp.read(128000)
+            if not d: break
+            ofp.write(d)
     ifp.close_data()
 
     d = ifp.read_rsrc(128000)
diff --git a/Lib/cgitb.py b/Lib/cgitb.py
--- a/Lib/cgitb.py
+++ b/Lib/cgitb.py
@@ -294,9 +294,8 @@
             (fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir)
 
             try:
-                file = os.fdopen(fd, 'w')
-                file.write(doc)
-                file.close()
+                with os.fdopen(fd, 'w') as file:
+                    file.write(doc)
                 msg = '%s contains the description of this error.' % path
             except:
                 msg = 'Tried to save traceback to %s, but failed.' % path
diff --git a/Lib/dbm/__init__.py b/Lib/dbm/__init__.py
--- a/Lib/dbm/__init__.py
+++ b/Lib/dbm/__init__.py
@@ -153,9 +153,9 @@
     except OSError:
         return None
 
-    # Read the start of the file -- the magic number
-    s16 = f.read(16)
-    f.close()
+    with f:
+        # Read the start of the file -- the magic number
+        s16 = f.read(16)
     s = s16[0:4]
 
     # Return "" if not at least 4 bytes
diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py
--- a/Lib/http/cookiejar.py
+++ b/Lib/http/cookiejar.py
@@ -1999,7 +1999,6 @@
 
         magic = f.readline()
         if not self.magic_re.search(magic):
-            f.close()
             raise LoadError(
                 "%r does not look like a Netscape format cookies file" %
                 filename)
diff --git a/Lib/platform.py b/Lib/platform.py
--- a/Lib/platform.py
+++ b/Lib/platform.py
@@ -163,40 +163,39 @@
         # here to work around problems with Cygwin not being
         # able to open symlinks for reading
         executable = os.path.realpath(executable)
-    f = open(executable, 'rb')
-    binary = f.read(chunksize)
-    pos = 0
-    while 1:
-        if b'libc' in binary or b'GLIBC' in binary:
-            m = _libc_search.search(binary, pos)
-        else:
-            m = None
-        if not m:
-            binary = f.read(chunksize)
-            if not binary:
-                break
-            pos = 0
-            continue
-        libcinit, glibc, glibcversion, so, threads, soversion = [
-            s.decode('latin1') if s is not None else s
-            for s in m.groups()]
-        if libcinit and not lib:
-            lib = 'libc'
-        elif glibc:
-            if lib != 'glibc':
-                lib = 'glibc'
-                version = glibcversion
-            elif glibcversion > version:
-                version = glibcversion
-        elif so:
-            if lib != 'glibc':
+    with open(executable, 'rb') as f:
+        binary = f.read(chunksize)
+        pos = 0
+        while 1:
+            if b'libc' in binary or b'GLIBC' in binary:
+                m = _libc_search.search(binary, pos)
+            else:
+                m = None
+            if not m:
+                binary = f.read(chunksize)
+                if not binary:
+                    break
+                pos = 0
+                continue
+            libcinit, glibc, glibcversion, so, threads, soversion = [
+                s.decode('latin1') if s is not None else s
+                for s in m.groups()]
+            if libcinit and not lib:
                 lib = 'libc'
-                if soversion and soversion > version:
-                    version = soversion
-                if threads and version[-len(threads):] != threads:
-                    version = version + threads
-        pos = m.end()
-    f.close()
+            elif glibc:
+                if lib != 'glibc':
+                    lib = 'glibc'
+                    version = glibcversion
+                elif glibcversion > version:
+                    version = glibcversion
+            elif so:
+                if lib != 'glibc':
+                    lib = 'libc'
+                    if soversion and soversion > version:
+                        version = soversion
+                    if threads and version[-len(threads):] != threads:
+                        version = version + threads
+            pos = m.end()
     return lib, version
 
 def _dist_try_harder(distname, version, id):
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -1639,9 +1639,8 @@
     try:
         object, name = resolve(thing, forceload)
         page = html.page(describe(object), html.document(object, name))
-        file = open(name + '.html', 'w', encoding='utf-8')
-        file.write(page)
-        file.close()
+        with open(name + '.html', 'w', encoding='utf-8') as file:
+            file.write(page)
         print('wrote', name + '.html')
     except (ImportError, ErrorDuringImport) as value:
         print(value)
diff --git a/Lib/sre_constants.py b/Lib/sre_constants.py
--- a/Lib/sre_constants.py
+++ b/Lib/sre_constants.py
@@ -182,8 +182,8 @@
         items = sorted(d)
         for item in items:
             f.write("#define %s_%s %d\n" % (prefix, item, item))
-    f = open("sre_constants.h", "w")
-    f.write("""\
+    with open("sre_constants.h", "w") as f:
+        f.write("""\
 /*
  * Secret Labs' Regular Expression Engine
  *
@@ -199,25 +199,24 @@
 
 """)
 
-    f.write("#define SRE_MAGIC %d\n" % MAGIC)
+        f.write("#define SRE_MAGIC %d\n" % MAGIC)
 
-    dump(f, OPCODES, "SRE_OP")
-    dump(f, ATCODES, "SRE")
-    dump(f, CHCODES, "SRE")
+        dump(f, OPCODES, "SRE_OP")
+        dump(f, ATCODES, "SRE")
+        dump(f, CHCODES, "SRE")
 
-    f.write("#define SRE_FLAG_TEMPLATE %d\n" % SRE_FLAG_TEMPLATE)
-    f.write("#define SRE_FLAG_IGNORECASE %d\n" % SRE_FLAG_IGNORECASE)
-    f.write("#define SRE_FLAG_LOCALE %d\n" % SRE_FLAG_LOCALE)
-    f.write("#define SRE_FLAG_MULTILINE %d\n" % SRE_FLAG_MULTILINE)
-    f.write("#define SRE_FLAG_DOTALL %d\n" % SRE_FLAG_DOTALL)
-    f.write("#define SRE_FLAG_UNICODE %d\n" % SRE_FLAG_UNICODE)
-    f.write("#define SRE_FLAG_VERBOSE %d\n" % SRE_FLAG_VERBOSE)
-    f.write("#define SRE_FLAG_DEBUG %d\n" % SRE_FLAG_DEBUG)
-    f.write("#define SRE_FLAG_ASCII %d\n" % SRE_FLAG_ASCII)
+        f.write("#define SRE_FLAG_TEMPLATE %d\n" % SRE_FLAG_TEMPLATE)
+        f.write("#define SRE_FLAG_IGNORECASE %d\n" % SRE_FLAG_IGNORECASE)
+        f.write("#define SRE_FLAG_LOCALE %d\n" % SRE_FLAG_LOCALE)
+        f.write("#define SRE_FLAG_MULTILINE %d\n" % SRE_FLAG_MULTILINE)
+        f.write("#define SRE_FLAG_DOTALL %d\n" % SRE_FLAG_DOTALL)
+        f.write("#define SRE_FLAG_UNICODE %d\n" % SRE_FLAG_UNICODE)
+        f.write("#define SRE_FLAG_VERBOSE %d\n" % SRE_FLAG_VERBOSE)
+        f.write("#define SRE_FLAG_DEBUG %d\n" % SRE_FLAG_DEBUG)
+        f.write("#define SRE_FLAG_ASCII %d\n" % SRE_FLAG_ASCII)
 
-    f.write("#define SRE_INFO_PREFIX %d\n" % SRE_INFO_PREFIX)
-    f.write("#define SRE_INFO_LITERAL %d\n" % SRE_INFO_LITERAL)
-    f.write("#define SRE_INFO_CHARSET %d\n" % SRE_INFO_CHARSET)
+        f.write("#define SRE_INFO_PREFIX %d\n" % SRE_INFO_PREFIX)
+        f.write("#define SRE_INFO_LITERAL %d\n" % SRE_INFO_LITERAL)
+        f.write("#define SRE_INFO_CHARSET %d\n" % SRE_INFO_CHARSET)
 
-    f.close()
     print("done")
diff --git a/Lib/token.py b/Lib/token.py
--- a/Lib/token.py
+++ b/Lib/token.py
@@ -97,8 +97,8 @@
     except OSError as err:
         sys.stdout.write("I/O error: %s\n" % str(err))
         sys.exit(1)
-    lines = fp.read().split("\n")
-    fp.close()
+    with fp:
+        lines = fp.read().split("\n")
     prog = re.compile(
         "#define[ \t][ \t]*([A-Z0-9][A-Z0-9_]*)[ \t][ \t]*([0-9][0-9]*)",
         re.IGNORECASE)
@@ -116,8 +116,8 @@
     except OSError as err:
         sys.stderr.write("I/O error: %s\n" % str(err))
         sys.exit(2)
-    format = fp.read().split("\n")
-    fp.close()
+    with fp:
+        format = fp.read().split("\n")
     try:
         start = format.index("#--start constants--") + 1
         end = format.index("#--end constants--")
@@ -133,8 +133,8 @@
     except OSError as err:
         sys.stderr.write("I/O error: %s\n" % str(err))
         sys.exit(4)
-    fp.write("\n".join(format))
-    fp.close()
+    with fp:
+        fp.write("\n".join(format))
 
 
 if __name__ == "__main__":
diff --git a/Lib/trace.py b/Lib/trace.py
--- a/Lib/trace.py
+++ b/Lib/trace.py
@@ -232,8 +232,8 @@
         if self.infile:
             # Try to merge existing counts file.
             try:
-                counts, calledfuncs, callers = \
-                        pickle.load(open(self.infile, 'rb'))
+                with open(self.infile, 'rb') as f:
+                    counts, calledfuncs, callers = pickle.load(f)
                 self.update(self.__class__(counts, calledfuncs, callers))
             except (OSError, EOFError, ValueError) as err:
                 print(("Skipping counts file %r: %s"
@@ -361,26 +361,26 @@
 
         n_lines = 0
         n_hits = 0
-        for lineno, line in enumerate(lines, 1):
-            # do the blank/comment match to try to mark more lines
-            # (help the reader find stuff that hasn't been covered)
-            if lineno in lines_hit:
-                outfile.write("%5d: " % lines_hit[lineno])
-                n_hits += 1
-                n_lines += 1
-            elif rx_blank.match(line):
-                outfile.write("       ")
-            else:
-                # lines preceded by no marks weren't hit
-                # Highlight them if so indicated, unless the line contains
-                # #pragma: NO COVER
-                if lineno in lnotab and not PRAGMA_NOCOVER in line:
-                    outfile.write(">>>>>> ")
+        with outfile:
+            for lineno, line in enumerate(lines, 1):
+                # do the blank/comment match to try to mark more lines
+                # (help the reader find stuff that hasn't been covered)
+                if lineno in lines_hit:
+                    outfile.write("%5d: " % lines_hit[lineno])
+                    n_hits += 1
                     n_lines += 1
+                elif rx_blank.match(line):
+                    outfile.write("       ")
                 else:
-                    outfile.write("       ")
-            outfile.write(line.expandtabs(8))
-        outfile.close()
+                    # lines preceded by no marks weren't hit
+                    # Highlight them if so indicated, unless the line contains
+                    # #pragma: NO COVER
+                    if lineno in lnotab and not PRAGMA_NOCOVER in line:
+                        outfile.write(">>>>>> ")
+                        n_lines += 1
+                    else:
+                        outfile.write("       ")
+                outfile.write(line.expandtabs(8))
 
         return n_hits, n_lines
 
diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py
--- a/Lib/xmlrpc/client.py
+++ b/Lib/xmlrpc/client.py
@@ -1010,12 +1010,9 @@
     if not gzip:
         raise NotImplementedError
     f = BytesIO()
-    gzf = gzip.GzipFile(mode="wb", fileobj=f, compresslevel=1)
-    gzf.write(data)
-    gzf.close()
-    encoded = f.getvalue()
-    f.close()
-    return encoded
+    with gzip.GzipFile(mode="wb", fileobj=f, compresslevel=1) as gzf:
+        gzf.write(data)
+    return f.getvalue()
 
 ##
 # Decode a string using the gzip content encoding such as specified by the
@@ -1036,17 +1033,14 @@
     """
     if not gzip:
         raise NotImplementedError
-    f = BytesIO(data)
-    gzf = gzip.GzipFile(mode="rb", fileobj=f)
-    try:
-        if max_decode < 0: # no limit
-            decoded = gzf.read()
-        else:
-            decoded = gzf.read(max_decode + 1)
-    except OSError:
-        raise ValueError("invalid data")
-    f.close()
-    gzf.close()
+    with gzip.GzipFile(mode="rb", fileobj=BytesIO(data)) as gzf:
+        try:
+            if max_decode < 0: # no limit
+                decoded = gzf.read()
+            else:
+                decoded = gzf.read(max_decode + 1)
+        except OSError:
+            raise ValueError("invalid data")
     if max_decode >= 0 and len(decoded) > max_decode:
         raise ValueError("max gzipped payload length exceeded")
     return decoded

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list