Skip to content

Commit

Permalink
[MAINT] use ruff (#109)
Browse files Browse the repository at this point in the history
* use ruff

* fix SIM

* fix PATH error flagged by ruff

* fix E

* fix B008

* fix B028

* fix PLR

* fix pandas error

* Apply suggestions from code review
  • Loading branch information
Remi-Gau authored Nov 10, 2024
1 parent a988673 commit d207212
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 106 deletions.
19 changes: 0 additions & 19 deletions .flake8

This file was deleted.

31 changes: 8 additions & 23 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,6 @@ repos:
- id: trailing-whitespace
- id: check-toml

- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
args: [--profile, black]

- repo: https://github.com/asottile/pyupgrade
rev: v3.19.0
hooks:
- id: pyupgrade
args: [--py39-plus]

- repo: https://github.com/psf/black
rev: 24.10.0
hooks:
- id: black
args: [--config, pyproject.toml]

- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
Expand All @@ -59,9 +41,12 @@ repos:
additional_dependencies: [types-requests, types-PyYAML, numpy]
args: [--config-file=pyproject.toml]

- repo: https://github.com/pyCQA/flake8
rev: 7.1.1
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.2
hooks:
- id: flake8
args: [--config, .flake8, --verbose]
additional_dependencies: [flake8-docstrings, flake8-use-fstring]
# Run the linter.
- id: ruff
# args: [--statistics]
args: [--fix, --show-fixes]
# Run the formatter.
- id: ruff-format
13 changes: 7 additions & 6 deletions eye2bids/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class BasePhysioEventsJson(dict[str, Any]):
two_eyes: bool

def __init__(self, metadata: None | dict[str, Any] = None) -> None:

self["Columns"] = ["onset", "duration", "trial_type", "blink", "message"]
self["Description"] = "Messages logged by the measurement device"
self["ForeignIndexColumn"] = "timestamp"
Expand Down Expand Up @@ -69,9 +68,10 @@ def write(
) -> None:
"""Write to json."""
content = {key: value for key, value in self.items() if self[key] is not None}
with open(output_dir / self.output_filename(recording=recording), "w") as outfile:
with (output_dir / self.output_filename(recording=recording)).open(
"w"
) as outfile:
json.dump(content, outfile, indent=4)
# e2b_log.info(f"file generated: {self.output_filename(recording=recording)}")


class BaseEventsJson(dict[str, Any]):
Expand Down Expand Up @@ -112,7 +112,7 @@ def write(
self[key] = value

content = {key: value for key, value in self.items() if self[key] is not None}
with open(output_dir / self.output_filename(), "w") as outfile:
with (output_dir / self.output_filename()).open("w") as outfile:
json.dump(content, outfile, indent=4)


Expand All @@ -125,7 +125,6 @@ class BasePhysioJson(dict[str, Any]):
has_calibration: bool

def __init__(self, manufacturer: str, metadata: dict[str, Any] | None = None) -> None:

self["Manufacturer"] = manufacturer
self["PhysioType"] = "eyetrack"

Expand Down Expand Up @@ -199,5 +198,7 @@ def write(
self[key] = value

content = {key: value for key, value in self.items() if self[key] is not None}
with open(output_dir / self.output_filename(recording=recording), "w") as outfile:
with (output_dir / self.output_filename(recording=recording)).open(
"w"
) as outfile:
json.dump(content, outfile, indent=4)
10 changes: 2 additions & 8 deletions eye2bids/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,8 @@ def set_verbosity(verbosity: int | list[int]) -> None:
"""Set verbosity level."""
if isinstance(verbosity, list):
verbosity = verbosity[0]
if verbosity == 0:
e2b_log.setLevel("ERROR")
elif verbosity == 1:
e2b_log.setLevel("WARNING")
elif verbosity == 2:
e2b_log.setLevel("INFO")
elif verbosity == 3:
e2b_log.setLevel("DEBUG")
verbosity_map = {0: "ERROR", 1: "WARNING", 2: "INFO", 3: "DEBUG"}
e2b_log.setLevel(verbosity_map[verbosity])


def cli(argv: Sequence[str] = sys.argv) -> None:
Expand Down
23 changes: 10 additions & 13 deletions eye2bids/edf2bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ def _extract_CalibrationCount(df: pd.DataFrame, two_eyes: bool) -> int:


def _extract_CalibrationPosition(df: pd.DataFrame) -> list[list[list[int]]]:

calibration_df = df[df[2] == "VALIDATE"]
calibration_df[5] = pd.to_numeric(calibration_df[5], errors="coerce")

Expand All @@ -175,7 +174,6 @@ def _extract_CalibrationPosition(df: pd.DataFrame) -> list[list[list[int]]]:
CalibrationPosition: Any = [[[]] * nb_calibration_postions]

for i_pos in range(nb_calibration_postions):

results_for_this_position = calibration_df[calibration_df[5] == i_pos]

for i, calibration in enumerate(results_for_this_position.iterrows()):
Expand Down Expand Up @@ -256,12 +254,13 @@ def _extract_SamplingFrequency(df: pd.DataFrame) -> int:

def _extract_RecordedEye(df: pd.DataFrame) -> str | list[str]:
eye = df[df[2] == "RECCFG"].iloc[0:1, 5:6].to_string(header=False, index=False)
if eye == "L":
return "Left"
elif eye == "R":
return "Right"
elif eye == "LR":
return ["Left", "Right"]
recorded_eye_map: dict[str, str | list[str]] = {
"L": "Left",
"R": "Right",
"LR": ["Left", "Right"],
}
if eye in recorded_eye_map:
return recorded_eye_map[eye]
return ""


Expand Down Expand Up @@ -313,7 +312,7 @@ def _extract_StopTime(events: list[str]) -> int:


def _load_asc_file(events_asc_file: str | Path) -> list[str]:
with open(events_asc_file) as f:
with Path(events_asc_file).open() as f:
return f.readlines()


Expand Down Expand Up @@ -425,7 +424,7 @@ def generate_physio_json(
if metadata_file is None:
metadata = {}
else:
with open(metadata_file) as f:
with Path(metadata_file).open() as f:
metadata = yaml.load(f, Loader=SafeLoader)

events = _load_asc_file(events_asc_file)
Expand Down Expand Up @@ -463,7 +462,6 @@ def generate_physio_json(
}

if base_json.has_validation:

if CalibrationPosition := _extract_CalibrationPosition(df_ms_reduced):
base_json["CalibrationCount"] = _extract_CalibrationCount(
df_ms_reduced, two_eyes=base_json.two_eyes
Expand Down Expand Up @@ -545,7 +543,7 @@ def edf2bids(
if metadata_file is None:
metadata = {}
else:
with open(metadata_file) as f:
with metadata_file.open() as f:
metadata = yaml.load(f, Loader=SafeLoader)

events_json = BaseEventsJson(metadata)
Expand Down Expand Up @@ -596,7 +594,6 @@ def edf2bids(
e2b_log.info(f"file generated: {output_filename_eye1}")

if _2eyesmode(df_ms_reduced):

output_filename_eye2 = generate_output_filename(
output_dir=output_dir,
input_file=input_file,
Expand Down
4 changes: 2 additions & 2 deletions eye2bids/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

from rich.logging import RichHandler

FORMAT = "%(message)s"


def eye2bids_logger(log_level: str = "INFO") -> logging.Logger:
"""Create a logger for the eye2bids package."""
FORMAT = "%(message)s"

logging.basicConfig(
level=log_level,
format=FORMAT,
Expand Down
69 changes: 63 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,6 @@ packages = ["eye2bids"]
[tool.hatch.version]
source = "vcs"

[tool.isort]
combine_as_imports = true
line_length = 90
profile = "black"
skip_gitignore = true

[tool.mypy]
check_untyped_defs = true
disallow_any_generics = true
Expand Down Expand Up @@ -121,3 +115,66 @@ module = [
addopts = "-ra --strict-config --strict-markers -q -vv --cov eye2bids --durations=0"
norecursedirs = "data"
testpaths = ["tests/"]

[tool.ruff]
include = ["pyproject.toml", "eye2bids/**/*.py", "tools/**/*.py"]
indent-width = 4
line-length = 90

[tool.ruff.format]
docstring-code-format = true
docstring-code-line-length = "dynamic"
indent-style = "space"
line-ending = "auto"
quote-style = "double"
skip-magic-trailing-comma = false

[tool.ruff.lint]
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
fixable = ["ALL"]
ignore = [
"D205",
"N802",
"N806"
]
# List of all the ruff rules (includes why the rule matters)
# https://docs.astral.sh/ruff/rules/
select = [
"ARG",
"B",
"C4",
"C90",
"D",
"E",
"ERA",
"F",
"FLY",
"I",
"N",
"NPY",
"PERF",
"PTH",
"PD",
"PLR",
"RUF",
"SIM",
"UP",
"W"
]
unfixable = []

[tool.ruff.lint.mccabe]
max-complexity = 21

[tool.ruff.lint.per-file-ignores]
"**/{tests}/*" = ["D100", "D103", "PLR2004"]
"__init__.py" = ["D100", "D104"]

[tool.ruff.lint.pydocstyle]
convention = "numpy"

[tool.ruff.lint.pylint]
# https://docs.astral.sh/ruff/settings/#lint_pylint_max-branches
max-branches = 17
# https://docs.astral.sh/ruff/settings/#lint_pylint_max-statements
max-statements = 71
16 changes: 10 additions & 6 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,24 @@ def data_dir() -> Path:
return Path(__file__).parent / "data"


def asc_test_files(input_dir: Path = data_dir(), suffix: str = "*") -> list[Path]:
def asc_test_files(input_dir: Path | None = None, suffix: str = "*") -> list[Path]:
if input_dir is None:
input_dir = data_dir()
files = input_dir.glob(f"**/{suffix}.asc")
tmp = list(files)
if not tmp:
warn(f"No .asc file found in: {input_dir}.")
warn(f"No .asc file found in: {input_dir}.", stacklevel=2)
return tmp


def edf_test_files(input_dir: Path = data_dir()) -> list[Path]:
def edf_test_files(input_dir: Path | None = None) -> list[Path]:
if input_dir is None:
input_dir = data_dir()
files = list(input_dir.glob("**/*.edf"))
EDF_files = list(input_dir.glob("**/*.EDF"))
files.extend(EDF_files)
edf_files = list(input_dir.glob("**/*.EDF"))
files.extend(edf_files)
if not files:
warn(f"No EDF file found in: {input_dir}")
warn(f"No EDF file found in: {input_dir}", stacklevel=2)
return files


Expand Down
1 change: 0 additions & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ def root_dir() -> Path:
@pytest.mark.parametrize("output_dir", [data_dir() / "output", None])
@pytest.mark.parametrize("use_relative_path", [False, True])
def test_edf_cli(use_relative_path, output_dir, eyelink_test_data_dir):

metadata_file = data_dir() / "metadata.yml"

input_dir = eyelink_test_data_dir / "satf"
Expand Down
Loading

0 comments on commit d207212

Please sign in to comment.