Repository: scipy/scipy
File: scipy/special/tests/test_basic.py (Python)

Code before:
        res_py = special.comb(n, k, exact=True)
        assert res_np == res_py

    def test_comb_zeros(self):
        assert_equal(special.comb(2, 3, exact=True), 0)
        assert_equal(special.comb(-1, 3, exact=True), 0)
        assert_equal(special.comb(2, -1, exact=True), 0)
        assert_equal(special.comb(2, -1, exact=False), 0)
        assert_allclose(special.comb([2, -1, 2, 10], [3, 3, -1, 3]), [0., 0., 0., 120.])

    def test_comb_exact_non_int_error(self):
        msg = "`exact=True`"
        with pytest.raises(ValueError, match=msg):
            special.comb(3.4, 4, exact=True)
        with pytest.raises(ValueError, match=msg):
            special.comb(3, 4.4, exact=True)

    def test_comb_repetition_k_zero(self):
        # Regression test for gh-23867
        # C(n, 0) should always be 1 for n >= 0, regardless of repetition
        assert_equal(special.comb(0, 0, exact=True, repetition=True), 1)
        assert_equal(special.comb(0, 0, exact=False, repetition=True), 1.0)
        assert_equal(special.comb(5, 0, exact=True, repetition=True), 1)
        assert_equal(special.comb(5, 0, exact=False, repetition=True), 1.0)
        assert_equal(special.comb(10, 0, exact=True, repetition=True), 1)
        assert_equal(special.comb(10, 0, exact=False, repetition=True), 1.0)

    def test_perm(self):
        assert_allclose(special.perm([10, 10], [3, 4]), [720., 5040.])
        assert_allclose(special.perm(10, 3), 720., atol=1.5e-7, rtol=0)
        assert_equal(special.perm(10, 3, exact=True), 720)

    def test_perm_zeros(self):
        assert_equal(special.perm(2, 3, exact=True), 0)
        assert_equal(special.perm(-1, 3, exact=True), 0)
        assert_equal(special.perm(2, -1, exact=True), 0)
        assert_equal(special.perm(2, -1, exact=False), 0)
        assert_allclose(special.perm([2, -1, 2, 10], [3, 3, -1, 3]), [0., 0., 0., 720.])

    def test_perm_iv(self):
        # currently `exact=True` only support scalars
        with pytest.raises(ValueError, match="scalar integers"):
            special.perm([1, 2], [4, 5], exact=True)

        with pytest.raises(ValueError, match="Non-integer"):
            special.perm(4.6, 6, exact=True)
        with pytest.raises(ValueError, match="Non-integer"):
            special.perm(-4.6, 3, exact=True)
        with pytest.raises(ValueError, match="Non-integer"):
            special.perm(4, -3.9, exact=True)
        with pytest.raises(ValueError, match="Non-integer"):

Review comment (suggestion):
It'd be cleaner to use `@pytest.mark.parametrize` (twice)

Code after:
        res_py = special.comb(n, k, exact=True)
        assert res_np == res_py

    def test_comb_zeros(self):
        assert_equal(special.comb(2, 3, exact=True), 0)
        assert_equal(special.comb(-1, 3, exact=True), 0)
        assert_equal(special.comb(2, -1, exact=True), 0)
        assert_equal(special.comb(2, -1, exact=False), 0)
        assert_allclose(special.comb([2, -1, 2, 10], [3, 3, -1, 3]), [0., 0., 0., 120.])

    def test_comb_exact_non_int_error(self):
        msg = "`exact=True`"
        with pytest.raises(ValueError, match=msg):
            special.comb(3.4, 4, exact=True)
        with pytest.raises(ValueError, match=msg):
            special.comb(3, 4.4, exact=True)

    @pytest.mark.parametrize('N', [0, 5, 10])
    @pytest.mark.parametrize('exact', [True, False])
    def test_comb_repetition_k_zero(self, N, exact):
        # Regression test for gh-23867
        # C(n, 0) should always be 1 for n >= 0, regardless of repetition
        actual = special.comb(N, 0, exact=exact, repetition=True)
        assert actual == 1
        assert type(actual) is int if exact else np.float64

    def test_comb_repetition_k_zero_array(self):
        # Test array-like input with exact=False for gh-23867
        N = np.array([0, 5, 10])
        result = special.comb(N, 0, exact=False, repetition=True)
        expected = np.array([1.0, 1.0, 1.0])
        assert_equal(result, expected)

    def test_perm(self):
        assert_allclose(special.perm([10, 10], [3, 4]), [720., 5040.])
        assert_allclose(special.perm(10, 3), 720., atol=1.5e-7, rtol=0)
        assert_equal(special.perm(10, 3, exact=True), 720)

    def test_perm_zeros(self):
        assert_equal(special.perm(2, 3, exact=True), 0)
        assert_equal(special.perm(-1, 3, exact=True), 0)
        assert_equal(special.perm(2, -1, exact=True), 0)
        assert_equal(special.perm(2, -1, exact=False), 0)
        assert_allclose(special.perm([2, -1, 2, 10], [3, 3, -1, 3]), [0., 0., 0., 720.])

    def test_perm_iv(self):
        # currently `exact=True` only support scalars
        with pytest.raises(ValueError, match="scalar integers"):
            special.perm([1, 2], [4, 5], exact=True)

        with pytest.raises(ValueError, match="Non-integer"):