Improve `iterparentnodeids` to consume `/` parts until the first `::` (#8577)
* Fix issue where TestCase.setUpClass is not called for test methods with a / in its name by checking if there is :: before the selected / or any :: after. Also added a test case for this. * removed print statement that was added * Change iterparentnodeids to consume / parts until the first ::. Then consider ::. Tests were changed to reflect this. * Update changelog/8509.improvement.rst Co-authored-by: Ran Benita <ran@unusedvar.com>
This commit is contained in:
parent
2049ae271e
commit
992c403fc8
1
AUTHORS
1
AUTHORS
|
@ -236,6 +236,7 @@ Omar Kohl
|
||||||
Omer Hadari
|
Omer Hadari
|
||||||
Ondřej Súkup
|
Ondřej Súkup
|
||||||
Oscar Benjamin
|
Oscar Benjamin
|
||||||
|
Parth Patel
|
||||||
Patrick Hayes
|
Patrick Hayes
|
||||||
Pauli Virtanen
|
Pauli Virtanen
|
||||||
Pavel Karateev
|
Pavel Karateev
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
Fixed issue where `TestCase.setUpClass` is not called when a test has `/` in its name since pytest 6.2.0.
|
||||||
|
|
||||||
|
This refers to the path part in pytest node IDs, e.g. `TestClass::test_it` in the node ID `tests/test_file.py::TestClass::test_it`.
|
||||||
|
|
||||||
|
Now, instead of assuming that the test name does not contain ``/``, it is assumed that test path does not contain ``::``. We plan to hopefully make both of these work in the future.
|
|
@ -62,23 +62,33 @@ def iterparentnodeids(nodeid: str) -> Iterator[str]:
|
||||||
"testing/code/test_excinfo.py::TestFormattedExcinfo"
|
"testing/code/test_excinfo.py::TestFormattedExcinfo"
|
||||||
"testing/code/test_excinfo.py::TestFormattedExcinfo::test_repr_source"
|
"testing/code/test_excinfo.py::TestFormattedExcinfo::test_repr_source"
|
||||||
|
|
||||||
Note that :: parts are only considered at the last / component.
|
Note that / components are only considered until the first ::.
|
||||||
"""
|
"""
|
||||||
pos = 0
|
pos = 0
|
||||||
sep = SEP
|
first_colons: Optional[int] = nodeid.find("::")
|
||||||
|
if first_colons == -1:
|
||||||
|
first_colons = None
|
||||||
|
# The root Session node - always present.
|
||||||
yield ""
|
yield ""
|
||||||
|
# Eagerly consume SEP parts until first colons.
|
||||||
while True:
|
while True:
|
||||||
at = nodeid.find(sep, pos)
|
at = nodeid.find(SEP, pos, first_colons)
|
||||||
if at == -1 and sep == SEP:
|
if at == -1:
|
||||||
sep = "::"
|
|
||||||
elif at == -1:
|
|
||||||
if nodeid:
|
|
||||||
yield nodeid
|
|
||||||
break
|
break
|
||||||
else:
|
if at > 0:
|
||||||
if at:
|
yield nodeid[:at]
|
||||||
yield nodeid[:at]
|
pos = at + len(SEP)
|
||||||
pos = at + len(sep)
|
# Eagerly consume :: parts.
|
||||||
|
while True:
|
||||||
|
at = nodeid.find("::", pos)
|
||||||
|
if at == -1:
|
||||||
|
break
|
||||||
|
if at > 0:
|
||||||
|
yield nodeid[:at]
|
||||||
|
pos = at + len("::")
|
||||||
|
# The node ID itself.
|
||||||
|
if nodeid:
|
||||||
|
yield nodeid
|
||||||
|
|
||||||
|
|
||||||
def _imply_path(
|
def _imply_path(
|
||||||
|
|
|
@ -18,11 +18,13 @@ from _pytest.warning_types import PytestWarning
|
||||||
("a/b/c", ["", "a", "a/b", "a/b/c"]),
|
("a/b/c", ["", "a", "a/b", "a/b/c"]),
|
||||||
("a/bbb/c::D", ["", "a", "a/bbb", "a/bbb/c", "a/bbb/c::D"]),
|
("a/bbb/c::D", ["", "a", "a/bbb", "a/bbb/c", "a/bbb/c::D"]),
|
||||||
("a/b/c::D::eee", ["", "a", "a/b", "a/b/c", "a/b/c::D", "a/b/c::D::eee"]),
|
("a/b/c::D::eee", ["", "a", "a/b", "a/b/c", "a/b/c::D", "a/b/c::D::eee"]),
|
||||||
# :: considered only at the last component.
|
|
||||||
("::xx", ["", "::xx"]),
|
("::xx", ["", "::xx"]),
|
||||||
("a/b/c::D/d::e", ["", "a", "a/b", "a/b/c::D", "a/b/c::D/d", "a/b/c::D/d::e"]),
|
# / only considered until first ::
|
||||||
|
("a/b/c::D/d::e", ["", "a", "a/b", "a/b/c", "a/b/c::D/d", "a/b/c::D/d::e"]),
|
||||||
# : alone is not a separator.
|
# : alone is not a separator.
|
||||||
("a/b::D:e:f::g", ["", "a", "a/b", "a/b::D:e:f", "a/b::D:e:f::g"]),
|
("a/b::D:e:f::g", ["", "a", "a/b", "a/b::D:e:f", "a/b::D:e:f::g"]),
|
||||||
|
# / not considered if a part of a test name
|
||||||
|
("a/b::c/d::e[/test]", ["", "a", "a/b", "a/b::c/d", "a/b::c/d::e[/test]"]),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_iterparentnodeids(nodeid: str, expected: List[str]) -> None:
|
def test_iterparentnodeids(nodeid: str, expected: List[str]) -> None:
|
||||||
|
|
Loading…
Reference in New Issue