Skip to content
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

Allow parametrize to depend on previous parametrize #13242

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Anton3
Copy link

@Anton3 Anton3 commented Feb 20, 2025

Closes: #13233

@psf-chronographer psf-chronographer bot added the bot:chronographer:provided (automation) changelog entry is part of PR label Feb 20, 2025
@Anton3 Anton3 marked this pull request as ready for review February 20, 2025 17:37
@RonnyPfannschmidt
Copy link
Member

the exposure of callspec, the hook order change as well as future considerations make this one extra hard to review

I'll need to schedule something for that


self._params_directness: dict[str, Literal["indirect", "direct"]] = {}

def parametrize(
self,
argnames: str | Sequence[str],
argvalues: Iterable[ParameterSet | Sequence[object] | object],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should introduce a new method name for this and mark it experimental to avoid locking into callspec as exposed api too early

I'm not sure what a fitting name would be

@Anton3
Copy link
Author

Anton3 commented Feb 21, 2025

An alternative to exposing CallSpec is, as I said, to add a new Node subtype with an additional getparam method. If it was a Node, the hook from docs

    def pytest_generate_tests(metafunc: pytest.Metafunc):
        if "bar" in metafunc.fixturenames:
            # parametrize "bar" arg based on "bar_params" mark
            base_bar_marks = list(metafunc.definition.iter_markers("bar_params"))

            def gen_params(callspec: pytest.CallSpec):
                # collect all marks
                bar_marks = base_bar_marks + [
                    mark for mark in callspec.marks if mark.name == "bar_params"
                ]
                # collect all args from all marks
                return [arg for mark in bar_marks for arg in mark.args]

            metafunc.parametrize("bar", gen_params)

would be rewritten as just:

    def pytest_generate_tests(metafunc: pytest.Metafunc):
        if "bar" in metafunc.fixturenames:
            def gen_params(proto_item: pytest.ProtoItem):
                bar_marks = proto_item.iter_markers("bar_params")
                return [arg for mark in bar_marks for arg in mark.args]

            metafunc.parametrize("bar", gen_params)

@RonnyPfannschmidt
Copy link
Member

I would like to avoid using nodes or node lookalikes

In fact thinking about potentially nesting and/or cascading I'd like to defer inventing new apis

Just ensuring the apis to experiment/ learn from this are experimental

We can't hope to initially account for something like acting in the bases of mark coming in from lazy fixtures

@Anton3
Copy link
Author

Anton3 commented Feb 24, 2025

@RonnyPfannschmidt I've figured out the ordering issue I struggled with

I can add parametrize_experimental that has everything of the normal parametrize, plus the new feature. What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bot:chronographer:provided (automation) changelog entry is part of PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pytest_generate_tests based on params and marks from previous parametrize
2 participants