import contextlib import pathlib import pathlib as pl from pathlib import Path from pathlib import Path as P # SIM115 f = open("foo.txt") f = Path("foo.txt").open() f = pathlib.Path("foo.txt").open() f = pl.Path("foo.txt").open() f = P("foo.txt").open() data = f.read() f.close() # OK with open("foo.txt") as f: data = f.read() # OK with contextlib.ExitStack() as exit_stack: f = exit_stack.enter_context(open("filename")) # OK with contextlib.ExitStack() as stack: files = [stack.enter_context(open(fname)) for fname in filenames] close_files = stack.pop_all().close # OK with contextlib.AsyncExitStack() as exit_stack: f = await exit_stack.enter_async_context(open("filename")) # OK (false negative) with contextlib.ExitStack(): f = exit_stack.enter_context(open("filename")) # SIM115 with contextlib.ExitStack(): f = open("filename") # OK with contextlib.ExitStack() as exit_stack: exit_stack_ = exit_stack f = exit_stack_.enter_context(open("filename")) # OK (quick one-liner to clear file contents) open("filename", "w").close() pathlib.Path("filename").open("w").close() # OK (custom context manager) class MyFile: def __init__(self, filename: str): self.filename = filename def __enter__(self): self.file = open(self.filename) def __exit__(self, exc_type, exc_val, exc_tb): self.file.close() import tempfile import tarfile from tarfile import TarFile import zipfile import io import codecs import bz2 import gzip import dbm import dbm.gnu import dbm.ndbm import dbm.dumb import lzma import shelve import tokenize import wave import fileinput f = tempfile.NamedTemporaryFile() f = tempfile.TemporaryFile() f = tempfile.SpooledTemporaryFile() f = tarfile.open("foo.tar") f = TarFile("foo.tar").open() f = tarfile.TarFile("foo.tar").open() f = tarfile.TarFile().open() f = zipfile.ZipFile("foo.zip").open("foo.txt") f = io.open("foo.txt") f = io.open_code("foo.txt") f = codecs.open("foo.txt") f = bz2.open("foo.txt") f = gzip.open("foo.txt") f = dbm.open("foo.db") f = dbm.gnu.open("foo.db") f = dbm.ndbm.open("foo.db") f = dbm.dumb.open("foo.db") f = lzma.open("foo.xz") f = lzma.LZMAFile("foo.xz") f = shelve.open("foo.db") f = tokenize.open("foo.py") f = wave.open("foo.wav") f = tarfile.TarFile.taropen("foo.tar") f = fileinput.input("foo.txt") f = fileinput.FileInput("foo.txt") with contextlib.suppress(Exception): # The following line is for example's sake. # For some f's above, this would raise an error (since it'd be f.readline() etc.) data = f.read() f.close() # OK with tempfile.TemporaryFile() as f: data = f.read() # OK with tarfile.open("foo.tar") as f: data = f.add("foo.txt") # OK with tarfile.TarFile("foo.tar") as f: data = f.add("foo.txt") # OK with tarfile.TarFile("foo.tar").open() as f: data = f.add("foo.txt") # OK with zipfile.ZipFile("foo.zip") as f: data = f.read("foo.txt") # OK with zipfile.ZipFile("foo.zip").open("foo.txt") as f: data = f.read() # OK with zipfile.ZipFile("foo.zip") as zf: with zf.open("foo.txt") as f: data = f.read() # OK with io.open("foo.txt") as f: data = f.read() # OK with io.open_code("foo.txt") as f: data = f.read() # OK with codecs.open("foo.txt") as f: data = f.read() # OK with bz2.open("foo.txt") as f: data = f.read() # OK with gzip.open("foo.txt") as f: data = f.read() # OK with dbm.open("foo.db") as f: data = f.get("foo") # OK with dbm.gnu.open("foo.db") as f: data = f.get("foo") # OK with dbm.ndbm.open("foo.db") as f: data = f.get("foo") # OK with dbm.dumb.open("foo.db") as f: data = f.get("foo") # OK with lzma.open("foo.xz") as f: data = f.read() # OK with lzma.LZMAFile("foo.xz") as f: data = f.read() # OK with shelve.open("foo.db") as f: data = f["foo"] # OK with tokenize.open("foo.py") as f: data = f.read() # OK with wave.open("foo.wav") as f: data = f.readframes(1024) # OK with tarfile.TarFile.taropen("foo.tar") as f: data = f.add("foo.txt") # OK with fileinput.input("foo.txt") as f: data = f.readline() # OK with fileinput.FileInput("foo.txt") as f: data = f.readline() # OK (quick one-liner to clear file contents) tempfile.NamedTemporaryFile().close() tempfile.TemporaryFile().close() tempfile.SpooledTemporaryFile().close() tarfile.open("foo.tar").close() tarfile.TarFile("foo.tar").close() tarfile.TarFile("foo.tar").open().close() tarfile.TarFile.open("foo.tar").close() zipfile.ZipFile("foo.zip").close() zipfile.ZipFile("foo.zip").open("foo.txt").close() io.open("foo.txt").close() io.open_code("foo.txt").close() codecs.open("foo.txt").close() bz2.open("foo.txt").close() gzip.open("foo.txt").close() dbm.open("foo.db").close() dbm.gnu.open("foo.db").close() dbm.ndbm.open("foo.db").close() dbm.dumb.open("foo.db").close() lzma.open("foo.xz").close() lzma.LZMAFile("foo.xz").close() shelve.open("foo.db").close() tokenize.open("foo.py").close() wave.open("foo.wav").close() tarfile.TarFile.taropen("foo.tar").close() fileinput.input("foo.txt").close() fileinput.FileInput("foo.txt").close() def aliased(): from shelve import open as open_shelf x = open_shelf("foo.dbm") x.close() from tarfile import TarFile as TF f = TF("foo").open() f.close() import dbm.sqlite3 # OK with dbm.sqlite3.open("foo.db") as f: print(f.keys()) # OK dbm.sqlite3.open("foo.db").close() # SIM115 f = dbm.sqlite3.open("foo.db") f.close() # OK def func(filepath, encoding): return open(filepath, mode="rt", encoding=encoding) # OK def func(filepath, encoding): return f(open(filepath, mode="rt", encoding=encoding))