Skip to content

Commit c3ca216

Browse files
committed
Avoid ResourceWarning: unclosed file
A number of such warnings showed up when running e.g. PYTHONWARNINGS=always python build_examples.py PYTHONWARNINGS=always wireviz ../../examples/demo0?.yml See #309 (comment) Fix: All open() calls should be in a "with open() as x" statement to ensure closing the file when exiting the block in any way. Otherwise, use the new file_read_text() or file_write_text() functions to read or write the whole utf-8 text file and closing it.
1 parent ba84c54 commit c3ca216

File tree

5 files changed

+29
-17
lines changed

5 files changed

+29
-17
lines changed

src/wireviz/Harness.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,10 @@
4444
)
4545
from wireviz.wv_helper import (
4646
awg_equiv,
47+
file_write_text,
4748
flatten2d,
4849
is_arrow,
4950
mm2_equiv,
50-
open_file_read,
51-
open_file_write,
5251
tuplelist2tsv,
5352
)
5453
from wireviz.wv_html import generate_html_output
@@ -693,7 +692,7 @@ def output(
693692
# BOM output
694693
bomlist = bom_list(self.bom())
695694
if "tsv" in fmt:
696-
open_file_write(f"{filename}.bom.tsv").write(tuplelist2tsv(bomlist))
695+
file_write_text(f"{filename}.bom.tsv", tuplelist2tsv(bomlist))
697696
if "csv" in fmt:
698697
# TODO: implement CSV output (preferrably using CSV library)
699698
print("CSV output is not yet supported")

src/wireviz/wireviz.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
from wireviz.Harness import Harness
1515
from wireviz.wv_helper import (
1616
expand,
17+
file_read_text,
1718
get_single_key_and_value,
1819
is_arrow,
19-
open_file_read,
2020
smart_file_resolve,
2121
)
2222

@@ -408,7 +408,7 @@ def _get_yaml_data_and_path(inp: Union[str, Path, Dict]) -> (Dict, Path):
408408
try:
409409
yaml_path = Path(inp).expanduser().resolve(strict=True)
410410
# if no FileNotFoundError exception happens, get file contents
411-
yaml_str = open_file_read(yaml_path).read()
411+
yaml_str = file_read_text(yaml_path)
412412
except (FileNotFoundError, OSError) as e:
413413
# if inp is a long YAML string, Pathlib will raise OSError: [errno.ENAMETOOLONG]
414414
# (in Windows, it seems OSError [errno.EINVAL] might be raised in some cases)

src/wireviz/wv_cli.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import wireviz.wireviz as wv
1313
from wireviz import APP_NAME, __version__
14-
from wireviz.wv_helper import open_file_read
14+
from wireviz.wv_helper import file_read_text
1515

1616
format_codes = {
1717
# "c": "csv",
@@ -111,7 +111,7 @@ def wireviz(file, format, prepend, output_dir, output_name, version):
111111
raise Exception(f"File does not exist:\n{prepend_file}")
112112
print("Prepend file:", prepend_file)
113113

114-
prepend_input += open_file_read(prepend_file).read() + "\n"
114+
prepend_input += file_read_text(prepend_file) + "\n"
115115
else:
116116
prepend_input = ""
117117

@@ -130,7 +130,7 @@ def wireviz(file, format, prepend, output_dir, output_name, version):
130130
"Output file: ", f"{Path(_output_dir / _output_name)}.{output_formats_str}"
131131
)
132132

133-
yaml_input = open_file_read(file).read()
133+
yaml_input = file_read_text(file)
134134
file_dir = file.parent
135135

136136
yaml_input = prepend_input + yaml_input

src/wireviz/wv_helper.py

+17-4
Original file line numberDiff line numberDiff line change
@@ -113,18 +113,31 @@ def clean_whitespace(inp):
113113

114114

115115
def open_file_read(filename):
116+
"""Open utf-8 encoded text file for reading - remember closing it when finished"""
116117
# TODO: Intelligently determine encoding
117118
return open(filename, "r", encoding="UTF-8")
118119

119120

120121
def open_file_write(filename):
122+
"""Open utf-8 encoded text file for writing - remember closing it when finished"""
121123
return open(filename, "w", encoding="UTF-8")
122124

123125

124126
def open_file_append(filename):
127+
"""Open utf-8 encoded text file for appending - remember closing it when finished"""
125128
return open(filename, "a", encoding="UTF-8")
126129

127130

131+
def file_read_text(filename: str) -> str:
132+
"""Read utf-8 encoded text file, close it, and return the text"""
133+
return Path(filename).read_text(encoding="utf-8")
134+
135+
136+
def file_write_text(filename: str, text: str) -> int:
137+
"""Write utf-8 encoded text file, close it, and return the number of characters written"""
138+
return Path(filename).write_text(text, encoding="utf-8")
139+
140+
128141
def is_arrow(inp):
129142
"""
130143
Matches strings of one or multiple `-` or `=` (but not mixed)
@@ -144,10 +157,10 @@ def aspect_ratio(image_src):
144157
try:
145158
from PIL import Image
146159

147-
image = Image.open(image_src)
148-
if image.width > 0 and image.height > 0:
149-
return image.width / image.height
150-
print(f"aspect_ratio(): Invalid image size {image.width} x {image.height}")
160+
with Image.open(image_src) as image:
161+
if image.width > 0 and image.height > 0:
162+
return image.width / image.height
163+
print(f"aspect_ratio(): Invalid image size {image.width} x {image.height}")
151164
# ModuleNotFoundError and FileNotFoundError are the most expected, but all are handled equally.
152165
except Exception as error:
153166
print(f"aspect_ratio(): {type(error).__name__}: {error}")

src/wireviz/wv_html.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
from wireviz.svgembed import data_URI_base64
1010
from wireviz.wv_gv_html import html_line_breaks
1111
from wireviz.wv_helper import (
12+
file_read_text,
13+
file_write_text,
1214
flatten2d,
13-
open_file_read,
14-
open_file_write,
1515
smart_file_resolve,
1616
)
1717

@@ -35,14 +35,14 @@ def generate_html_output(
3535
# fall back to built-in simple template if no template was provided
3636
templatefile = Path(__file__).parent / "templates/simple.html"
3737

38-
html = open_file_read(templatefile).read()
38+
html = file_read_text(templatefile)
3939

4040
# embed SVG diagram (only if used)
4141
def svgdata() -> str:
4242
return re.sub(
4343
"^<[?]xml [^?>]*[?]>[^<]*<!DOCTYPE [^>]*>",
4444
"<!-- XML and DOCTYPE declarations from SVG file removed -->",
45-
open_file_read(f"{filename}.tmp.svg").read(),
45+
file_read_text(f"{filename}.tmp.svg"),
4646
1,
4747
)
4848

@@ -128,4 +128,4 @@ def replacement_if_used(key: str, func: Callable[[], str]) -> None:
128128
pattern = re.compile("|".join(replacements_escaped))
129129
html = pattern.sub(lambda match: replacements[match.group(0)], html)
130130

131-
open_file_write(f"{filename}.html").write(html)
131+
file_write_text(f"{filename}.html", html)

0 commit comments

Comments
 (0)