Remove prune_dependency_tree and reuse getfixtureclosure logic by sadra-barikbin · Pull Request #11243 · pytest-dev/pytest (original) (raw)

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 andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation30 Commits19 Checks0 Files changed

Conversation

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})

sadra-barikbin

nicoddemus

Choose a reason for hiding this comment

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

Hi @sadra-barikbin thanks a lot for the PR, as always.

I left some minor comments, but I'm not sure overall it is an improvement, specially the "magic" needed around unwrap_metafunc_parametrize_and_possibly_prune_dependency_tree. The previous function was a bit convoluted, but at least it was direct and executed around a specific point.

Can you add more details to the PR, specially why you think prune_dependency_tree is problematic and how this improves and/or enables further improvements?

ignore_args: Sequence[str] = (),
) -> Tuple[Tuple[str, ...], List[str], Dict[str, Sequence[FixtureDef[Any]]]]:
) -> List[str]:

Choose a reason for hiding this comment

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

I would prefer to keep returning a brand new arg2fixturedefs, and let the caller merge it with other dict if they want, rather than passing in a dict and fill it inside. This makes it clear what's input/output.

Choose a reason for hiding this comment

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

But the second fixture closure computation needs arg2fixturedefs as input, otherwise it should compute it again which is expensive according to docstring:

........ we also populate arg2fixturedefs mapping

for the args missing therein so that the caller can reuse it and does

not have to re-discover fixturedefs again for each fixturename

(discovering matching fixtures for a given name/node is expensive).

Choose a reason for hiding this comment

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

How about this?

def getfixtureclosure( self, parentnode: nodes.Node, initialnames: Tuple[str, ...], arg2fixturedefs: Union[Dict[str, Sequence[FixtureDef[Any]]], None], ignore_args: Sequence[str] = (), ) -> Tuple[List[str], Dict[str, Sequence[FixtureDef[Any]]]]:

If arg2fixturedefs is none, we create one, populate it and return it. Otherwise we just use it and return it.

@bluetech

@sadra-barikbin

nicoddemus

@sadra-barikbin

@sadra-barikbin

@sadra-barikbin

…dency_tree' into Improvement-remove-prune_dependency_tree

@sadra-barikbin

RonnyPfannschmidt

RonnyPfannschmidt

RonnyPfannschmidt

@sadra-barikbin

Now we precisely prune only when there's dynamic direct parametrization.

@sadra-barikbin

@sadra-barikbin

@sadra-barikbin

bluetech

@@ -4534,8 +4534,178 @@ def test_fixt(custom):
assert result.ret == ExitCode.TESTS_FAILED
def test_fixture_info_after_dynamic_parametrize(pytester: Pytester) -> None:

Choose a reason for hiding this comment

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

Since these tests (except test_dont_recompute_dependency_tree_if_no_dynamic_parametrize) are applicable also to the current code in main, I'd like to add them there first (https://github.com/bluetech/pytest/commits/fixtures-tests). However, when I comment out the fixtureinfo.prune_dependency_tree() call, they all still pass. So I'm not sure if they're testing the right thing?

It would be great to add a docstring to each test explaining what is its purpose, i.e. if it fails I should the docstring should help me understand which mechanism probably failed.

Choose a reason for hiding this comment

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

Are you sure that test_fixture_info_after_dynamic_parametrize passes? The rest are to make sure the correct behavior isn't going to change but this one should fail, because the prune_dependency_tree takes place after fixtures.py::pytest_generate_tests's parametrization on fixture3 and its two generated items along with the two from dynamic parametrization on fixture2 make up four items causing the test to fail.
I added the test to main branch and it failed expectedly.
OK, I add docstring to the tests.

Choose a reason for hiding this comment

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

Update: test_reordering_after_dynamic_parametrize had a bug. I fix it. This should fail as well for the same reason as the test_fixture_info_after_dynamic_parametrize.

@@ -1102,6 +1074,26 @@ def __repr__(self) -> str:
)
class IdentityFixture(FixtureDef[FixtureValue]):

Choose a reason for hiding this comment

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

Since it's a special case of FixtureDef, should be IdentityFixtureDef.

Also, I think "Identity" is not what we want. It described what it does well enough, however when we check isinstance(fixturedefs[-1], IdentityFixture): we aren't checking if it's an "identity fixture", we check if it's a "pseudo fixture". Therefore I think we should call it PseudoFixtureDef.

Also, is it possible to change name2pseudofixturedef type from FixtureDef to PseudoFixtureDef?

Choose a reason for hiding this comment

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

How is to keep IdentityFixtureDef but do PseudoFixtureDef = IdentityFixtureDef in fixtures.py?

Choose a reason for hiding this comment

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

But we already have a PseudoFixtureDef representing request fixturedefs.

@sadra-barikbin

and fix a couple of Mypy issues