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

InvalidArgument when using @given with a function with positional-only args #3838

Closed
mx781 opened this issue Jan 12, 2024 · 2 comments
Closed
Labels
question not sure it's a bug? questions welcome

Comments

@mx781
Copy link

mx781 commented Jan 12, 2024

Hi and thanks for the hard work on hypothesis, it's been super useful already.

I can't seem to use @given with a function that has pos-only args:

@given(st.integers())
def test(a: int, /, b: str, *, q: int = 3) -> None:
    pass

test()

raises InvalidArgument: positional arguments to @given are not supported with varargs, varkeywords, positional-only, or keyword-only arguments

while

@given(st.integers())
def test(a: int, /, b: str, *, q: int = 3) -> None:
    pass

test()

throws InvalidArgument: test() got an unexpected keyword argument 'a', from a=integers() in @given.

Is there a way to do this? I see some tests relating to pos-only args, so I suspect this has been though about, but I also haven't found examples of this (somewhat hard to search for).

@Zac-HD Zac-HD added the question not sure it's a bug? questions welcome label Jan 13, 2024
@Zac-HD
Copy link
Member

Zac-HD commented Jan 13, 2024

It looks like you've pasted the first example test twice, so I'm not sure what's different in the second? If it's meant to show @given(st.integers()), then you'll have two problems: no argument given for b, and passing a by keyword when it's a positional-only argument.

Unfortunately we had to lock in the details for how Hypothesis translates the arguments to @given() into arguments to your test function back when we supported Python 2, before positional-only or even keyword-only arguments (or inspect.Signature.bind()) existed. As a result, I've been unable to support generating positional-only arguments using Hypothesis - although we can now generate the other parameters for a test function-or-method which has some posonly params - and we've also had to exclude mixing positional and keyword arguments to the @given() decorator.

While this is definitely not ideal, restricting the signatures of supported test functions is a relatively small cost compared to breaking many existing tests which would change the signature binding semantics. For what it's worth, I'm not convinced that offering more power is a good tradeoff against simplicity either 😕

@Zac-HD Zac-HD closed this as completed Jan 15, 2024
@mx781
Copy link
Author

mx781 commented Jan 15, 2024

Ooof, my bad. The example that raises "InvalidArgument: test() got an unexpected keyword argument 'a', from a=integers() in @given" should've indeed been this:

@given(a=st.integers(), b=st.text(), q=st.integers())
def test(a: int, /, b: str, *, q: int = 3) -> None:
    pass

test()

Posonly-args are indeed rare so what you said makes sense - thanks for the speedy response and for clearing this up! 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question not sure it's a bug? questions welcome
Projects
None yet
Development

No branches or pull requests

2 participants