-
Notifications
You must be signed in to change notification settings - Fork 40
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
Cases depending on other cases getting a LazyValue is problematic #158
Comments
Thanks @plammens for testing all these situations ! I really appreciate, this is great Well, So at least one workaround is probably to have your case require a fixture parametrized with the other case. This should work. |
I see. So if I understand correctly, the case is getting a lazy value because it's parameterised with a case, and cases get collected at the test collection stage (hence the need for LazyValue). But a fixture would get the actual value because it is run "immediately" before the test node. Is this more or less what's going on? |
This makes me think, are cases parametrised with other cases even supported, or did I just dream that up? If they are supported, I think an exception should be made for these, in that the LazyValue should be actually computed before passing it to the dependent case—you can't do anything useful at all with a lazy value if you need that value to construct the dependent test case. And if the dependent case function is being called, it means that the depended-on case function would have been called soon in any case, so you're not gaining anything by delaying the computation of the value. Otherwise I'd resort to calling |
They were not working correctly because of some premature optimization. In 3.0.0 I fixed it so they should be working fine, at the cost of some extra fixtures being created. I'll probably need to re-optimize it again: if a case is parameterized it does not always need to be turned into a fixture (as it is for now). But doing this properly, as you noted with nested lazy values, requires an extra care. Let me know if 3.0.0 solves the issue, and I'll open another ticket for the internal optimization that needs to be done |
Thanks! Now I'm getting an error though, and I'm not able to make a minimal reproducible example :( My case code looks like this: class DummyPlayerCases:
...
@staticmethod
@pytest_cases.case()
@pytest_cases.parametrize_with_cases("hand", cases=PlayerHandCases.case_single_card)
def case_single_card(hand):
return DummyPlayerCases.__make_player(hand) and the test function: @pytest_cases.parametrize_with_cases("card", cases=card_cases.CardCases)
@pytest_cases.parametrize_with_cases(
"player", cases=player_cases.DummyPlayerCases.case_single_card
)
def test_cardSteps_correspondsToReality(player: RoundPlayer, card: cards.Card):
... I'm getting
Could you give me a pointer perhaps as to where to put breakpoints for debugging, @smarie? Running |
ouch. this will be hard then, as I won't be able to help. I'll try random examples this afternoon
Note that the intermediate fixture created at step 3 would not be if we fix #170 . Some (but not all) intermediate fixtures created at step 2 would also not be if we fix #169 . So, now in your situation, I think that the problem happend in the first So for now the only workaround I see is that you put all of your code in the same module. Ugly, but will work. I reopen this issue so that we can try to properly fix it in the future version of the engine (after #170 ). |
Thanks, this was the key to the issue! Now I was able to make a MRE, I was trying to do that in a single module but that wouldn't have reproduced it due to the nature of the error :) I will open a separate issue since it is kind of unrelated to this one. |
Sorry for the issue spamming Sylvain.
Very briefly, if I have a case
case_a
that is parametrised with another case,case_b
,case_a
doesn't get an actual value, it gets aLazyValue
. So when I do e.g.MagicMock(spec=value_of_case_b)
, it uses the attributes and methods of theLazyValue
object, not the value itself. Is there a way around that? Are case functions supposed to be aware that they'll be getting aLazyValue
? If so is it encouraged to explicitly call.valuegetter()
?I'm starting to think these
LazyValue
s cause more problems than they are useful 🤔Example:
This gives a
TypeError
when trying to compute3*x + 2
, sincex
is aLazyValue
.The text was updated successfully, but these errors were encountered: