diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index b49735da..0a51eb77 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -19,37 +19,9 @@ repos:
- id: mixed-line-ending
- id: trailing-whitespace
-- repo: https://github.com/asottile/pyupgrade
- rev: v3.17.0
+- repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: "v0.6.8"
hooks:
- - id: pyupgrade
- args: ["--py37-plus"]
-
-- repo: https://github.com/pycqa/isort
- rev: 5.13.2
- hooks:
- - id: isort
-
-- repo: https://github.com/PyCQA/flake8
- rev: 7.1.1
- hooks:
- - id: flake8
-
-- repo: https://github.com/MarcoGorelli/absolufy-imports
- rev: v0.3.1
- hooks:
- - id: absolufy-imports
-
-- repo: https://github.com/psf/black-pre-commit-mirror
- rev: 24.8.0
- hooks:
- - id: black-jupyter
-
-- repo: https://github.com/nbQA-dev/nbQA
- rev: 1.8.7
- hooks:
- - id: nbqa-pyupgrade
- additional_dependencies: [pyupgrade==3.15.0]
- args: ["--py37-plus"]
- - id: nbqa-isort
- additional_dependencies: [isort==5.12.0]
+ - id: ruff
+ args: ["--fix", "--show-fixes"]
+ - id: ruff-format
diff --git a/examples/awkward_example.ipynb b/examples/awkward_example.ipynb
index c8a44978..c4e1ad74 100644
--- a/examples/awkward_example.ipynb
+++ b/examples/awkward_example.ipynb
@@ -6,9 +6,7 @@
"metadata": {},
"outputs": [],
"source": [
- "import awkward as ak\n",
"import hist\n",
- "import numpy as np\n",
"\n",
"import pylhe"
]
diff --git a/examples/parquet_cache.ipynb b/examples/parquet_cache.ipynb
index 75d7d03c..1657f97b 100644
--- a/examples/parquet_cache.ipynb
+++ b/examples/parquet_cache.ipynb
@@ -68,7 +68,8 @@
"\n",
" # need the file to exist\n",
" if not os.path.exists(filepath):\n",
- " raise FileNotFoundError(f\"Input LHE file {filepath} does not exist.\")\n",
+ " msg = f\"Input LHE file {filepath} does not exist.\"\n",
+ " raise FileNotFoundError(msg)\n",
"\n",
" # leave early without even thinking about cache if user doesn't want it\n",
" if not parquet_cache:\n",
diff --git a/examples/zpeak.ipynb b/examples/zpeak.ipynb
index 8c080daf..b114f2ef 100644
--- a/examples/zpeak.ipynb
+++ b/examples/zpeak.ipynb
@@ -20,8 +20,6 @@
},
"outputs": [],
"source": [
- "import math\n",
- "\n",
"import hist\n",
"\n",
"import pylhe"
@@ -386,8 +384,8 @@
],
"metadata": {
"kernelspec": {
- "name": "pythonjvsc74a57bd073182083f4e2a7a153b1c22bd64054bec714030b17650bd3a885c40287b848ca",
- "display_name": "Python 3.7.2 ('_env': venv)"
+ "display_name": "Python 3.7.2 ('_env': venv)",
+ "name": "pythonjvsc74a57bd073182083f4e2a7a153b1c22bd64054bec714030b17650bd3a885c40287b848ca"
},
"language_info": {
"codemirror_mode": {
diff --git a/pyproject.toml b/pyproject.toml
index 1422ec0c..89a08c75 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -47,8 +47,7 @@ dependencies = [
[project.optional-dependencies]
lint = [
- "black",
- "flake8",
+ "ruff",
]
test = [
"pydocstyle",
@@ -89,28 +88,34 @@ include = [
[tool.hatch.build.targets.wheel]
packages = ["src/pylhe"]
-[tool.black]
-line-length = 88
-include = '\.pyi?$'
-extend-exclude = '''
-/(
- \.git
- | .eggs
- | build
- | src/pylhe/_version.py
-)/
-'''
-
-[tool.isort]
-profile = "black"
-
-[tool.nbqa.config]
-black = "pyproject.toml"
-
-[tool.nbqa.mutate]
-black = 1
-pyupgrade = 1
-isort = 1
-
-[tool.nbqa.addopts]
-pyupgrade = ["--py36-plus"]
+[tool.ruff.lint]
+extend-select = [
+ "B", # flake8-bugbear
+ "I", # isort
+ "ARG", # flake8-unused-arguments
+ "C4", # flake8-comprehensions
+ "EM", # flake8-errmsg
+ "ICN", # flake8-import-conventions
+ "G", # flake8-logging-format
+ "PGH", # pygrep-hooks
+ "PIE", # flake8-pie
+ "PL", # pylint
+ "PT", # flake8-pytest-style
+ "RET", # flake8-return
+ "RUF", # Ruff-specific
+ "SIM", # flake8-simplify
+ "UP", # pyupgrade
+ "YTT", # flake8-2020
+ "EXE", # flake8-executable
+ "NPY", # NumPy specific rules
+ "PD", # pandas-vet
+ "FURB", # refurb
+ "PYI", # flake8-pyi
+]
+ignore = [
+ "PLR09", # Too many <...>
+ "PLR2004", # Magic value used in comparison
+ "ISC001", # Conflicts with formatter
+ "RUF012", # TODO: mutable class attributes
+ "SIM115", # TODO: use context manager for opening files
+]
diff --git a/src/pylhe/__init__.py b/src/pylhe/__init__.py
index 3d74f583..5f37498e 100644
--- a/src/pylhe/__init__.py
+++ b/src/pylhe/__init__.py
@@ -64,18 +64,16 @@ def tolhe(self, rwgt=True, weights=False):
str: The event as a string in LHE format.
"""
sweights = ""
- if rwgt:
- if self.weights:
- sweights = "\n"
- for k, v in self.weights.items():
- sweights += f" {v:11.4e}\n"
- sweights += "\n"
- if weights:
- if self.weights:
- sweights = "\n"
- for k, v in self.weights.items():
- sweights += f"{v:11.4e}\n"
- sweights += "\n"
+ if rwgt and self.weights:
+ sweights = "\n"
+ for k, v in self.weights.items():
+ sweights += f" {v:11.4e}\n"
+ sweights += "\n"
+ if weights and self.weights:
+ sweights = "\n"
+ for v in self.weights.values():
+ sweights += f"{v:11.4e}\n"
+ sweights += "\n"
return (
"\n"
@@ -156,9 +154,8 @@ class LHEEventInfo:
def __init__(self, **kwargs):
if set(kwargs.keys()) != set(self.fieldnames):
- raise RuntimeError(
- f"LHEEventInfo constructor expects fields {self.fieldnames}! Got {kwargs.keys()}."
- )
+ msg = f"LHEEventInfo constructor expects fields {self.fieldnames}! Got {kwargs.keys()}."
+ raise RuntimeError(msg)
for k, v in kwargs.items():
setattr(self, k, v)
@@ -198,9 +195,8 @@ class LHEParticle:
def __init__(self, **kwargs):
if set(kwargs.keys()) != set(self.fieldnames):
- raise RuntimeError(
- f"LHEParticle constructor expects fields {self.fieldnames}! Got {kwargs.keys()}."
- )
+ msg = f"LHEParticle constructor expects fields {self.fieldnames}! Got {kwargs.keys()}."
+ raise RuntimeError(msg)
for k, v in kwargs.items():
setattr(self, k, v)
@@ -224,7 +220,7 @@ def mothers(self):
first_idx = int(self.mother1) - 1
second_idx = int(self.mother2) - 1
return [
- self.event.particles[idx] for idx in {first_idx, second_idx} if idx >= 0
+ self.event.particles[idx] for idx in (first_idx, second_idx) if idx >= 0
]
@@ -238,13 +234,13 @@ def _indent(elem, level=0):
elem.text = i + " "
if not elem.tail or not elem.tail.strip():
elem.tail = i
- for elem in elem:
- _indent(elem, level + 1)
+ for inner_elem in elem:
+ _indent(inner_elem, level + 1)
+ elem = inner_elem
if not elem.tail or not elem.tail.strip():
elem.tail = i
- else:
- if level and (not elem.tail or not elem.tail.strip()):
- elem.tail = i
+ elif level and (not elem.tail or not elem.tail.strip()):
+ elem.tail = i
class LHEInit(dict):
@@ -264,9 +260,9 @@ def tolhe(self):
"""
# weightgroups to xml
root = ET.Element("initrwgt")
- for k, v in self["weightgroup"].items():
+ for _k, v in self["weightgroup"].items():
weightgroup_elem = ET.SubElement(root, "weightgroup", **v["attrib"])
- for key, value in v["weights"].items():
+ for _key, value in v["weights"].items():
weight_elem = ET.SubElement(
weightgroup_elem, "weight", **value["attrib"]
)
@@ -288,8 +284,7 @@ def tolhe(self):
def __getitem__(self, key):
if key not in self:
return self["initInfo"][key]
- else:
- return super().__getitem__(key)
+ return super().__getitem__(key)
# custom backwards compatibility set for dict
def __setitem__(self, key, value):
@@ -404,7 +399,7 @@ def read_lhe_init(filepath):
"""
initDict = {}
with _extract_fileobj(filepath) as fileobj:
- for event, element in ET.iterparse(fileobj, events=["start", "end"]):
+ for _event, element in ET.iterparse(fileobj, events=["start", "end"]):
if element.tag == "init":
data = element.text.split("\n")[1:-1]
initDict["initInfo"] = LHEInitInfo.fromstring(data[0])
@@ -453,7 +448,7 @@ def read_lhe_init(filepath):
def read_lhe(filepath):
try:
with _extract_fileobj(filepath) as fileobj:
- for event, element in ET.iterparse(fileobj, events=["end"]):
+ for _event, element in ET.iterparse(fileobj, events=["end"]):
if element.tag == "event":
data = element.text.strip().split("\n")
eventdata, particles = data[0], data[1:]
@@ -495,7 +490,7 @@ def read_lhe_with_attributes(filepath):
index_map = None
try:
with _extract_fileobj(filepath) as fileobj:
- for event, element in ET.iterparse(fileobj, events=["end"]):
+ for _event, element in ET.iterparse(fileobj, events=["end"]):
if element.tag == "event":
eventdict = {}
data = element.text.strip().split("\n")
@@ -517,7 +512,7 @@ def read_lhe_with_attributes(filepath):
read_lhe_init(filepath)
)
for i, w in enumerate(sub.text.split()):
- if w and not index_map[i] in eventdict["weights"]:
+ if w and index_map[i] not in eventdict["weights"]:
eventdict["weights"][index_map[i]] = float(w)
if sub.tag == "rwgt":
for r in sub:
@@ -570,7 +565,7 @@ def write_lhe_file(lheinit, lheevents, filepath, gz=False, rwgt=True, weights=Fa
Write the LHE file.
"""
# if filepath suffix is gz, write as gz
- if filepath.endswith(".gz") or filepath.endswith(".gzip") or gz:
+ if filepath.endswith((".gz", ".gzip")) or gz:
with gzip.open(filepath, "wt") as f:
f.write(write_lhe_string(lheinit, lheevents, rwgt=rwgt, weights=weights))
else:
diff --git a/tests/test_lhe_reader.py b/tests/test_lhe_reader.py
index c58e20ff..653c7ee6 100644
--- a/tests/test_lhe_reader.py
+++ b/tests/test_lhe_reader.py
@@ -17,7 +17,7 @@
)
TEST_FILE_LHE_RWGT_WGT = skhep_testdata.data_path("pylhe-testfile-powheg-box-v2-W.lhe")
TEST_FILES_LHE_POWHEG = [
- skhep_testdata.data_path("pylhe-testfile-powheg-box-v2-%s.lhe" % (proc))
+ skhep_testdata.data_path(f"pylhe-testfile-powheg-box-v2-{proc}.lhe")
for proc in ["Z", "W", "Zj", "trijet", "directphoton", "hvq"]
]
@@ -28,23 +28,21 @@ def testdata_gzip_file():
tmp_path = Path(NamedTemporaryFile().name)
# create what is basically pylhe-testfile-pr29.lhe.gz
- with open(test_data, "rb") as readfile:
- with gzip.open(tmp_path, "wb") as writefile:
- shutil.copyfileobj(readfile, writefile)
+ with open(test_data, "rb") as readfile, gzip.open(tmp_path, "wb") as writefile:
+ shutil.copyfileobj(readfile, writefile)
yield tmp_path
# teardown
os.remove(tmp_path)
-def test_gzip_open(tmpdir, testdata_gzip_file):
+def test_gzip_open(testdata_gzip_file):
assert pylhe._extract_fileobj(TEST_FILE_LHE_v1)
assert pylhe._extract_fileobj(testdata_gzip_file)
# Needs path-like object, not a fileobj
- with pytest.raises(TypeError):
- with open(TEST_FILE_LHE_v1, "rb") as fileobj:
- pylhe._extract_fileobj(fileobj)
+ with pytest.raises(TypeError), open(TEST_FILE_LHE_v1, "rb") as fileobj:
+ pylhe._extract_fileobj(fileobj)
with open(TEST_FILE_LHE_v1, "rb") as fileobj:
assert isinstance(pylhe._extract_fileobj(TEST_FILE_LHE_v1), type(fileobj))
diff --git a/tests/test_lhe_writer.py b/tests/test_lhe_writer.py
index d85eeb87..667b5a74 100644
--- a/tests/test_lhe_writer.py
+++ b/tests/test_lhe_writer.py
@@ -9,7 +9,7 @@
)
TEST_FILE_LHE_RWGT_WGT = skhep_testdata.data_path("pylhe-testfile-powheg-box-v2-W.lhe")
TEST_FILES_LHE_POWHEG = [
- skhep_testdata.data_path("pylhe-testfile-powheg-box-v2-%s.lhe" % (proc))
+ skhep_testdata.data_path(f"pylhe-testfile-powheg-box-v2-{proc}.lhe")
for proc in ["Z", "W", "Zj", "trijet", "directphoton", "hvq"]
]