Skip to content

Commit 7d2abba

Browse files
authored
Merge pull request #277 from CompOmics/fix/ruff-errors
Resolve ruff linting errors
2 parents 73fc94d + e4ae8dc commit 7d2abba

28 files changed

Lines changed: 216 additions & 236 deletions

ms2rescore/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
module="pyopenms",
2828
)
2929

30-
from ms2rescore._version import get_version # noqa: E402
31-
from ms2rescore.config_parser import parse_configurations # noqa: E402
32-
from ms2rescore.core import rescore # noqa: E402
30+
from ms2rescore._version import get_version
31+
from ms2rescore.config_parser import parse_configurations
32+
from ms2rescore.core import rescore
3333

3434
__version__ = get_version()

ms2rescore/__main__.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import sys
99
from datetime import datetime
1010
from pathlib import Path
11-
from typing import Union
1211

1312
from rich.console import Console
1413
from rich.logging import RichHandler
@@ -23,7 +22,7 @@
2322
try:
2423
import matplotlib.pyplot as plt
2524

26-
plt.set_loglevel("warning")
25+
plt.set_loglevel("WARNING")
2726
except ImportError:
2827
pass
2928

@@ -164,7 +163,7 @@ def _argument_parser() -> argparse.ArgumentParser:
164163
return parser
165164

166165

167-
def _setup_logging(passed_level: str, log_file: Union[str, Path]):
166+
def _setup_logging(passed_level: str, log_file: str | Path):
168167
"""Setup logging for writing to log file and Rich Console."""
169168
if passed_level not in LOG_MAPPING:
170169
raise MS2RescoreConfigurationError(
@@ -190,7 +189,7 @@ def inner(*args, **kwargs):
190189
return_value = fnc(*args, **kwargs)
191190

192191
# Add timestamp to profiler output filename
193-
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
192+
timestamp = datetime.now().astimezone().strftime("%Y%m%d_%H%M%S")
194193
profile_filename = f"{filepath}.profile_{timestamp}.prof"
195194
profiler.dump_stats(profile_filename)
196195
LOGGER.info(f"Profile data written to: {profile_filename}")
@@ -255,8 +254,8 @@ def main(tims=False):
255254
profiled_rescore(configuration=config)
256255
else:
257256
rescore(configuration=config)
258-
except Exception as e:
259-
LOGGER.exception(e)
257+
except Exception:
258+
LOGGER.exception("Unhandled error during rescoring")
260259
sys.exit(1)
261260
finally:
262261
CONSOLE.save_html(config["ms2rescore"]["output_path"] + ".log.html")

ms2rescore/_ristretto_utils.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
"""
1010

1111
import logging
12-
from typing import Dict, Optional, Set
1312

1413
import numpy as np
1514
import pandas as pd
@@ -25,7 +24,7 @@
2524

2625
def _build_features_dataframe(
2726
psm_list: PSMList,
28-
feature_names: Set[str],
27+
feature_names: set[str],
2928
lower_score_is_better: bool,
3029
) -> pd.DataFrame:
3130
"""
@@ -71,9 +70,9 @@ def _trim_and_evaluate(
7170
max_rank: int,
7271
*,
7372
run_col: str,
74-
peptide_col: Optional[str],
75-
protein_col: Optional[str],
76-
decoy_pattern: Optional[str],
73+
peptide_col: str | None,
74+
protein_col: str | None,
75+
decoy_pattern: str | None,
7776
) -> RescoreResult:
7877
"""
7978
Compete to at most ``max_rank`` PSMs per spectrum, then compute q-values/PEP/rollups.
@@ -128,7 +127,7 @@ def _is_original_psm(psm) -> bool:
128127
return bool(value)
129128

130129

131-
def evaluate_before(psm_list: PSMList, config: Dict) -> RescoreResult:
130+
def evaluate_before(psm_list: PSMList, config: dict) -> RescoreResult:
132131
"""
133132
Evaluate the PSMs' current (pre-rescoring) score with ristretto, for report baselines.
134133
@@ -159,7 +158,7 @@ def evaluate_before(psm_list: PSMList, config: Dict) -> RescoreResult:
159158
)
160159

161160

162-
def evaluate_before_from_provenance(psm_list: PSMList, config: Dict) -> RescoreResult:
161+
def evaluate_before_from_provenance(psm_list: PSMList, config: dict) -> RescoreResult:
163162
"""
164163
Rebuild the "before" ``RescoreResult`` for standalone report regeneration.
165164
@@ -181,7 +180,7 @@ def evaluate_before_from_provenance(psm_list: PSMList, config: Dict) -> RescoreR
181180
return evaluate_before(psm_list, config)
182181

183182

184-
def evaluate_after_from_psm_list(psm_list: PSMList, config: Dict) -> RescoreResult:
183+
def evaluate_after_from_psm_list(psm_list: PSMList, config: dict) -> RescoreResult:
185184
"""
186185
Rebuild the "after" ``RescoreResult`` for standalone report regeneration.
187186

ms2rescore/_utils.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,22 @@
44
import os
55
from glob import glob
66
from pathlib import Path
7-
from typing import Optional, Union
87

98
import numpy as np
109
import pandas as pd
1110
from ms2rescore_rs import is_supported_file_type
1211
from psm_utils import PSMList
1312

14-
from ms2rescore.exceptions import MS2RescoreConfigurationError
1513
from ms2rescore._ristretto_utils import _is_original_psm
14+
from ms2rescore.exceptions import MS2RescoreConfigurationError
1615

1716
logger = logging.getLogger(__name__)
1817

1918

2019
def infer_spectrum_path(
21-
configured_path: Union[str, Path, None],
22-
run_name: Optional[str] = None,
23-
) -> Union[str, Path]:
20+
configured_path: str | Path | None,
21+
run_name: str | None = None,
22+
) -> str | Path:
2423
"""
2524
Infer spectrum path from passed path and expected filename (e.g. from PSM file).
2625

ms2rescore/_version.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@
88
import importlib.metadata
99
import json
1010
import logging
11+
import tomllib as toml
1112
from pathlib import Path
12-
from typing import Dict, Optional, Tuple, Union
1313
from urllib.error import HTTPError, URLError
1414
from urllib.request import Request, urlopen
1515

1616
from packaging.version import Version
1717

18-
import tomllib as toml
19-
2018
from ms2rescore.exceptions import MS2RescoreError
2119

2220
LOGGER = logging.getLogger(__name__)
@@ -28,17 +26,16 @@
2826
class UpdateCheckError(MS2RescoreError):
2927
"""An error occurred while checking for software updates."""
3028

31-
pass
3229

3330

34-
def _version_from_metadata() -> Optional[Version]:
31+
def _version_from_metadata() -> Version | None:
3532
try:
3633
return Version(importlib.metadata.version("ms2rescore"))
3734
except importlib.metadata.PackageNotFoundError:
3835
return None
3936

4037

41-
def _version_from_pyproject() -> Optional[Version]:
38+
def _version_from_pyproject() -> Version | None:
4239
pyproject = Path(__file__).resolve().parents[1] / "pyproject.toml"
4340
if not pyproject.is_file():
4441
return None
@@ -56,7 +53,7 @@ def _version_from_pyproject() -> Optional[Version]:
5653
return None
5754

5855

59-
def _get_latest_version(timeout_seconds: float) -> Tuple[Version, Optional[str]]:
56+
def _get_latest_version(timeout_seconds: float) -> tuple[Version, str | None]:
6057
"""Check GitHub latest release and return the version string."""
6158
# Prepare GitHub API request
6259
url = f"https://api.github.com/repos/{_GITHUB_REPO}/releases/latest"
@@ -95,13 +92,13 @@ def get_version() -> str:
9592

9693

9794
def check_for_update(
98-
timeout_seconds: Optional[float] = None,
99-
) -> Dict[str, Optional[Union[str, bool]]]:
95+
timeout_seconds: float | None = None,
96+
) -> dict[str, str | bool | None]:
10097
"""Check GitHub latest release and report whether an update exists."""
10198
timeout_seconds = timeout_seconds or _GITHUB_TIMEOUT_SECONDS
10299

103100
# Initialize result dictionary
104-
result: Dict[str, Optional[Union[str, bool]]] = {
101+
result: dict[str, str | bool | None] = {
105102
"update_available": False,
106103
"current_version": None,
107104
"latest_version": None,
@@ -128,5 +125,6 @@ def check_for_update(
128125
result["update_available"] = latest_version > current_version
129126
except Exception:
130127
# If current_version can't be parsed, don't treat as updateable
128+
LOGGER.exception("Update check failed")
131129
result["update_available"] = False
132130
return result

ms2rescore/config_parser.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44
import json
55
import multiprocessing as mp
66
import re
7+
import tomllib
78
from argparse import Namespace
89
from pathlib import Path
9-
from typing import Dict, List, Union
10-
11-
import tomllib
1210

1311
from cascade_config import CascadeConfig
1412

@@ -36,7 +34,7 @@ def _parse_output_path(configured_path, psm_file_path):
3634
return (Path(psm_file_path).parent / psm_file_stem).as_posix()
3735

3836

39-
def _validate_filenames(config: Dict) -> Dict:
37+
def _validate_filenames(config: dict) -> dict:
4038
"""Validate and infer input/output filenames."""
4139
# psm_file should be provided
4240
if not config["ms2rescore"]["psm_file"]:
@@ -74,7 +72,7 @@ def _validate_filenames(config: Dict) -> Dict:
7472
return config
7573

7674

77-
def _validate_processes(config: Dict) -> Dict:
75+
def _validate_processes(config: dict) -> dict:
7876
"""Validate requested processes with available cpu count."""
7977
n_available = mp.cpu_count()
8078
if (config["ms2rescore"]["processes"] == -1) or (
@@ -84,7 +82,7 @@ def _validate_processes(config: Dict) -> Dict:
8482
return config
8583

8684

87-
def _validate_regular_expressions(config: Dict) -> Dict:
85+
def _validate_regular_expressions(config: dict) -> dict:
8886
"""Validate regular expressions in configuration."""
8987
for field in [
9088
"psm_id_pattern",
@@ -113,7 +111,7 @@ def _validate_regular_expressions(config: Dict) -> Dict:
113111
return config
114112

115113

116-
def parse_configurations(configurations: List[Union[dict, str, Path, Namespace]]) -> Dict:
114+
def parse_configurations(configurations: list[dict | str | Path | Namespace]) -> dict:
117115
"""
118116
Parse and validate MS²Rescore configuration files and CLI arguments.
119117
@@ -150,19 +148,20 @@ def parse_configurations(configurations: List[Union[dict, str, Path, Namespace]]
150148
continue
151149
if isinstance(config, dict):
152150
cascade_conf.add_dict(config)
153-
elif isinstance(config, str) or isinstance(config, Path):
151+
elif isinstance(config, (str, Path)):
154152
if Path(config).suffix.lower() == ".json":
155153
cascade_conf.add_json(config)
156154
elif Path(config).suffix.lower() == ".toml":
157-
cascade_conf.add_dict(dict(tomllib.load(Path(config).open("rb"))))
155+
with Path(config).open("rb") as f:
156+
cascade_conf.add_dict(dict(tomllib.load(f)))
158157
else:
159158
raise MS2RescoreConfigurationError(
160159
"Unknown file extension for configuration file. Should be `json` or `toml`."
161160
)
162161
elif isinstance(config, Namespace):
163162
cascade_conf.add_namespace(config, subkey="ms2rescore")
164163
else:
165-
raise ValueError(
164+
raise TypeError(
166165
"Configuration should be a dictionary, argparse Namespace, or path to a "
167166
"configuration file."
168167
)

ms2rescore/core.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import json
22
import logging
33
from multiprocessing import cpu_count
4-
from typing import Dict, Optional
54

65
import psm_utils.io
76
from psm_utils import PSMList
@@ -16,7 +15,7 @@
1615
logger = logging.getLogger(__name__)
1716

1817

19-
def rescore(configuration: Dict, psm_list: Optional[PSMList] = None) -> None:
18+
def rescore(configuration: dict, psm_list: PSMList | None = None) -> None:
2019
"""
2120
Run full MS²Rescore workflow with passed configuration.
2221
@@ -55,11 +54,11 @@ def rescore(configuration: Dict, psm_list: Optional[PSMList] = None) -> None:
5554
)
5655

5756
# Define feature names; get existing feature names from PSM file
58-
feature_names = dict()
57+
feature_names = {}
5958
psm_list_feature_names = {
6059
feature_name
6160
for psm_list_features in psm_list["rescoring_features"]
62-
for feature_name in psm_list_features.keys()
61+
for feature_name in psm_list_features
6362
}
6463
feature_names["psm_file"] = psm_list_feature_names
6564
logger.debug(
@@ -81,7 +80,7 @@ def rescore(configuration: Dict, psm_list: Optional[PSMList] = None) -> None:
8180
# Add missing precursor info from spectrum file if needed
8281
required_ms_data = {
8382
ms_data
84-
for fgen_name in config["feature_generators"].keys()
83+
for fgen_name in config["feature_generators"]
8584
if fgen_name not in skip_fgens
8685
for ms_data in FEATURE_GENERATORS[fgen_name].required_ms_data
8786
}
@@ -208,7 +207,7 @@ def rescore(configuration: Dict, psm_list: Optional[PSMList] = None) -> None:
208207

209208
# Rename PSMs to USIs if requested, reusing the lookup built above
210209
if config["rename_to_usi"]:
211-
logging.debug(f"Creating USIs for {len(psm_list)} PSMs")
210+
logger.debug(f"Creating USIs for {len(psm_list)} PSMs")
212211
psm_list["spectrum_id"] = [usi_by_native_id[(psm.run, psm.spectrum_id)] for psm in psm_list]
213212

214213
# Rescore PSMs
@@ -268,14 +267,13 @@ def rescore(configuration: Dict, psm_list: Optional[PSMList] = None) -> None:
268267
fdr_threshold=config["report_fdr"],
269268
)
270269
generate.generate_report(output_file_root, report_data)
271-
except exceptions.ReportGenerationError as e:
272-
logger.exception(e)
270+
except exceptions.ReportGenerationError:
271+
logger.exception("Report generation failed")
273272

274273

275274
def _write_feature_names(feature_names, output_file_root):
276275
"""Write feature names to file."""
277276
with open(output_file_root + ".feature_names.tsv", "w") as f:
278277
f.write("feature_generator\tfeature_name\n")
279278
for fgen, fgen_features in feature_names.items():
280-
for feature in fgen_features:
281-
f.write(f"{fgen}\t{feature}\n")
279+
f.writelines(f"{fgen}\t{feature}\n" for feature in fgen_features)

ms2rescore/exceptions.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,46 +4,38 @@
44
class MS2RescoreError(Exception):
55
"""Generic MS2Rescore error."""
66

7-
pass
87

98

109
class MS2RescoreConfigurationError(MS2RescoreError):
1110
"""Invalid MS2Rescore configuration."""
1211

13-
pass
1412

1513

1614
class IDFileParsingError(MS2RescoreError):
1715
"""Identification file parsing error."""
1816

19-
pass
2017

2118

2219
class ModificationParsingError(IDFileParsingError):
2320
"""Identification file parsing error."""
2421

25-
pass
2622

2723

2824
class MissingValuesError(MS2RescoreError):
2925
"""Missing values in PSMs and/or spectra."""
3026

31-
pass
3227

3328

3429
class ReportGenerationError(MS2RescoreError):
3530
"""Error while generating report."""
3631

37-
pass
3832

3933

4034
class RescoringError(MS2RescoreError):
4135
"""Error while rescoring PSMs."""
4236

43-
pass
4437

4538

4639
class ParseSpectrumError(MS2RescoreError):
4740
"""Error while parsing spectrum files."""
4841

49-
pass

0 commit comments

Comments
 (0)