Merge pull request #16 from HideyoshiNakazone/chore/switches-to-ruff

chore: switches from black and isort to ruff
This commit is contained in:
2026-02-26 17:48:33 -03:00
committed by GitHub
20 changed files with 286 additions and 77 deletions

184
.gitignore vendored
View File

@@ -1,20 +1,184 @@
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
.vscode/settings.json
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
#uv.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
.pdm.toml
.pdm-python
.pdm-build/
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# Ruff stuff:
.ruff_cache/
# PyPI configuration file
.pypirc
# IDE
.idea/
.vscode
*.ljc
*.log
*.log.backup
simfiles/*
.vscode/*
.idea/*
*.pkl
*.xyz
dist/

View File

@@ -1,13 +1,9 @@
repos:
- repo: https://github.com/psf/black
rev: 24.4.2
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.14.7
hooks:
- id: black
args: [--config=pyproject.toml]
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
files: "\\.(py)$"
args: [--settings-path=pyproject.toml]
# Run the linter.
- id: ruff
# Run the formatter.
- id: ruff-format

View File

@@ -2,6 +2,7 @@ from diceplayer.shared.utils.logger import Logger
from importlib import metadata
VERSION = metadata.version("diceplayer")
logger = Logger(__name__)

View File

@@ -1,10 +1,6 @@
from diceplayer.shared.utils.dataclass_protocol import Dataclass
from pydantic import BaseModel, Field
from typing_extensions import List, Literal
from dataclasses import dataclass, fields
class DiceConfig(BaseModel):
"""

View File

@@ -1,10 +1,6 @@
from diceplayer.shared.utils.dataclass_protocol import Dataclass
from pydantic import BaseModel, Field
from typing_extensions import Literal
from dataclasses import dataclass, fields
class GaussianConfig(BaseModel):
"""

View File

@@ -1,13 +1,12 @@
from diceplayer.config.dice_config import DiceConfig
from diceplayer.config.gaussian_config import GaussianConfig
from diceplayer.shared.utils.dataclass_protocol import Dataclass
from pydantic import BaseModel, Field, field_validator, model_validator
from pydantic import BaseModel, Field, model_validator
from typing_extensions import Self
from dataclasses import dataclass, fields
from pathlib import Path
MIN_STEP = 20000

View File

@@ -1,25 +1,23 @@
from diceplayer import VERSION, logger
from diceplayer.config.dice_config import DiceConfig
from diceplayer.config.gaussian_config import GaussianConfig
from diceplayer.config.player_config import PlayerConfig
from diceplayer.shared.environment.atom import Atom
from diceplayer.shared.environment.molecule import Molecule
from diceplayer.shared.environment.system import System
from diceplayer.shared.interface.dice_interface import DiceInterface
from diceplayer.shared.interface.gaussian_interface import GaussianInterface
from diceplayer.shared.utils.dataclass_protocol import Dataclass
from diceplayer.shared.utils.misc import weekday_date_time
from diceplayer.shared.utils.ptable import atomsymb
import yaml
from pydantic import BaseModel
from typing_extensions import Tuple, Type
from typing_extensions import Tuple
import os
import pickle
import sys
from pathlib import Path
ENV = ["OMP_STACKSIZE"]
@@ -413,7 +411,7 @@ class Player:
with open("latest-step.pkl", "wb") as pickle_file:
pickle.dump((self.config, self.system, cycle), pickle_file)
except Exception:
raise RuntimeError(f"Could not save pickle file latest-step.pkl.")
raise RuntimeError("Could not save pickle file latest-step.pkl.")
@staticmethod
def load_run_from_pickle() -> Tuple[PlayerConfig, System, int]:

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
from typing_extensions import TYPE_CHECKING
if TYPE_CHECKING:
from nptyping import Float, NDArray, Shape
@@ -319,7 +320,7 @@ class Molecule:
self.com[0], self.com[1], self.com[2]
)
)
inertia = self.inertia_tensor()
self.inertia_tensor()
evals, evecs = self.principal_axes()
logger.info(

View File

@@ -1,11 +1,10 @@
from diceplayer import logger
from diceplayer.shared.environment.molecule import Molecule
from diceplayer.shared.utils.misc import BOHR2ANG
from diceplayer.shared.utils.ptable import atomsymb
import numpy as np
from numpy import linalg
from typing_extensions import List, TextIO, Tuple
from typing_extensions import List, Tuple
import math
from copy import deepcopy
@@ -92,8 +91,10 @@ class System:
try:
evals, evecs = linalg.eigh(rr)
except:
raise RuntimeError("Error: diagonalization of RR matrix did not converge")
except Exception as err:
raise RuntimeError(
"Error: diagonalization of RR matrix did not converge"
) from err
a1 = evecs[:, 2].T
a2 = evecs[:, 1].T

View File

@@ -1 +1,4 @@
from .__interface import Interface
__all__ = ["Interface"]

View File

@@ -17,6 +17,7 @@ import time
from multiprocessing import Process, connection
from pathlib import Path
DICE_END_FLAG: Final[str] = "End of simulation"
DICE_FLAG_LINE: Final[int] = -2
UMAANG3_TO_GCM3: Final[float] = 1.6605
@@ -206,10 +207,10 @@ class DiceInterface(Interface):
f.write(f"temp = {self.step.dice.temp}\n")
if self.step.dice.randominit == "first" and cycle > 1:
f.write(f"init = yesreadxyz\n")
f.write("init = yesreadxyz\n")
f.write(f"nstep = {self.step.altsteps}\n")
else:
f.write(f"init = yes\n")
f.write("init = yes\n")
f.write(f"nstep = {self.step.dice.nstep[0]}\n")
f.write("vstep = 0\n")
@@ -301,7 +302,7 @@ class DiceInterface(Interface):
f.write(f"press = {self.step.dice.press}\n")
f.write(f"temp = {self.step.dice.temp}\n")
f.write(f"nstep = 5\n")
f.write("nstep = 5\n")
f.write(f"vstep = {int(self.step.dice.nstep[2] / 5)}\n")
f.write("init = no\n")

View File

@@ -60,13 +60,13 @@ class GaussianInterface(Interface):
def _copy_chk_file_from_previous_step(self, cycle: int):
current_chk_file_path = Path(
self.step.simulation_dir, f"step{cycle:02d}", "qm", f"asec.chk"
self.step.simulation_dir, f"step{cycle:02d}", "qm", "asec.chk"
)
if current_chk_file_path.exists():
raise FileExistsError(f"File {current_chk_file_path} already exists.")
previous_chk_file_path = Path(
self.step.simulation_dir, f"step{(cycle - 1):02d}", "qm", f"asec.chk"
self.step.simulation_dir, f"step{(cycle - 1):02d}", "qm", "asec.chk"
)
if not previous_chk_file_path.exists():
raise FileNotFoundError(f"File {previous_chk_file_path} does not exist.")
@@ -139,7 +139,7 @@ class GaussianInterface(Interface):
charges_nsites = int(charges.pop(0))
if int(charges_nsites) != total_nsites:
raise ValueError(
f"Number of sites does not match total number of sites."
"Number of sites does not match total number of sites."
)
thickness.append(self._calculate_proc_thickness(charges))
@@ -166,7 +166,7 @@ class GaussianInterface(Interface):
].strip()
):
raise SyntaxError(
f"Error: Invalid Dice Output. Atom type does not match."
"Error: Invalid Dice Output. Atom type does not match."
)
new_molecule.add_atom(
@@ -216,7 +216,7 @@ class GaussianInterface(Interface):
def _make_gaussian_input_file(self, cycle: int, asec_charges: list[dict]) -> None:
gaussian_input_file_path = Path(
self.step.simulation_dir, f"step{cycle:02d}", "qm", f"asec.gjf"
self.step.simulation_dir, f"step{cycle:02d}", "qm", "asec.gjf"
)
with open(gaussian_input_file_path, "w") as gaussian_input_file:

View File

@@ -6,6 +6,7 @@ import shutil
import sys
import time
####################################### constants ######################################
@@ -36,7 +37,7 @@ def compress_files_1mb(path):
with open(file, "rb") as f_in:
with gzip.open(filegz, "wb") as f_out:
shutil.copyfileobj(f_in, f_out)
except:
except Exception as _:
sys.exit("Error: cannot compress file {}".format(file))
os.chdir(working_dir)
@@ -52,7 +53,7 @@ def make_step_dir(cycle):
sys.exit("Error: a file or directory {} already exists".format(step_dir))
try:
os.makedirs(path)
except:
except Exception as _:
sys.exit("Error: cannot make directory {}".format(step_dir))
@@ -62,5 +63,5 @@ def make_qm_dir(cycle):
path = sim_dir + os.sep + step_dir + os.sep + "qm"
try:
os.makedirs(path)
except:
except Exception as _:
sys.exit("Error: cannot make directory {}".format(path))

30
poetry.lock generated
View File

@@ -636,6 +636,34 @@ files = [
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
]
[[package]]
name = "ruff"
version = "0.15.2"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
groups = ["dev"]
files = [
{file = "ruff-0.15.2-py3-none-linux_armv6l.whl", hash = "sha256:120691a6fdae2f16d65435648160f5b81a9625288f75544dc40637436b5d3c0d"},
{file = "ruff-0.15.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a89056d831256099658b6bba4037ac6dd06f49d194199215befe2bb10457ea5e"},
{file = "ruff-0.15.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e36dee3a64be0ebd23c86ffa3aa3fd3ac9a712ff295e192243f814a830b6bd87"},
{file = "ruff-0.15.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9fb47b6d9764677f8c0a193c0943ce9a05d6763523f132325af8a858eadc2b9"},
{file = "ruff-0.15.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f376990f9d0d6442ea9014b19621d8f2aaf2b8e39fdbfc79220b7f0c596c9b80"},
{file = "ruff-0.15.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2dcc987551952d73cbf5c88d9fdee815618d497e4df86cd4c4824cc59d5dd75f"},
{file = "ruff-0.15.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:42a47fd785cbe8c01b9ff45031af875d101b040ad8f4de7bbb716487c74c9a77"},
{file = "ruff-0.15.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cbe9f49354866e575b4c6943856989f966421870e85cd2ac94dccb0a9dcb2fea"},
{file = "ruff-0.15.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7a672c82b5f9887576087d97be5ce439f04bbaf548ee987b92d3a7dede41d3a"},
{file = "ruff-0.15.2-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:72ecc64f46f7019e2bcc3cdc05d4a7da958b629a5ab7033195e11a438403d956"},
{file = "ruff-0.15.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:8dcf243b15b561c655c1ef2f2b0050e5d50db37fe90115507f6ff37d865dc8b4"},
{file = "ruff-0.15.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dab6941c862c05739774677c6273166d2510d254dac0695c0e3f5efa1b5585de"},
{file = "ruff-0.15.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1b9164f57fc36058e9a6806eb92af185b0697c9fe4c7c52caa431c6554521e5c"},
{file = "ruff-0.15.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:80d24fcae24d42659db7e335b9e1531697a7102c19185b8dc4a028b952865fd8"},
{file = "ruff-0.15.2-py3-none-win32.whl", hash = "sha256:fd5ff9e5f519a7e1bd99cbe8daa324010a74f5e2ebc97c6242c08f26f3714f6f"},
{file = "ruff-0.15.2-py3-none-win_amd64.whl", hash = "sha256:d20014e3dfa400f3ff84830dfb5755ece2de45ab62ecea4af6b7262d0fb4f7c5"},
{file = "ruff-0.15.2-py3-none-win_arm64.whl", hash = "sha256:cabddc5822acdc8f7b5527b36ceac55cc51eec7b1946e60181de8fe83ca8876e"},
{file = "ruff-0.15.2.tar.gz", hash = "sha256:14b965afee0969e68bb871eba625343b8673375f457af4abe98553e8bbb98342"},
]
[[package]]
name = "setproctitle"
version = "1.3.3"
@@ -801,4 +829,4 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess
[metadata]
lock-version = "2.1"
python-versions = ">=3.9"
content-hash = "5279a27d4c4f2d07ca08ba879729efb8e7259c64907bbac87e5f574818eb66e2"
content-hash = "0e661d700053564022ef8eff6a86d1d55bc23196df8383a7241cad4ced174b1b"

View File

@@ -33,6 +33,7 @@ isort = "^5.13.2"
black = "^24.4.2"
pre-commit = "^3.7.1"
poethepoet = "^0.27.0"
ruff = "^0.15.2"
# Build system
@@ -45,17 +46,38 @@ requires = ["poetry-core"]
build-backend = "poetry_dynamic_versioning.backend"
# Development tools
# POE Tasks
[tool.poe.tasks]
hooks = "pre-commit install --config .pre-commit-config.yaml"
create-hooks = "bash .githooks/set-hooks.sh"
tests = "python -m coverage run -m unittest discover -v"
tests-report = "python -m coverage xml"
[tool.isort]
profile = "black"
line_length = 79
sections=[
"FUTURE",
"FIRSTPARTY",
"LOCALFOLDER",
"THIRDPARTY",
"STDLIB",
# Tests
[tool.coverage.run]
omit = [
"tests/*",
]
# Linters
[tool.ruff.lint]
extend-select = ["I"]
[tool.ruff.lint.isort]
known-first-party = ["jambo"]
section-order=[
"future",
"first-party",
"local-folder",
"third-party",
"standard-library",
]
lines-after-imports = 2
[tool.pyright]
venvPath = "."
venv = ".venv"

View File

@@ -15,7 +15,7 @@ class TestGaussianDTO(unittest.TestCase):
def test_is_valid_qmprog(self):
with self.assertRaises(ValueError):
gaussian_dto = GaussianConfig(
GaussianConfig(
level="test",
qmprog="test",
keywords="test",
@@ -23,7 +23,7 @@ class TestGaussianDTO(unittest.TestCase):
def test_is_valid_level(self):
with self.assertRaises(ValueError):
gaussian_dto = GaussianConfig(
GaussianConfig(
level=None,
qmprog="g16",
keywords="test",

View File

@@ -103,11 +103,14 @@ class TestMolecule(unittest.TestCase):
Atom(lbl=1, na=1, rx=0.0, ry=0.0, rz=0.0, chg=1.0, eps=1.0, sig=1.0)
)
expected_evals, expected_evecs = [0.0, 0.0, 0.0], [
expected_evals, expected_evecs = (
[0.0, 0.0, 0.0],
[
[1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0],
]
],
)
evals, evecs = mol.principal_axes()

View File

@@ -1,4 +1,3 @@
from diceplayer.shared.environment.atom import Atom
from diceplayer.shared.environment.molecule import Molecule
from diceplayer.shared.environment.system import System

View File

@@ -309,7 +309,7 @@ class TestDiceInterface(unittest.TestCase):
self.assertTrue(mock_os.getcwd.called)
self.assertTrue(mock_os.chdir.called)
self.assertEqual(dice.run_dice_file.call_count, 1)
self.assertEqual(dice.run_dice_file.call_count, 2)
self.assertTrue(mock_shutils.copy.called)
@mock.patch("diceplayer.shared.interface.dice_interface.os")
@@ -317,7 +317,7 @@ class TestDiceInterface(unittest.TestCase):
@mock.patch(
"diceplayer.shared.interface.dice_interface.Path.exists", return_value=False
)
def test_run_dice_on_second_cycle_run_successful(
def test_run_dice_raises_filenotfound_on_invalid_file(
self, mock_path_exists, mock_shutils, mock_os
):
dice = DiceInterface()

View File

@@ -1,4 +1,4 @@
from diceplayer import VERSION, logger
from diceplayer import logger
from diceplayer.player import Player
from tests.mocks.mock_inputs import mock_open