Source code for bacpipe.tests.conftest

from pathlib import Path
from bacpipe import supported_models, models_needing_checkpoint, settings
import importlib.resources as pkg_resources
import bacpipe
import yaml
import pytest

# cache so we only compute once
_filtered_models = None


[docs] def pytest_addoption(parser): parser.addoption( "--models", action="store", default=None, help="Comma-separated list of models to test (default: all available models)", ) parser.addoption( "--device", action="store", default=None, #"cpu", help="Device to run the tests on (e.g., 'cpu', 'cuda')", ) parser.addoption( "--overwrite", action="store", default=None, #True, help="overwrite already processed results or not", ) parser.addoption( "--only_embed_annotations", action="store", default=None, #False, help="Only embed annotations or create annotations from grid based on model input length", ) parser.addoption( "--check_if_already_processed", action="store", default=None, #False, help="Check if embeddings already exist, if so use existing ones. if False, will overwrite embeddings.", ) parser.addoption( "--check_if_already_dim_reduced", action="store", default=None, #False, help="Check if dimensionality reduced embeddings already exist, if so use existing ones. if False, will overwrite.", )
# List of boolean options to potentially parametrize BOOL_OPTIONS = [ 'overwrite', 'only_embed_annotations', 'check_if_already_processed', 'check_if_already_dim_reduced', ]
[docs] def pytest_generate_tests(metafunc): global _filtered_models # --- models --- if "model" in metafunc.fixturenames: if _filtered_models is None: option = metafunc.config.getoption("models") if option == 'tf': models = bacpipe.TF_MODELS elif option == 'torch': all_models = list(supported_models) models = [ m for m in all_models if m not in bacpipe.TF_MODELS ] elif option: models = option.split(",") else: models = bacpipe.TF_MODELS if not models: models = ["birdnet"] _filtered_models = models metafunc.parametrize("model", _filtered_models) if "device" in metafunc.fixturenames: raw = metafunc.config.getoption("device") if raw is None: metafunc.parametrize("device", ["cpu", "cuda"]) else: metafunc.parametrize("device", [raw]) # --- boolean options --- for opt in BOOL_OPTIONS: if opt in metafunc.fixturenames: raw = metafunc.config.getoption(opt) if raw is None: vals = [True, False] # This creates labels like 'overwrite=True' and 'overwrite=False' metafunc.parametrize(opt, vals, ids=[f"{opt.split('_')[0]}={str(v)[0]}" for v in vals]) else: val = False if raw == 'False' else True metafunc.parametrize(opt, [val], ids=[f"{opt.split('_')[0]}={val}"])
[docs] @pytest.fixture def device(request): return request.param
[docs] @pytest.fixture def overwrite(request): return request.param
[docs] @pytest.fixture def only_embed_annotations(request): return request.param
[docs] @pytest.fixture def check_if_already_processed(request): return request.param
[docs] @pytest.fixture def check_if_already_dim_reduced(request): return request.param
[docs] @pytest.fixture(scope='function') def kwargs(request): # 1. Load your YAMLs once with pkg_resources.open_text(bacpipe, "settings.yaml") as f: settings_dict = yaml.load(f, Loader=yaml.CLoader) with pkg_resources.open_text(bacpipe, "config.yaml") as f: config_dict = yaml.load(f, Loader=yaml.CLoader) settings_dict["testing"] = True # 2. Dynamically pull values ONLY if the test is using those fixtures # This prevents unnecessary parametrization for tests that don't list them opts = ['device', 'overwrite', 'only_embed_annotations', 'check_if_already_processed', 'check_if_already_dim_reduced'] for opt in opts: if opt in request.fixturenames: # Get the value from the parametrized fixture val = request.getfixturevalue(opt) settings_dict[opt] = val else: # Use the default from the YAML or a fallback # (Ensures bacpipe.settings remains consistent) pass # 3. Sync with global bacpipe.settings for k, v in settings_dict.items(): if hasattr(bacpipe.settings, k): setattr(bacpipe.settings, k, v) with pkg_resources.path(bacpipe.tests, "test_data") as audio_dir: config_dict["audio_dir"] = Path(audio_dir) return {**config_dict, **settings_dict}