Skip to content

Commit c5ecd00

Browse files
committed
Close file handles with context managers
modelsim and questaformal opened their generated tcl/Makefile outputs without closing them (or closed them in a non-exception-safe way), which shows up as ResourceWarnings under pytest. reporting and tools/edatool leaked read handles the same way. Convert all of them to with-statements. No functional change; the test suite passes with -W error::ResourceWarning.
1 parent 7e5f16f commit c5ecd00

4 files changed

Lines changed: 222 additions & 217 deletions

File tree

edalize/modelsim.py

Lines changed: 111 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -106,134 +106,133 @@ def get_doc(cls, api_ver):
106106
}
107107

108108
def _write_build_rtl_tcl_file(self, tcl_main):
109-
tcl_build_rtl = open(os.path.join(self.work_root, "edalize_build_rtl.tcl"), "w")
110-
111-
(src_files, incdirs) = self._get_fileset_files()
112-
vlog_include_dirs = ["+incdir+" + d.replace("\\", "/") for d in incdirs]
113-
114-
libs = []
115-
116-
vlog_files = []
117-
118-
common_compilation = self.tool_options.get("compilation_mode") == "common"
119-
for f in src_files:
120-
if not f.logical_name:
121-
f.logical_name = "work"
122-
if not f.logical_name in libs:
123-
tcl_build_rtl.write("vlib {}\n".format(f.logical_name))
124-
libs.append(f.logical_name)
125-
if f.file_type.startswith("verilogSource") or f.file_type.startswith(
126-
"systemVerilogSource"
127-
):
128-
vlog_files.append(f)
129-
cmd = "vlog"
130-
args = []
131-
132-
args += self.tool_options.get("vlog_options", [])
109+
with open(
110+
os.path.join(self.work_root, "edalize_build_rtl.tcl"), "w"
111+
) as tcl_build_rtl:
112+
113+
(src_files, incdirs) = self._get_fileset_files()
114+
vlog_include_dirs = ["+incdir+" + d.replace("\\", "/") for d in incdirs]
115+
116+
libs = []
117+
118+
vlog_files = []
119+
120+
common_compilation = self.tool_options.get("compilation_mode") == "common"
121+
for f in src_files:
122+
if not f.logical_name:
123+
f.logical_name = "work"
124+
if not f.logical_name in libs:
125+
tcl_build_rtl.write("vlib {}\n".format(f.logical_name))
126+
libs.append(f.logical_name)
127+
if f.file_type.startswith("verilogSource") or f.file_type.startswith(
128+
"systemVerilogSource"
129+
):
130+
vlog_files.append(f)
131+
cmd = "vlog"
132+
args = []
133133

134+
args += self.tool_options.get("vlog_options", [])
135+
136+
for k, v in self.vlogdefine.items():
137+
args += ["+define+{}={}".format(k, self._param_value_str(v))]
138+
139+
if f.file_type.startswith("systemVerilogSource"):
140+
args += ["-sv"]
141+
args += vlog_include_dirs
142+
elif f.file_type.startswith("vhdlSource"):
143+
cmd = "vcom"
144+
if f.file_type.endswith("-87"):
145+
args = ["-87"]
146+
if f.file_type.endswith("-93"):
147+
args = ["-93"]
148+
if f.file_type.endswith("-2008"):
149+
args = ["-2008"]
150+
else:
151+
args = []
152+
153+
args += self.tool_options.get("vcom_options", [])
154+
155+
elif f.file_type == "tclSource":
156+
cmd = None
157+
tcl_main.write("do {}\n".format(f.name))
158+
elif f.file_type == "user":
159+
cmd = None
160+
else:
161+
_s = "{} has unknown file type '{}'"
162+
logger.warning(_s.format(f.name, f.file_type))
163+
cmd = None
164+
if cmd and ((cmd != "vlog") or not common_compilation):
165+
args += ["-quiet"]
166+
args += ["-work", f.logical_name]
167+
args += [f.name.replace("\\", "/")]
168+
tcl_build_rtl.write("{} {}\n".format(cmd, " ".join(args)))
169+
if common_compilation:
170+
args = self.tool_options.get("vlog_options", [])
134171
for k, v in self.vlogdefine.items():
135172
args += ["+define+{}={}".format(k, self._param_value_str(v))]
136173

137-
if f.file_type.startswith("systemVerilogSource"):
174+
_vlog_files = []
175+
has_sv = False
176+
for f in vlog_files:
177+
_vlog_files.append(f.name.replace("\\", "/"))
178+
if f.file_type.startswith("systemVerilogSource"):
179+
has_sv = True
180+
181+
if has_sv:
138182
args += ["-sv"]
139183
args += vlog_include_dirs
140-
elif f.file_type.startswith("vhdlSource"):
141-
cmd = "vcom"
142-
if f.file_type.endswith("-87"):
143-
args = ["-87"]
144-
if f.file_type.endswith("-93"):
145-
args = ["-93"]
146-
if f.file_type.endswith("-2008"):
147-
args = ["-2008"]
148-
else:
149-
args = []
150-
151-
args += self.tool_options.get("vcom_options", [])
152-
153-
elif f.file_type == "tclSource":
154-
cmd = None
155-
tcl_main.write("do {}\n".format(f.name))
156-
elif f.file_type == "user":
157-
cmd = None
158-
else:
159-
_s = "{} has unknown file type '{}'"
160-
logger.warning(_s.format(f.name, f.file_type))
161-
cmd = None
162-
if cmd and ((cmd != "vlog") or not common_compilation):
163184
args += ["-quiet"]
164-
args += ["-work", f.logical_name]
165-
args += [f.name.replace("\\", "/")]
166-
tcl_build_rtl.write("{} {}\n".format(cmd, " ".join(args)))
167-
if common_compilation:
168-
args = self.tool_options.get("vlog_options", [])
169-
for k, v in self.vlogdefine.items():
170-
args += ["+define+{}={}".format(k, self._param_value_str(v))]
171-
172-
_vlog_files = []
173-
has_sv = False
174-
for f in vlog_files:
175-
_vlog_files.append(f.name.replace("\\", "/"))
176-
if f.file_type.startswith("systemVerilogSource"):
177-
has_sv = True
178-
179-
if has_sv:
180-
args += ["-sv"]
181-
args += vlog_include_dirs
182-
args += ["-quiet"]
183-
args += ["-work", "work"]
184-
args += ["-mfcu"]
185-
tcl_build_rtl.write(f"vlog {' '.join(args)} {' '.join(_vlog_files)}")
185+
args += ["-work", "work"]
186+
args += ["-mfcu"]
187+
tcl_build_rtl.write(f"vlog {' '.join(args)} {' '.join(_vlog_files)}")
186188

187189
def _write_makefile(self):
188-
vpi_make = open(os.path.join(self.work_root, "Makefile"), "w")
189-
_parameters = []
190-
for key, value in self.vlogparam.items():
191-
_parameters += ["{}={}".format(key, self._param_value_str(value))]
192-
for key, value in self.generic.items():
193-
_parameters += [
194-
"{}={}".format(key, self._param_value_str(value, bool_is_str=True))
195-
]
196-
_plusargs = []
197-
for key, value in self.plusarg.items():
198-
_plusargs += ["{}={}".format(key, self._param_value_str(value))]
199-
200-
_vsim_options = self.tool_options.get("vsim_options", [])
201-
202-
_modules = [m["name"] for m in self.vpi_modules]
203-
_clean_targets = " ".join(["clean_" + m for m in _modules])
204-
_s = MAKE_HEADER.format(
205-
toplevel=self.toplevel,
206-
parameters=" ".join(_parameters),
207-
plusargs=" ".join(_plusargs),
208-
vsim_options=" ".join(_vsim_options),
209-
modules=" ".join(_modules),
210-
clean_targets=_clean_targets,
211-
)
212-
vpi_make.write(_s)
213-
214-
for vpi_module in self.vpi_modules:
215-
_name = vpi_module["name"]
216-
_objs = [os.path.splitext(s)[0] + ".o" for s in vpi_module["src_files"]]
217-
_libs = ["-l" + l for l in vpi_module["libs"]]
218-
_incs = ["-I" + d for d in vpi_module["include_dirs"]]
219-
_s = VPI_MAKE_SECTION.format(
220-
name=_name,
221-
objs=" ".join(_objs),
222-
libs=" ".join(_libs),
223-
incs=" ".join(_incs),
190+
with open(os.path.join(self.work_root, "Makefile"), "w") as vpi_make:
191+
_parameters = []
192+
for key, value in self.vlogparam.items():
193+
_parameters += ["{}={}".format(key, self._param_value_str(value))]
194+
for key, value in self.generic.items():
195+
_parameters += [
196+
"{}={}".format(key, self._param_value_str(value, bool_is_str=True))
197+
]
198+
_plusargs = []
199+
for key, value in self.plusarg.items():
200+
_plusargs += ["{}={}".format(key, self._param_value_str(value))]
201+
202+
_vsim_options = self.tool_options.get("vsim_options", [])
203+
204+
_modules = [m["name"] for m in self.vpi_modules]
205+
_clean_targets = " ".join(["clean_" + m for m in _modules])
206+
_s = MAKE_HEADER.format(
207+
toplevel=self.toplevel,
208+
parameters=" ".join(_parameters),
209+
plusargs=" ".join(_plusargs),
210+
vsim_options=" ".join(_vsim_options),
211+
modules=" ".join(_modules),
212+
clean_targets=_clean_targets,
224213
)
225214
vpi_make.write(_s)
226215

227-
vpi_make.close()
216+
for vpi_module in self.vpi_modules:
217+
_name = vpi_module["name"]
218+
_objs = [os.path.splitext(s)[0] + ".o" for s in vpi_module["src_files"]]
219+
_libs = ["-l" + l for l in vpi_module["libs"]]
220+
_incs = ["-I" + d for d in vpi_module["include_dirs"]]
221+
_s = VPI_MAKE_SECTION.format(
222+
name=_name,
223+
objs=" ".join(_objs),
224+
libs=" ".join(_libs),
225+
incs=" ".join(_incs),
226+
)
227+
vpi_make.write(_s)
228228

229229
def configure_main(self):
230-
tcl_main = open(os.path.join(self.work_root, "edalize_main.tcl"), "w")
231-
tcl_main.write("onerror { quit -code 1; }\n")
232-
tcl_main.write("do edalize_build_rtl.tcl\n")
230+
with open(os.path.join(self.work_root, "edalize_main.tcl"), "w") as tcl_main:
231+
tcl_main.write("onerror { quit -code 1; }\n")
232+
tcl_main.write("do edalize_build_rtl.tcl\n")
233233

234-
self._write_build_rtl_tcl_file(tcl_main)
234+
self._write_build_rtl_tcl_file(tcl_main)
235235
self._write_makefile()
236-
tcl_main.close()
237236

238237
def run_main(self):
239238
args = ["run"]

0 commit comments

Comments
 (0)