Skip to content

ParameterSet is private #13431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
stevenh opened this issue May 18, 2025 · 2 comments
Open

ParameterSet is private #13431

stevenh opened this issue May 18, 2025 · 2 comments
Labels
topic: parametrize related to @pytest.mark.parametrize topic: typing type-annotation issue type: enhancement new feature or API change, should be merged into features branch

Comments

@stevenh
Copy link

stevenh commented May 18, 2025

When using pytest.param to create parameters for a test from a function, that function will return a list of ParameterSet but currently that is only available from _pytest.mark.structures which is private so importing it results in a private import warning.

It would be ideal if this structure was publicly available so developers don't need to disable warnings for uses of pytest.param when using fully hinted code.

The current situation looks like this, which requires a pyright ignore directive to be warning free.

This is simplified example, which could be defined inline but for more complex where the test cases were built by code using a function is more necessary.

from _pytest.mark.structures import ParameterSet  # pyright: ignore[reportPrivateImportUsage]
import pytest

def params() -> list[ParameterSet]:
    return [
        pytest.param("basic", 10, True, id="basic")
        pytest.param("advanced", 5, False, id="advanced")}
    ]


@pytest.mark.parametrize(("val1", "val2", "expected"), params())
async def test_ratelimiter(val1: str, val2: int, expected: bool) -> None:
       """Test code goes here..."""

Ideally this would be public to avoid this, for example:

from pytest.mark.structures import ParameterSet
import pytest

def params() -> list[ParameterSet]:
    return [
        pytest.param("basic", 10, True, id="basic")
        pytest.param("advanced", 5, False, id="advanced")}
    ]


@pytest.mark.parametrize(("val1", "val2", "expected"), params())
async def test_ratelimiter(val1: str, val2: int, expected: bool) -> None:
       """Test code goes here..."""
@RonnyPfannschmidt RonnyPfannschmidt added type: enhancement new feature or API change, should be merged into features branch topic: parametrize related to @pytest.mark.parametrize topic: typing type-annotation issue labels May 18, 2025
@bluetech
Copy link
Member

Yes, this is a TODO in #7469. I think we can do it. We'd need to audit the API for exposure, specifically, make the constructor private (using the is_pytest trick -- need to check if it's possible with a namedtuple), hide the factory methods (at least from docs), and change the recently added docstring to be outward-facing.

@stevenh
Copy link
Author

stevenh commented May 28, 2025

For reference for others, in part to avoid having to import this private class, but also to make paramertisation easier to grok we changed the pattern to use test case classes, which seems like quite an elegant solution, similar to golang test tables.

from dataclasses import dataclass

import pytest

def multiply(a: int, b: int) -> int
    return a * b

@dataclass(frozen=True, kw_only=True)
class MultiplyTest:
     id: str
     a: int
     b: int
     expected int

@pytest.mark.parametrize(
    "tc",
    [
        MultiplyTest(
            id="small",
            a: 1,
            b: 2,
            expected: 2,
        ),
        MultiplyTest(
            id="big",
            a: 100,
            b: 200,
            expected: 20000,
        ),
    ],
    ids=lambda x: x.id,
)
def test_multiply(tc: MultiplyTest) -> None:
    result: int = multiply(tc.a, tc.b)
    assert result = tc.expected

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: parametrize related to @pytest.mark.parametrize topic: typing type-annotation issue type: enhancement new feature or API change, should be merged into features branch
Projects
None yet
Development

No branches or pull requests

3 participants