Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,8 @@ flake8-tidy-imports.ban-relative-imports = "all"
"docs/lite/jupyterlite.py" = ["F401", "F704"]
"**.ipynb" = ["T20"]
"noxfile.py" = ["T20"]
"tests/**" = ["ARG001", "ARG002", "NPY002", "PLR0124", "PT012", "T20"]
"validation/**" = ["T20", "PTH123", "NPY002"]
"tests/**" = ["NPY002"]
"validation/**" = ["T20", "NPY002"]

[tool.pixi.workspace]
channels = ["conda-forge"]
Expand Down
3 changes: 2 additions & 1 deletion tests/benchmarks/test_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ def hypotest(pdf, data):


@pytest.mark.parametrize("n_bins", bins, ids=bin_ids)
def test_hypotest(benchmark, backend, n_bins):
@pytest.mark.usefixtures("backend")
def test_hypotest(benchmark, n_bins):
"""
Benchmark the performance of pyhf.utils.hypotest()
for various numbers of bins and different backends
Expand Down
6 changes: 6 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ def backend(request):
return (tensor, optimizer)


@pytest.fixture
def _backend(backend):
"""Alias for the backend fixture for use in fixtures that need the backend
side-effect but don't use the return value."""


@pytest.fixture(
params=[0, 1, 2, 4],
ids=["interpcode0", "interpcode1", "interpcode2", "interpcode4"],
Expand Down
9 changes: 2 additions & 7 deletions tests/test_backend_consistency.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,5 @@ def test_hypotest_qmu_tilde(n_bins, invert_order):
numpy_ratio = np.divide(test_statistic, test_statistic[0])
numpy_ratio_delta_unity = np.absolute(np.subtract(numpy_ratio, 1))

try:
assert (numpy_ratio_delta_unity < tolerance["numpy"]).all()
except AssertionError:
print(
f"Ratio to NumPy+SciPy exceeded tolerance of {tolerance['numpy']}: {numpy_ratio_delta_unity.tolist()}"
)
raise AssertionError from None
err_msg = f"Ratio to NumPy+SciPy exceeded tolerance of {tolerance['numpy']}: {numpy_ratio_delta_unity.tolist()}"
assert (numpy_ratio_delta_unity < tolerance["numpy"]).all(), err_msg
3 changes: 2 additions & 1 deletion tests/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ def test_tensor_array_types():


@pytest.mark.only_jax
def test_jax_data_shape_mismatch_during_jitting(backend):
@pytest.mark.usefixtures("backend")
def test_jax_data_shape_mismatch_during_jitting():
"""
Validate that during JAX tracing time pyhf doesn't try
to convert the data to a list, which is not possible with tracers,
Expand Down
25 changes: 17 additions & 8 deletions tests/test_combined_modifiers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import numpy as np
import pytest

import pyhf
from pyhf.modifiers.histosys import histosys_combined
Expand Down Expand Up @@ -44,7 +45,8 @@ def param_set(self, name):
return self.par_map[name]["paramset"]


def test_histosys(backend):
@pytest.mark.usefixtures("backend")
def test_histosys():
mc = MockConfig(
par_map={
"hello": {
Expand Down Expand Up @@ -149,7 +151,8 @@ def test_histosys(backend):
assert np.allclose(mod[0, 0, 3], [1.0, 2.0, 3.0])


def test_normsys(backend):
@pytest.mark.usefixtures("backend")
def test_normsys():
mc = MockConfig(
par_map={
"hello": {
Expand Down Expand Up @@ -256,7 +259,8 @@ def test_normsys(backend):
assert np.allclose(mod[0, 0, 3], [1.1, 1.1, 1.1])


def test_lumi(backend):
@pytest.mark.usefixtures("backend")
def test_lumi():
mc = MockConfig(
par_map={
"lumi": {
Expand Down Expand Up @@ -315,7 +319,8 @@ def test_lumi(backend):
assert np.allclose(mod[0, 0, 3], [4.0, 4.0, 4.0])


def test_stat(backend):
@pytest.mark.usefixtures("backend")
def test_stat():
mc = MockConfig(
par_map={
"staterror_chan1": {
Expand Down Expand Up @@ -406,7 +411,8 @@ def test_stat(backend):
assert np.allclose(mod[1, 0, 0], [1, 1.2, 1.3])


def test_shapesys(backend):
@pytest.mark.usefixtures("backend")
def test_shapesys():
mc = MockConfig(
par_map={
"dummy1": {
Expand Down Expand Up @@ -519,7 +525,8 @@ def test_shapesys(backend):
assert np.allclose(mod[1, 0, 0], [1, 1.2, 1.3])


def test_normfactor(backend):
@pytest.mark.usefixtures("backend")
def test_normfactor():
mc = MockConfig(
par_map={
"mu1": {
Expand Down Expand Up @@ -609,7 +616,8 @@ def test_normfactor(backend):
assert np.allclose(mod[1, 0, 3], [1.0, 8.0, 8.0])


def test_shapesys_zero(backend):
@pytest.mark.usefixtures("backend")
def test_shapesys_zero():
mc = MockConfig(
par_map={
"SigXsecOverSM": {
Expand Down Expand Up @@ -675,7 +683,8 @@ def test_shapesys_zero(backend):
assert mod[0, 1, 0, 2] == 1.0


def test_shapefactor(backend):
@pytest.mark.usefixtures("backend")
def test_shapefactor():
mc = MockConfig(
par_map={
"shapefac1": {
Expand Down
6 changes: 4 additions & 2 deletions tests/test_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def param_set(self, name):
return self.par_map[name]["paramset"]


def test_numpy_pdf_inputs(backend):
@pytest.mark.usefixtures("backend")
def test_numpy_pdf_inputs():
spec = {
"channels": [
{
Expand Down Expand Up @@ -131,7 +132,8 @@ def fast(self, auxdata, pars):
assert pytest.approx(slow_result) == fast_result


def test_batched_constraints(backend):
@pytest.mark.usefixtures("backend")
def test_batched_constraints():
config = MockConfig(
par_order=["pois1", "pois2", "norm1", "norm2"],
par_map={
Expand Down
3 changes: 1 addition & 2 deletions tests/test_custom_mods.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def test_missing_poi():
modifier_set.update(**pyhf.modifiers.histfactory_set)

with pytest.raises(exceptions.InvalidModel):
model = pyhf.Model(
pyhf.Model(
{
"channels": [
{
Expand All @@ -108,4 +108,3 @@ def test_missing_poi():
poi_name="non_existent_poi",
validate=False,
)
assert model
4 changes: 2 additions & 2 deletions tests/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def test_subscribe_function(capsys):
ename = "test"

def add(a, b):
print(a + b)
print(a + b) # noqa: T201

events.subscribe(ename)(add)
events.trigger(ename)(1, 2)
Expand All @@ -91,7 +91,7 @@ def test_trigger_function(capsys):
ename = "test"

def add(a, b):
print(a + b)
print(a + b) # noqa: T201

precall = mock.Mock()
postcall = mock.Mock()
Expand Down
5 changes: 4 additions & 1 deletion tests/test_examples.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import shlex

import pytest

def test_2bin_1channel(tmp_path, script_runner):

@pytest.mark.usefixtures("tmp_path")
def test_2bin_1channel(script_runner):
command = f"pyhf inspect {'docs/examples/json/2-bin_1-channel.json':s}"
ret = script_runner.run(shlex.split(command))
assert ret.success
35 changes: 23 additions & 12 deletions tests/test_infer.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ def check_uniform_type(in_list):
)


def test_toms748_scan(tmp_path, hypotest_args):
@pytest.mark.usefixtures("tmp_path")
def test_toms748_scan(hypotest_args):
"""
Test the upper limit toms748 scan returns the correct structure and values
"""
Expand Down Expand Up @@ -206,7 +207,8 @@ def test_upper_limit_return_tail_probs(hypotest_args):
assert observed_limit == pytest.approx(1.01156939, abs=0.1)


def test_mle_fit_default(tmp_path, hypotest_args):
@pytest.mark.usefixtures("tmp_path")
def test_mle_fit_default(hypotest_args):
"""
Check that the default return structure of pyhf.infer.mle.fit is as expected
"""
Expand All @@ -220,7 +222,8 @@ def test_mle_fit_default(tmp_path, hypotest_args):
assert pyhf.tensorlib.shape(result) == (model.config.npars,)


def test_mle_fit_return_fitted_val(tmp_path, hypotest_args):
@pytest.mark.usefixtures("tmp_path")
def test_mle_fit_return_fitted_val(hypotest_args):
"""
Check that the return structure of pyhf.infer.mle.fit with the
return_fitted_val keyword arg is as expected
Expand All @@ -236,7 +239,8 @@ def test_mle_fit_return_fitted_val(tmp_path, hypotest_args):
assert pyhf.tensorlib.shape(result[1]) == ()


def test_hypotest_default(tmp_path, hypotest_args):
@pytest.mark.usefixtures("tmp_path")
def test_hypotest_default(hypotest_args):
"""
Check that the default return structure of pyhf.infer.hypotest is as expected
"""
Expand All @@ -249,7 +253,8 @@ def test_hypotest_default(tmp_path, hypotest_args):
assert isinstance(result, type(tb.astensor(result)))


def test_hypotest_poi_outofbounds(tmp_path, hypotest_args):
@pytest.mark.usefixtures("tmp_path", "hypotest_args")
def test_hypotest_poi_outofbounds():
"""
Check that the fit errors for POI outside of parameter bounds
"""
Expand All @@ -270,7 +275,8 @@ def test_hypotest_poi_outofbounds(tmp_path, hypotest_args):


@pytest.mark.parametrize("test_stat", ["q0", "q", "qtilde"])
def test_hypotest_return_tail_probs(tmp_path, hypotest_args, test_stat):
@pytest.mark.usefixtures("tmp_path")
def test_hypotest_return_tail_probs(hypotest_args, test_stat):
"""
Check that the return structure of pyhf.infer.hypotest with the
return_tail_probs keyword arg is as expected
Expand All @@ -287,7 +293,8 @@ def test_hypotest_return_tail_probs(tmp_path, hypotest_args, test_stat):


@pytest.mark.parametrize("test_stat", ["q0", "q", "qtilde"])
def test_hypotest_return_expected(tmp_path, hypotest_args, test_stat):
@pytest.mark.usefixtures("tmp_path")
def test_hypotest_return_expected(hypotest_args, test_stat):
"""
Check that the return structure of pyhf.infer.hypotest with the
addition of the return_expected keyword arg is as expected
Expand All @@ -309,7 +316,8 @@ def test_hypotest_return_expected(tmp_path, hypotest_args, test_stat):


@pytest.mark.parametrize("test_stat", ["q0", "q", "qtilde"])
def test_hypotest_return_expected_set(tmp_path, hypotest_args, test_stat):
@pytest.mark.usefixtures("tmp_path")
def test_hypotest_return_expected_set(hypotest_args, test_stat):
"""
Check that the return structure of pyhf.infer.hypotest with the
addition of the return_expected_set keyword arg is as expected
Expand Down Expand Up @@ -343,8 +351,8 @@ def test_hypotest_return_expected_set(tmp_path, hypotest_args, test_stat):
@pytest.mark.parametrize("return_tail_probs", [True, False])
@pytest.mark.parametrize("return_expected", [True, False])
@pytest.mark.parametrize("return_expected_set", [True, False])
@pytest.mark.usefixtures("tmp_path")
def test_hypotest_return_calculator(
tmp_path,
hypotest_args,
calctype,
kwargs,
Expand Down Expand Up @@ -391,7 +399,8 @@ def test_hypotest_return_calculator(
[{"calctype": "asymptotics"}, {"calctype": "toybased", "ntoys": 5}],
ids=lambda x: x["calctype"],
)
def test_hypotest_backends(backend, kwargs):
@pytest.mark.usefixtures("backend")
def test_hypotest_backends(kwargs):
"""
Check that hypotest runs fully across all backends for all calculator types.
"""
Expand Down Expand Up @@ -535,7 +544,8 @@ def test_significance_to_pvalue_roundtrip(backend):
assert np.allclose(sigma, back_to_sigma, atol=0, rtol=rtol)


def test_emperical_distribution(tmp_path, hypotest_args):
@pytest.mark.usefixtures("tmp_path")
def test_emperical_distribution(hypotest_args):
"""
Check that the empirical distribution of the test statistic gives
expected results
Expand Down Expand Up @@ -581,7 +591,8 @@ def test_emperical_distribution(tmp_path, hypotest_args):
)


def test_toy_calculator(tmp_path, hypotest_args):
@pytest.mark.usefixtures("tmp_path")
def test_toy_calculator(hypotest_args):
"""
Check that the toy calculator is performing as expected
"""
Expand Down
6 changes: 4 additions & 2 deletions tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
],
ids=["numpy", "jax"],
)
def test_missing_backends(isolate_modules, param):
@pytest.mark.usefixtures("isolate_modules")
def test_missing_backends(param):
backend_name, module_name, import_name, expectation = param

# hide
Expand Down Expand Up @@ -57,7 +58,8 @@ def test_missing_backends(isolate_modules, param):
],
ids=["scipy", "minuit"],
)
def test_missing_optimizer(isolate_modules, param):
@pytest.mark.usefixtures("isolate_modules")
def test_missing_optimizer(param):
backend_name, module_name, import_name, expectation = param

# hide
Expand Down
Loading
Loading