Skip to content

Commit

Permalink
main: fix reversed collection order in Session
Browse files Browse the repository at this point in the history
Since we're working with a stack (last in first out), we need to append
to it in reverse to preserve the order when popped.

Fix pytest-dev#11937.
  • Loading branch information
bluetech committed Feb 9, 2024
1 parent 9454fc3 commit ea57c40
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 4 deletions.
1 change: 1 addition & 0 deletions changelog/11937.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a regression in pytest 8.0.0 whereby items would be collected in reverse order in some circumstances.
2 changes: 1 addition & 1 deletion src/_pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,7 @@ def collect(self) -> Iterator[Union[nodes.Item, nodes.Collector]]:

# Prune this level.
any_matched_in_collector = False
for node in subnodes:
for node in reversed(subnodes):
# Path part e.g. `/a/b/` in `/a/b/test_file.py::TestIt::test_it`.
if isinstance(matchparts[0], Path):
is_match = node.path == matchparts[0]
Expand Down
2 changes: 1 addition & 1 deletion testing/acceptance_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ def test_issue88_initial_file_multinodes(self, pytester: Pytester) -> None:
pytester.copy_example("issue88_initial_file_multinodes")
p = pytester.makepyfile("def test_hello(): pass")
result = pytester.runpytest(p, "--collect-only")
result.stdout.fnmatch_lines(["*Module*test_issue88*", "*MyFile*test_issue88*"])
result.stdout.fnmatch_lines(["*MyFile*test_issue88*", "*Module*test_issue88*"])

def test_issue93_initialnode_importing_capturing(self, pytester: Pytester) -> None:
pytester.makeconftest(
Expand Down
21 changes: 19 additions & 2 deletions testing/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -592,12 +592,12 @@ def pytest_collect_file(file_path, parent):
hookrec.assert_contains(
[
("pytest_collectstart", "collector.path == collector.session.path"),
("pytest_collectstart", "collector.__class__.__name__ == 'Module'"),
("pytest_pycollect_makeitem", "name == 'test_func'"),
(
"pytest_collectstart",
"collector.__class__.__name__ == 'SpecialFile'",
),
("pytest_collectstart", "collector.__class__.__name__ == 'Module'"),
("pytest_pycollect_makeitem", "name == 'test_func'"),
("pytest_collectreport", "report.nodeid.startswith(p.name)"),
]
)
Expand Down Expand Up @@ -671,6 +671,23 @@ def test_method(self):
# ensure we are reporting the collection of the single test item (#2464)
assert [x.name for x in self.get_reported_items(hookrec)] == ["test_method"]

def test_collect_parametrized_order(self, pytester: Pytester) -> None:
p = pytester.makepyfile(
"""
import pytest
@pytest.mark.parametrize('i', [0, 1, 2])
def test_param(i): ...
"""
)
items, hookrec = pytester.inline_genitems(f"{p}::test_param")
assert len(items) == 3
assert [item.nodeid for item in items] == [
"test_collect_parametrized_order.py::test_param[0]",
"test_collect_parametrized_order.py::test_param[1]",
"test_collect_parametrized_order.py::test_param[2]",
]


class Test_getinitialnodes:
def test_global_file(self, pytester: Pytester) -> None:
Expand Down

0 comments on commit ea57c40

Please sign in to comment.