From 8aa8e02a5a8397b2e570d176b168c8b345fc09e6 Mon Sep 17 00:00:00 2001 From: DorisMai Date: Thu, 26 Feb 2026 15:35:30 -0800 Subject: [PATCH 1/3] initial commit. fixes test data path. added pre-commit and build workflow. incomplete work skip ci. --- .github/workflows/build.yml | 34 +++++++++++ .pre-commit-config.yaml | 10 ++++ pyproject.toml | 22 +++++-- tests/conftest.py | 59 +++++++++++++++++++ tests/test_dataset.py | 35 ----------- tests/test_encoder.py | 5 -- .../test_files/6eey}/6eey_final.pdb | 0 tests/test_flow.py | 5 -- tests/test_forward.py | 5 -- 9 files changed, 121 insertions(+), 54 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 .pre-commit-config.yaml create mode 100644 tests/conftest.py rename {test_files => tests/test_files/6eey}/6eey_final.pdb (100%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..92bdbd6 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,34 @@ +name: Build + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.12] + + # Skip CI if 'skip ci' is contained in the latest commit message + if: "!contains(github.event.head_commit.message, 'skip ci')" + + steps: + - uses: actions/checkout@v6 + + - name: Setup UV and python version + uses: astral-sh/setup-uv@v7 + with: + version: "0.10.6" + python: ${{ matrix.python-version }} + + - name: Install dependencies + run: uv sync --group dev + + - name: Run tests + env: + TEST_DATA_DIR: ${{ github.workspace }}/tests/test_files + run: uv run pytest diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..412c34d --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,10 @@ +repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.15.0 + hooks: + # Run the linter. + - id: ruff-check + args: [--verbose, --fix] + # Run the formatter. + - id: ruff-format + args: [--verbose] \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index e59121b..f28de7e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -189,11 +189,9 @@ dependencies = [ [dependency-groups] dev = [ - "black>=23.0.0", - "flake8>=6.0.0", + "ruff", + "prek", "hypothesis>=6.70.0", - "isort>=5.12.0", - "mypy>=1.0.0", "pytest>=7.0.0", "pytest-cov>=4.0.0", "pytest-mock>=3.10.0", @@ -201,6 +199,22 @@ dev = [ "pytest-xdist>=3.0.0", ] +[tool.ruff] +line-length = 88 +target-version = "py312" + +[tool.ruff.lint] +select = [ + "E", # pycodestyle errors + "F", # pyflakes + "I", # isort (import sorting) + "W", # pycodestyle warnings + "UP", # pyupgrade (modernize syntax) +] + +[tool.ruff.lint.isort] +known-first-party = ["src"] + # PyTorch CUDA 12.6 index (so `torch`/`torchvision` come from the right place) [[tool.uv.index]] name = "pytorch-cu126" diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..0d5b875 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,59 @@ +import os +from pathlib import Path + +import pytest +import torch + +TEST_DIR = Path(__file__).parent + + +@pytest.fixture +def device(): + return torch.device("cuda" if torch.cuda.is_available() else "cpu") + + +@pytest.fixture +def pdb_base_dir(): + """Base directory for test PDB files. + + Override via the TEST_DATA_DIR environment variable (e.g. in CI). + """ + env = os.environ.get("TEST_DATA_DIR") + if env: + return Path(env) + return TEST_DIR / "test_files" + + +@pytest.fixture +def pdb_path(pdb_base_dir): + """Factory fixture that resolves a PDB path, skipping if missing.""" + def _resolve(pdb_id: str) -> str: + path = pdb_base_dir / pdb_id / f"{pdb_id}_final.pdb" + if not path.exists(): + pytest.skip(f"PDB file not found: {path}") + return str(path) + return _resolve + + +@pytest.fixture +def pdb_6eey(pdb_path): + """6eey - standard PDB that passes all quality checks.""" + return pdb_path("6eey") + + +@pytest.fixture +def pdb_2b5w(pdb_path): + """2b5w - fails COM distance check.""" + return pdb_path("2b5w") + + +@pytest.fixture +def pdb_8dzt(pdb_path): + """8dzt - fails water clash check at 2% threshold with 2A distance.""" + return pdb_path("8dzt") + + +@pytest.fixture +def pdb_1deu(pdb_path): + """1deu - has insertion codes (52 residues with ins_code='P').""" + return pdb_path("1deu") diff --git a/tests/test_dataset.py b/tests/test_dataset.py index e97aaed..80c5975 100644 --- a/tests/test_dataset.py +++ b/tests/test_dataset.py @@ -19,8 +19,6 @@ All test cases created with assistance from Claude Code. """ -from pathlib import Path - import numpy as np import pytest import torch @@ -44,39 +42,6 @@ ) -@pytest.fixture -def pdb_base_dir(): - """Base directory for PDB files.""" - return Path("/sb/wankowicz_lab/data/srivasv/pdb_redo_data") - - -@pytest.fixture -def pdb_6eey(pdb_base_dir): - """Path to 6eey PDB file - should pass all quality checks.""" - path = pdb_base_dir / "6eey" / "6eey_final.pdb" - if not path.exists(): - pytest.skip(f"PDB file not found: {path}") - return str(path) - - -@pytest.fixture -def pdb_2b5w(pdb_base_dir): - """Path to 2b5w PDB file - should fail COM distance check.""" - path = pdb_base_dir / "2b5w" / "2b5w_final.pdb" - if not path.exists(): - pytest.skip(f"PDB file not found: {path}") - return str(path) - - -@pytest.fixture -def pdb_8dzt(pdb_base_dir): - """Path to 8dzt PDB file - should fail water clash check at 2% threshold.""" - path = pdb_base_dir / "8dzt" / "8dzt_final.pdb" - if not path.exists(): - pytest.skip(f"PDB file not found: {path}") - return str(path) - - @pytest.fixture def tmp_processed_dir(tmp_path): """Temporary directory for processed files.""" diff --git a/tests/test_encoder.py b/tests/test_encoder.py index f48531b..bd0b760 100644 --- a/tests/test_encoder.py +++ b/tests/test_encoder.py @@ -20,11 +20,6 @@ # ============== Fixtures ============== -@pytest.fixture -def device(): - return torch.device("cuda" if torch.cuda.is_available() else "cpu") - - @pytest.fixture def sample_homogeneous_data(): """Sample Data for testing ProteinGVPEncoder directly.""" diff --git a/test_files/6eey_final.pdb b/tests/test_files/6eey/6eey_final.pdb similarity index 100% rename from test_files/6eey_final.pdb rename to tests/test_files/6eey/6eey_final.pdb diff --git a/tests/test_flow.py b/tests/test_flow.py index 7990f6a..22db8f5 100644 --- a/tests/test_flow.py +++ b/tests/test_flow.py @@ -19,11 +19,6 @@ from src.gvp_encoder import GVPEncoder, ProteinGVPEncoder, make_encoder_data -@pytest.fixture -def device(): - return torch.device("cuda" if torch.cuda.is_available() else "cpu") - - @pytest.fixture def simple_hetero_data(device): """Minimal HeteroData with protein and water nodes.""" diff --git a/tests/test_forward.py b/tests/test_forward.py index d15da6d..ef415cd 100644 --- a/tests/test_forward.py +++ b/tests/test_forward.py @@ -77,11 +77,6 @@ def __exit__(self, exc_type, exc, tb): return False # don't suppress exceptions -@pytest.fixture -def device(): - return torch.device("cuda" if torch.cuda.is_available() else "cpu") - - def make_batched_hetero( device, n_graphs=2, From 35abfef12ae2bb345be78b41155011afef529b7e Mon Sep 17 00:00:00 2001 From: Doris Mai Date: Sat, 28 Feb 2026 18:06:32 -0800 Subject: [PATCH 2/3] Revert non-test file changes --- .github/workflows/build.yml | 34 ---------------------------------- .pre-commit-config.yaml | 10 ---------- pyproject.toml | 22 ++++------------------ 3 files changed, 4 insertions(+), 62 deletions(-) delete mode 100644 .github/workflows/build.yml delete mode 100644 .pre-commit-config.yaml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 92bdbd6..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Build - -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: [3.12] - - # Skip CI if 'skip ci' is contained in the latest commit message - if: "!contains(github.event.head_commit.message, 'skip ci')" - - steps: - - uses: actions/checkout@v6 - - - name: Setup UV and python version - uses: astral-sh/setup-uv@v7 - with: - version: "0.10.6" - python: ${{ matrix.python-version }} - - - name: Install dependencies - run: uv sync --group dev - - - name: Run tests - env: - TEST_DATA_DIR: ${{ github.workspace }}/tests/test_files - run: uv run pytest diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index 412c34d..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,10 +0,0 @@ -repos: - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.0 - hooks: - # Run the linter. - - id: ruff-check - args: [--verbose, --fix] - # Run the formatter. - - id: ruff-format - args: [--verbose] \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index f28de7e..e59121b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -189,9 +189,11 @@ dependencies = [ [dependency-groups] dev = [ - "ruff", - "prek", + "black>=23.0.0", + "flake8>=6.0.0", "hypothesis>=6.70.0", + "isort>=5.12.0", + "mypy>=1.0.0", "pytest>=7.0.0", "pytest-cov>=4.0.0", "pytest-mock>=3.10.0", @@ -199,22 +201,6 @@ dev = [ "pytest-xdist>=3.0.0", ] -[tool.ruff] -line-length = 88 -target-version = "py312" - -[tool.ruff.lint] -select = [ - "E", # pycodestyle errors - "F", # pyflakes - "I", # isort (import sorting) - "W", # pycodestyle warnings - "UP", # pyupgrade (modernize syntax) -] - -[tool.ruff.lint.isort] -known-first-party = ["src"] - # PyTorch CUDA 12.6 index (so `torch`/`torchvision` come from the right place) [[tool.uv.index]] name = "pytorch-cu126" From 3c46e8f269a38966e4e7ee80b0cc990521bc28ef Mon Sep 17 00:00:00 2001 From: Doris Mai Date: Mon, 2 Mar 2026 10:41:46 -0800 Subject: [PATCH 3/3] make pdb dir constant to avoid repeated call of os.environ --- tests/conftest.py | 45 +++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 0d5b875..474ef68 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,55 +5,48 @@ import torch TEST_DIR = Path(__file__).parent +ENV_PDB_DIR = os.environ.get("ENV_PDB_DIR") +PDB_BASE_DIR = Path(ENV_PDB_DIR) if ENV_PDB_DIR else TEST_DIR / "test_files" @pytest.fixture def device(): return torch.device("cuda" if torch.cuda.is_available() else "cpu") - -@pytest.fixture +@pytest.fixture(scope="session") def pdb_base_dir(): - """Base directory for test PDB files. - - Override via the TEST_DATA_DIR environment variable (e.g. in CI). + """Wrapper of constant PDB_BASE_DIR. """ - env = os.environ.get("TEST_DATA_DIR") - if env: - return Path(env) - return TEST_DIR / "test_files" + return PDB_BASE_DIR -@pytest.fixture -def pdb_path(pdb_base_dir): - """Factory fixture that resolves a PDB path, skipping if missing.""" - def _resolve(pdb_id: str) -> str: - path = pdb_base_dir / pdb_id / f"{pdb_id}_final.pdb" - if not path.exists(): - pytest.skip(f"PDB file not found: {path}") - return str(path) - return _resolve +def _resolve_pdb_path(pdb_id): + """Resolves a PDB path, skipping if missing.""" + path = PDB_BASE_DIR / pdb_id / f"{pdb_id}_final.pdb" + if not path.exists(): + pytest.skip(f"PDB file not found: {path}") + return str(path) @pytest.fixture -def pdb_6eey(pdb_path): +def pdb_6eey(): """6eey - standard PDB that passes all quality checks.""" - return pdb_path("6eey") + return _resolve_pdb_path("6eey") @pytest.fixture -def pdb_2b5w(pdb_path): +def pdb_2b5w(): """2b5w - fails COM distance check.""" - return pdb_path("2b5w") + return _resolve_pdb_path("2b5w") @pytest.fixture -def pdb_8dzt(pdb_path): +def pdb_8dzt(): """8dzt - fails water clash check at 2% threshold with 2A distance.""" - return pdb_path("8dzt") + return _resolve_pdb_path("8dzt") @pytest.fixture -def pdb_1deu(pdb_path): +def pdb_1deu(): """1deu - has insertion codes (52 residues with ins_code='P').""" - return pdb_path("1deu") + return _resolve_pdb_path("1deu")