Skip to content
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

Difference between types with type arguments and without them #2537

Closed
sobolevn opened this issue Aug 9, 2020 · 4 comments · Fixed by #2543
Closed

Difference between types with type arguments and without them #2537

sobolevn opened this issue Aug 9, 2020 · 4 comments · Fixed by #2543
Labels
enhancement it's not broken, but we want it to be better

Comments

@sobolevn
Copy link
Member

sobolevn commented Aug 9, 2020

I have this code:

def associativity_law(
    mappable: MappableN[_FirstType, _SecondType, _ThirdType],
    first: Callable[[_FirstType], _NewType1],
    second: Callable[[_NewType1], _NewType2],
) -> None:
    assert mappable.map(first).map(second) == mappable.map(
        compose(first, second),
    )

Then, I use this code to generate values based on this annotation:

@given(st.data())
def test_assoc(data: st.DataObject):
    st.register_type_strategy(
        MappableN[_FirstType, _SecondType, _ThirdType],  # just `MappableN` does not work
        st.one_of(
            st.builds(Result.from_value),
            st.builds(Result.from_failure),
        ),
    )
    x = data.draw(st.builds(associativity_law))
    assert x is None

So, the thing is that just MappableN does not work when trying to use it as a type in st.register_type_strategy. Output for the broken case:

E           hypothesis.errors.ResolutionFailed: Could not resolve returns.interfaces.mappable.MappableN[~_FirstType, ~_SecondType, ~_ThirdType] to a strategy; consider using register_type_strategy

.venv/lib/python3.8/site-packages/hypothesis/strategies/_internal/types.py:229: ResolutionFailed

I guess, that using MappableN[_FirstType, _SecondType, _ThirdType] to register a type is incorrect, because types should be used like this.

@sobolevn
Copy link
Member Author

sobolevn commented Aug 10, 2020

So, my fix for this problem (very straight-forward):

    origin_handler = _global_type_lookup.get(origin)
    if origin_handler:
        return origin_handler if isinstance(origin_handler, st.SearchStrategy) else origin_handler(thing)

I have patched the code here: https://github.com/HypothesisWorks/hypothesis/blob/master/hypothesis-python/src/hypothesis/strategies/_internal/types.py#L183

Does this look like something in the right direction?

@Zac-HD
Copy link
Member

Zac-HD commented Aug 11, 2020

Yeah, I think that would work - we'll just need some user-defined generic types to test with.

It's still possible that I'll look at the results and decide that this is the wrong approach, but I think it's unlikely if this does solve your problem without breaking anything else.

@sobolevn
Copy link
Member Author

I will send a PR shorly.

@sobolevn
Copy link
Member Author

This is only the case for python3.7+. python3.6 handles this correctly.

@Zac-HD Zac-HD added the enhancement it's not broken, but we want it to be better label Aug 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement it's not broken, but we want it to be better
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants