Skip to content

Commit 7f05bc5

Browse files
committed
fix: force utf-8 encoding on all text file reads/writes
Several read_text()/open() calls relied on the platform's default encoding (locale-dependent), which breaks on ASCII-locale systems (e.g. bioconda's Linux test env, UnicodeDecodeError on texts.toml) and mis-encodes on non-UTF-8 Windows locales (e.g. French cp1252).
1 parent 7d2abba commit 7f05bc5

6 files changed

Lines changed: 14 additions & 8 deletions

File tree

ms2rescore/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ def main(tims=False):
218218
json.loads(
219219
importlib.resources.files(package_data)
220220
.joinpath("config_default_tims.json")
221-
.read_text()
221+
.read_text(encoding="utf-8")
222222
)
223223
)
224224
if cli_args.config_file:

ms2rescore/config_parser.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,14 @@ def parse_configurations(configurations: list[dict | str | Path | Namespace]) ->
130130

131131
# Initialize CascadeConfig with validation schema and defaults
132132
config_schema = json.loads(
133-
importlib.resources.files(package_data).joinpath("config_schema.json").read_text()
133+
importlib.resources.files(package_data)
134+
.joinpath("config_schema.json")
135+
.read_text(encoding="utf-8")
134136
)
135137
config_default = json.loads(
136-
importlib.resources.files(package_data).joinpath("config_default.json").read_text()
138+
importlib.resources.files(package_data)
139+
.joinpath("config_default.json")
140+
.read_text(encoding="utf-8")
137141
)
138142
cascade_conf = CascadeConfig(
139143
validation_schema=config_schema,

ms2rescore/core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def rescore(configuration: dict, psm_list: PSMList | None = None) -> None:
3636
] # if no intermediate, takes full name
3737

3838
# Write full configuration including defaults to file
39-
with open(output_file_root + ".full-config.json", "w") as f:
39+
with open(output_file_root + ".full-config.json", "w", encoding="utf-8") as f:
4040
json.dump(configuration, f, indent=4)
4141

4242
logger.debug("Using %i of %i available CPUs.", int(config["processes"]), int(cpu_count()))
@@ -273,7 +273,7 @@ def rescore(configuration: dict, psm_list: PSMList | None = None) -> None:
273273

274274
def _write_feature_names(feature_names, output_file_root):
275275
"""Write feature names to file."""
276-
with open(output_file_root + ".feature_names.tsv", "w") as f:
276+
with open(output_file_root + ".feature_names.tsv", "w", encoding="utf-8") as f:
277277
f.write("feature_generator\tfeature_name\n")
278278
for fgen, fgen_features in feature_names.items():
279279
f.writelines(f"{fgen}\t{feature}\n" for feature in fgen_features)

ms2rescore/report/data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ def _read_config(path: Path) -> dict:
184184
logger.info("No configuration file found. Proceeding without it.")
185185
return {"ms2rescore": {}}
186186
try:
187-
return json.loads(path.read_text())
187+
return json.loads(path.read_text(encoding="utf-8"))
188188
except (json.JSONDecodeError, OSError):
189189
logger.warning("Could not read configuration file. Proceeding without it.")
190190
return {"ms2rescore": {}}

ms2rescore/report/generate.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
# charts (DeepLC, IM2Deep, MS²PIP) reuse the same color as the feature-generator overview charts.
3333
FEATURE_GENERATOR_COLORS = charts.FEATURE_GENERATOR_COLORS
3434

35-
TEXTS = tomllib.loads(importlib.resources.files(templates).joinpath("texts.toml").read_text())
35+
TEXTS = tomllib.loads(
36+
importlib.resources.files(templates).joinpath("texts.toml").read_text(encoding="utf-8")
37+
)
3638

3739

3840
def generate_report(

ms2rescore/report/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def read_feature_names(feature_names_path: Path | None) -> dict:
2828
return feature_names
2929

3030
try:
31-
with open(feature_names_path) as f:
31+
with open(feature_names_path, encoding="utf-8") as f:
3232
reader = DictReader(f, delimiter="\t")
3333
for line in reader:
3434
feature_names[line["feature_generator"]].append(line["feature_name"])

0 commit comments

Comments
 (0)