-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
indirectly parameterized session-scoped fixtures aren't #13159
Comments
Pytest cannot know if a duplicate is intentional or accidentally See Also see |
A important note I forgot Multiple parameter variants of a fixture may not exist at the same time |
I think this latter point is the limit I'm running into. If that could be overcome, it would be very helpful for my use cases. Doing so would sidestep any issues related to case (or test) ordering. Would it be possible to fix that, either in pytest or in a plugin? |
There's currently no plan/concepts for such fixtures in a builtin way It's so deep in pytest that a plugin can't safely mess with it A workaround could be a managing fixture that creates data and essentially having the concrete parameterized fixture leak so the managing fixture has to clean up all instances |
This issue is stale because it has the |
As @RonnyPfannschmidt said, the current invariant is that no more than 1 instance of each fixture exists at a time. (I hope pytest does not change this invariant, as some of our parametrized fixtures cannot have multiple concurrent instances, they would conflict with each other, e.g. as files on disk.) So pytest walks through the tests, in whatever order they end up (this can be changed via The issue can be mitigated by reordering test parameters so that for "heavy" parameters, same values are grouped together: @pytest.mark.parametrize(
"case_fixture, expected",
[
(1, "case_fixture 1"),
(1, "case_fixture 1"), # <====
(2, "case_fixture 2"), # <====
],
indirect=["case_fixture"],
scope="session"
)
def test_one(case_fixture, expected):
assert case_fixture == expected This can be automated using from collections import defaultdict
from typing import List
def pytest_collection_modifyitems(items: List[pytest.Item]):
grouped = defaultdict(list)
for item in items:
grouping_key = None
if hasattr(item, 'callspec'):
# callspec does not seem to be public API, but oh well
grouping_key = item.callspec.params.get('my_heavy_fixture', None)
grouped[grouping_key].append(item)
items.clear()
items.extend(item for group in grouped.values() for item in group) If there are multiple "heavy" fixtures with conflicting order of values, then there is nothing that can be done. |
Summary
When a fixture is passed parameters from a test, via
@pytest.mark.parameterize
'sindirect=True
, per-parameter-value session-scoping does not work. For a given passed value, the fixture may be created/torn down multiple times.Minimal example
Code
Expected Result
Actual Result
Platform details
Pytest 8.2.2
Python 3.11.10
MacOS 15.2 (Sequoia)
Pip list output
The text was updated successfully, but these errors were encountered: