Skip to content

Commit

Permalink
Next incremental batch of pathlib changes (Issue #210)
Browse files Browse the repository at this point in the history
This one is related to the previous commit in the sense that the changes are related to file access. It's not really specific to pathlib, however.

The biggest change is to remove most of the exception handling for file access from IV_Swinger2.py (and IV_Swinger_plotter.py.) Most such exceptions would just print and log an error message. But for anyone running the GUI, that wouldn't be very noticeable. Instead, it's better to just let the exceptions propagate up to the GUI and either handle them explicitly there, or let the catch-all exception handler generate the message with the exception text.

In IV_Swinger2_gui.py, the exceptions that are explicitly caught look for either PermissionError if that is specifically what is being checked for, or OSError, which is more general. IOError was merged into OSError in Python 3.3.
  • Loading branch information
csatt committed Jul 28, 2023
1 parent 2fb8c4f commit e10e79d
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 101 deletions.
121 changes: 41 additions & 80 deletions python3/IV_Swinger2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1307,15 +1307,9 @@ def save(self, copy_dir=None):
self.ivs2.logger.print_and_log(dbg_str)
self.cfg_dump()
# Attempt to open the file for writing
try:
with self.cfg_filename.open("w", encoding="utf-8") as cfg_fp:
# Write config to file
self.cfg.write(cfg_fp)
except IOError:
# Failed to open file for writing
err_str = "Couldn't open config file for writing"
self.ivs2.logger.print_and_log(err_str)
return
with self.cfg_filename.open("w", encoding="utf-8") as cfg_fp:
# Write config to file
self.cfg.write(cfg_fp)

# Write meter debug values to log file since they may have
# changed
Expand All @@ -1336,13 +1330,8 @@ def save_snapshot(self):
f"config to {self.cfg_filename}")
self.ivs2.logger.print_and_log(dbg_str)
# Attempt to open the file for writing
try:
with self.cfg_filename.open("w", encoding="utf-8") as cfg_fp:
self.cfg_snapshot.write(cfg_fp)
except IOError:
# Failed to open file for writing
err_str = "Couldn't open config file for writing"
self.ivs2.logger.print_and_log(err_str)
with self.cfg_filename.open("w", encoding="utf-8") as cfg_fp:
self.cfg_snapshot.write(cfg_fp)

# -------------------------------------------------------------------------
def copy_file(self, dest_dir):
Expand All @@ -1356,11 +1345,7 @@ def copy_file(self, dest_dir):
dbg_str = (f"copy_file: Copying config from "
f"{self.cfg_filename} to {dest_dir}")
self.ivs2.logger.print_and_log(dbg_str)
try:
shutil.copy(self.cfg_filename, dest_dir)
except shutil.Error as e:
err_str = f"Couldn't copy config file to {dest_dir} ({e})"
self.ivs2.logger.print_and_log(err_str)
shutil.copy(self.cfg_filename, dest_dir)

# -------------------------------------------------------------------------
def populate(self):
Expand Down Expand Up @@ -1937,11 +1922,7 @@ def add_sensor_info_to_curve_names(self):
for csv_dir in self.csv_dirs:
run_info_filename = get_run_info_filename(Path(csv_dir))
info_added = False
try:
(irrad,
temps_dict) = get_sensor_values_from_file(run_info_filename)
except (IOError, OSError) as e:
self.logger.print_and_log(f"({e})")
(irrad, temps_dict) = get_sensor_values_from_file(run_info_filename)
if self.plot_ref and curve_num == 0:
irrad = None
temps_dict = {}
Expand Down Expand Up @@ -3733,10 +3714,7 @@ def create_run_info_file(self):
if self._ds18b20_rom_codes:
for msg in self._ds18b20_rom_codes:
run_info += f"{msg}"
try:
self.run_info_filename.write_text(run_info, encoding="utf-8")
except (IOError, OSError) as e:
self.logger.print_and_log(f"({e})")
self.run_info_filename.write_text(run_info, encoding="utf-8")

# -------------------------------------------------------------------------
def convert_sensor_to_run_info_file(self):
Expand All @@ -3747,15 +3725,12 @@ def convert_sensor_to_run_info_file(self):
# - append the contents of the sensor_info file
# - remove the sensor_info file
self.create_run_info_file()
try:
with self.sensor_info_filename.open(encoding="utf-8") as f:
sensor_lines = f.read().splitlines()
with self.run_info_filename.open("a", encoding="utf-8") as f:
for line in sensor_lines:
f.write(f"{line}\n")
Path(self.sensor_info_filename).unlink()
except (IOError, OSError) as e:
self.logger.print_and_log(f"({e})")
with self.sensor_info_filename.open(encoding="utf-8") as f:
sensor_lines = f.read().splitlines()
with self.run_info_filename.open("a", encoding="utf-8") as f:
for line in sensor_lines:
f.write(f"{line}\n")
Path(self.sensor_info_filename).unlink()

# -------------------------------------------------------------------------
def write_sensor_info_to_file(self, msg):
Expand All @@ -3767,11 +3742,8 @@ def write_sensor_info_to_file(self, msg):
info_str = self.translate_ads1115_msg_to_irradiance(msg)
else:
info_str = msg
try:
with self.run_info_filename.open("a", encoding="utf-8") as f:
f.write(f"{info_str}")
except (IOError, OSError) as e:
self.logger.print_and_log(f"({e})")
with self.run_info_filename.open("a", encoding="utf-8") as f:
f.write(f"{info_str}")

# -------------------------------------------------------------------------
def translate_ads1115_msg_to_photodiode_temp_scaling(self, msg):
Expand Down Expand Up @@ -3911,33 +3883,30 @@ def update_irradiance(self, new_irradiance):
new_lines = []
irrad_re = re.compile(r"Irradiance: (\d+) W/m\^2")
ext_irrad_re = re.compile(r"(\d+) @ (\S+) deg C")
try:
with self.run_info_filename.open(encoding="utf-8") as f:
for line in f.read().splitlines():
match = irrad_re.search(line)
if match:
ext_match = ext_irrad_re.search(line)
if ext_match:
old_irradiance = int(match.group(1))
ratio = new_irradiance / old_irradiance
old_uncomp_irrad = int(ext_match.group(1))
temp = float(ext_match.group(2))
new_uncomp_irrad = int(round(old_uncomp_irrad *
ratio))
ext_str = f" ({new_uncomp_irrad} @ {temp} deg C)"
else:
ext_str = ""
round_new_irradiance = int(round(new_irradiance))
new_lines.append(f"Irradiance: {round_new_irradiance} "
f"W/m^2{ext_str}")
self.irradiance = round_new_irradiance
with self.run_info_filename.open(encoding="utf-8") as f:
for line in f.read().splitlines():
match = irrad_re.search(line)
if match:
ext_match = ext_irrad_re.search(line)
if ext_match:
old_irradiance = int(match.group(1))
ratio = new_irradiance / old_irradiance
old_uncomp_irrad = int(ext_match.group(1))
temp = float(ext_match.group(2))
new_uncomp_irrad = int(round(old_uncomp_irrad *
ratio))
ext_str = f" ({new_uncomp_irrad} @ {temp} deg C)"
else:
new_lines.append(line)
with self.run_info_filename.open("w", encoding="utf-8") as f:
for line in new_lines:
f.write(f"{line}\n")
except (IOError, OSError) as e:
self.logger.print_and_log(f"({e})")
ext_str = ""
round_new_irradiance = int(round(new_irradiance))
new_lines.append(f"Irradiance: {round_new_irradiance} "
f"W/m^2{ext_str}")
self.irradiance = round_new_irradiance
else:
new_lines.append(line)
with self.run_info_filename.open("w", encoding="utf-8") as f:
for line in new_lines:
f.write(f"{line}\n")

# -------------------------------------------------------------------------
def log_msg_from_arduino(self, msg):
Expand Down Expand Up @@ -4961,11 +4930,7 @@ def copy_file_to_parent(self, filename):
output directory)
"""
run_dir = self.hdd_output_dir.parent
try:
shutil.copy(filename, run_dir)
except shutil.Error as e:
err_str = f"Couldn't copy {filename} to {run_dir} ({e})"
self.logger.print_and_log(err_str)
shutil.copy(filename, run_dir)

# -------------------------------------------------------------------------
def write_adc_pairs_to_csv_file(self, filename, adc_pairs):
Expand All @@ -4988,11 +4953,7 @@ def read_adc_pairs_from_csv_file(self, filename):
of ADC pairs
"""
adc_pairs = []
try:
csv_lines = filename.read_text(encoding="utf-8").splitlines()
except IOError:
self.logger.print_and_log(f"ERROR: Cannot read {filename}")
return []
csv_lines = filename.read_text(encoding="utf-8").splitlines()
for ii, line in enumerate(csv_lines):
if ii == 0:
expected_first_line = "CH0 (voltage), CH1 (current)"
Expand Down
43 changes: 29 additions & 14 deletions python3/IV_Swinger2_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ def handle_early_exception():
if not getattr(sys, "frozen", False):
print(err_msg)
return
tmp_file = Path(tempfile.NamedTemporaryFile(delete=False).name)
with tempfile.NamedTemporaryFile(delete=False) as f:
tmp_file = Path(f.name)
err_msg += f"""
-----------------------------------------------------------
Please copy/paste the above and send it to csatt1@gmail.com
Expand Down Expand Up @@ -332,9 +333,10 @@ def retry_if_pdf_permission_denied(func, *args):
file if they have it open in a viewer. Then the function is
called again.
"""
rc = RC_FAILURE
try:
rc = func(*args)
except IOError as e:
except PermissionError as e:
if pdf_permission_denied(e):
err_str = (f"({e})\n\nPDF could not be written. If you have it "
f"open in a viewer, close it BEFORE clicking OK.")
Expand All @@ -347,6 +349,8 @@ def retry_if_pdf_permission_denied(func, *args):
err_str = (f"({ee})\n\nPDF still could not be written. "
f"It will not be updated.")
tkmsg.showerror(message=err_str)
else:
tkmsg.showerror(message=e)
return rc


Expand Down Expand Up @@ -817,18 +821,17 @@ def check_app_data_dir(self, app_data_dir):
"""
try:
app_data_dir.mkdir(exist_ok=True)
except (IOError, OSError):
except PermissionError:
err_msg = f"""
FATAL ERROR: This user does not have
permission to create directories (folders) in
{app_data_dir.parent}"""
tkmsg.showerror(message=err_msg)
sys.exit()
try:
dummy_file = app_data_dir / "DUMMY_FILE"
dummy_file.touch()
dummy_file.unlink()
except (IOError, OSError):
(app_data_dir / "DUMMY_FILE").touch()
(app_data_dir / "DUMMY_FILE").unlink()
except PermissionError:
err_msg = f"""
FATAL ERROR: This user does not have
permission to create files in
Expand Down Expand Up @@ -876,7 +879,7 @@ def get_version(self):
version_file = self.app_dir / VERSION_FILE
try:
lines = version_file.read_text(encoding="utf-8").splitlines()
except IOError:
except OSError:
err_str = f"ERROR: {version_file} cannot be read"
self.ivs2.logger.print_and_log(err_str)
return
Expand Down Expand Up @@ -1582,7 +1585,7 @@ def restore_config(self, run_dir, config_dir,
if (run_dir is not None and run_dir.resolve() != config_dir.resolve()
and cfg_file.exists()):
self.config.cfg_filename = original_cfg_file
self.config.save_snapshot()
self.save_snapshot()

# -------------------------------------------------------------------------
def handle_plot_power_or_ref_event(self, button="power", plot=True):
Expand Down Expand Up @@ -1936,7 +1939,19 @@ def save_config(self):
(not self.looping or self.loop_save_results)):
copy_dir = self.ivs2.hdd_output_dir

self.config.save(copy_dir=copy_dir)
try:
self.config.save(copy_dir=copy_dir)
except OSError as e:
tkmsg.showerror(message=e)

# -------------------------------------------------------------------------
def save_snapshot(self):
"""Wrapper around save_snapshot() method of the Configuration class.
"""
try:
self.config.save_snapshot()
except OSError as e:
tkmsg.showerror(message=e)

# -------------------------------------------------------------------------
def show_preferences(self, event=None):
Expand Down Expand Up @@ -3721,7 +3736,7 @@ def copy_dirs(self, src_dirs, overwrite):
if overwrite:
try:
shutil.rmtree(dest_dir)
except (IOError, OSError, shutil.Error) as e:
except (OSError, shutil.Error) as e:
err_str = f"ERROR: removing {dest_dir} ({e})"
tkmsg.showerror(message=err_str)
continue
Expand All @@ -3734,7 +3749,7 @@ def copy_dirs(self, src_dirs, overwrite):
else:
num_copied["runs"] += 1
self.master.ivs2.logger.log(f"Copied {src_dir} to {dest_dir}")
except (IOError, OSError, shutil.Error) as e:
except (OSError, shutil.Error) as e:
err_str = (f"ERROR: error copying {src_dir} to "
f"{dest_dir}\n({e})")
tkmsg.showerror(message=err_str)
Expand Down Expand Up @@ -7214,7 +7229,7 @@ def revert(self):
values to properties and the config
"""
# Restore config
self.master.config.save_snapshot()
self.master.save_snapshot()
self.master.config.get()

# Restore properties
Expand Down Expand Up @@ -9739,7 +9754,7 @@ def revert(self):
values to properties and the config
"""
# Restore config
self.master.config.save_snapshot()
self.master.save_snapshot()
self.master.config.get()

# Restore properties
Expand Down
1 change: 0 additions & 1 deletion python3/IV_Swinger2_sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@
# standalone. The main() function creates a SimulatorDialog object with a
# basic ttk.Frame object as its parent and runs it.
#
from pathlib import Path
import re
from tkinter import ttk
import tkinter as tk
Expand Down
7 changes: 1 addition & 6 deletions python3/IV_Swinger_plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,7 @@ def data_points(self):
"""
csv = self.csv_filename
if not self._data_points:
try:
csv_lines = csv.read_text(encoding="utf-8").splitlines()
except IOError:
PrintAndOrLog.print_and_log_msg(self.logger,
f"Cannot read {csv}")
return []
csv_lines = csv.read_text(encoding="utf-8").splitlines()
for ii, line in enumerate(csv_lines):
if ii == 0:
expected_first_line = "Volts, Amps, Watts, Ohms"
Expand Down

0 comments on commit e10e79d

Please sign in to comment.